1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/shell/renderer/test_runner/mock_web_user_media_client.h" 6 7 #include "base/logging.h" 8 #include "base/macros.h" 9 #include "content/shell/renderer/test_runner/mock_constraints.h" 10 #include "content/shell/renderer/test_runner/web_test_delegate.h" 11 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 12 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" 13 #include "third_party/WebKit/public/platform/WebMediaStream.h" 14 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 15 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 16 #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h" 17 #include "third_party/WebKit/public/platform/WebSourceInfo.h" 18 #include "third_party/WebKit/public/platform/WebVector.h" 19 #include "third_party/WebKit/public/web/WebDocument.h" 20 #include "third_party/WebKit/public/web/WebMediaDevicesRequest.h" 21 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" 22 #include "third_party/WebKit/public/web/WebUserMediaRequest.h" 23 24 using blink::WebMediaConstraints; 25 using blink::WebMediaDeviceInfo; 26 using blink::WebMediaDevicesRequest; 27 using blink::WebMediaStream; 28 using blink::WebMediaStreamSource; 29 using blink::WebMediaStreamTrack; 30 using blink::WebMediaStreamTrackSourcesRequest; 31 using blink::WebSourceInfo; 32 using blink::WebString; 33 using blink::WebUserMediaRequest; 34 using blink::WebVector; 35 36 namespace content { 37 38 class UserMediaRequestTask : public WebMethodTask<MockWebUserMediaClient> { 39 public: 40 UserMediaRequestTask(MockWebUserMediaClient* object, 41 const WebUserMediaRequest& request, 42 const WebMediaStream result) 43 : WebMethodTask<MockWebUserMediaClient>(object), 44 request_(request), 45 result_(result) { 46 DCHECK(!result_.isNull()); 47 } 48 49 virtual void RunIfValid() OVERRIDE { request_.requestSucceeded(result_); } 50 51 private: 52 WebUserMediaRequest request_; 53 WebMediaStream result_; 54 55 DISALLOW_COPY_AND_ASSIGN(UserMediaRequestTask); 56 }; 57 58 class UserMediaRequestConstraintFailedTask 59 : public WebMethodTask<MockWebUserMediaClient> { 60 public: 61 UserMediaRequestConstraintFailedTask(MockWebUserMediaClient* object, 62 const WebUserMediaRequest& request, 63 const WebString& constraint) 64 : WebMethodTask<MockWebUserMediaClient>(object), 65 request_(request), 66 constraint_(constraint) {} 67 68 virtual void RunIfValid() OVERRIDE { 69 request_.requestFailedConstraint(constraint_); 70 } 71 72 private: 73 WebUserMediaRequest request_; 74 WebString constraint_; 75 76 DISALLOW_COPY_AND_ASSIGN(UserMediaRequestConstraintFailedTask); 77 }; 78 79 class UserMediaRequestPermissionDeniedTask 80 : public WebMethodTask<MockWebUserMediaClient> { 81 public: 82 UserMediaRequestPermissionDeniedTask(MockWebUserMediaClient* object, 83 const WebUserMediaRequest& request) 84 : WebMethodTask<MockWebUserMediaClient>(object), 85 request_(request) {} 86 87 virtual void RunIfValid() OVERRIDE { request_.requestFailed(); } 88 89 private: 90 WebUserMediaRequest request_; 91 92 DISALLOW_COPY_AND_ASSIGN(UserMediaRequestPermissionDeniedTask); 93 }; 94 95 class MediaDevicesRequestTask : public WebMethodTask<MockWebUserMediaClient> { 96 public: 97 MediaDevicesRequestTask(MockWebUserMediaClient* object, 98 const WebMediaDevicesRequest& request, 99 const WebVector<WebMediaDeviceInfo>& result) 100 : WebMethodTask<MockWebUserMediaClient>(object), 101 request_(request), 102 result_(result) {} 103 104 virtual void RunIfValid() OVERRIDE { request_.requestSucceeded(result_); } 105 106 private: 107 WebMediaDevicesRequest request_; 108 WebVector<WebMediaDeviceInfo> result_; 109 110 DISALLOW_COPY_AND_ASSIGN(MediaDevicesRequestTask); 111 }; 112 113 class SourcesRequestTask : public WebMethodTask<MockWebUserMediaClient> { 114 public: 115 SourcesRequestTask(MockWebUserMediaClient* object, 116 const WebMediaStreamTrackSourcesRequest& request, 117 const WebVector<WebSourceInfo>& result) 118 : WebMethodTask<MockWebUserMediaClient>(object), 119 request_(request), 120 result_(result) {} 121 122 virtual void RunIfValid() OVERRIDE { request_.requestSucceeded(result_); } 123 124 private: 125 WebMediaStreamTrackSourcesRequest request_; 126 WebVector<WebSourceInfo> result_; 127 128 DISALLOW_COPY_AND_ASSIGN(SourcesRequestTask); 129 }; 130 131 class MockExtraData : public WebMediaStream::ExtraData { 132 public: 133 int foo; 134 }; 135 136 MockWebUserMediaClient::MockWebUserMediaClient(WebTestDelegate* delegate) 137 : delegate_(delegate) {} 138 139 void MockWebUserMediaClient::requestUserMedia( 140 const WebUserMediaRequest& stream_request) { 141 DCHECK(!stream_request.isNull()); 142 WebUserMediaRequest request = stream_request; 143 144 if (request.ownerDocument().isNull() || !request.ownerDocument().frame()) { 145 delegate_->PostTask( 146 new UserMediaRequestPermissionDeniedTask(this, request)); 147 return; 148 } 149 150 WebMediaConstraints constraints = request.audioConstraints(); 151 WebString failed_constraint; 152 if (!constraints.isNull() && 153 !MockConstraints::VerifyConstraints(constraints, &failed_constraint)) { 154 delegate_->PostTask(new UserMediaRequestConstraintFailedTask( 155 this, request, failed_constraint)); 156 return; 157 } 158 constraints = request.videoConstraints(); 159 if (!constraints.isNull() && 160 !MockConstraints::VerifyConstraints(constraints, &failed_constraint)) { 161 delegate_->PostTask(new UserMediaRequestConstraintFailedTask( 162 this, request, failed_constraint)); 163 return; 164 } 165 166 const size_t zero = 0; 167 const size_t one = 1; 168 WebVector<WebMediaStreamTrack> audio_tracks(request.audio() ? one : zero); 169 WebVector<WebMediaStreamTrack> video_tracks(request.video() ? one : zero); 170 171 if (request.audio()) { 172 WebMediaStreamSource source; 173 source.initialize("MockAudioDevice#1", 174 WebMediaStreamSource::TypeAudio, 175 "Mock audio device"); 176 audio_tracks[0].initialize(source); 177 } 178 179 if (request.video()) { 180 WebMediaStreamSource source; 181 source.initialize("MockVideoDevice#1", 182 WebMediaStreamSource::TypeVideo, 183 "Mock video device"); 184 video_tracks[0].initialize(source); 185 } 186 187 WebMediaStream stream; 188 stream.initialize(audio_tracks, video_tracks); 189 190 stream.setExtraData(new MockExtraData()); 191 192 delegate_->PostTask(new UserMediaRequestTask(this, request, stream)); 193 } 194 195 void MockWebUserMediaClient::cancelUserMediaRequest( 196 const WebUserMediaRequest&) { 197 } 198 199 void MockWebUserMediaClient::requestMediaDevices( 200 const WebMediaDevicesRequest& request) { 201 struct { 202 const char* device_id; 203 WebMediaDeviceInfo::MediaDeviceKind kind; 204 const char* label; 205 const char* group_id; 206 } test_devices[] = { 207 { 208 "device1", 209 WebMediaDeviceInfo::MediaDeviceKindAudioInput, 210 "Built-in microphone", 211 "group1", 212 }, 213 { 214 "device2", 215 WebMediaDeviceInfo::MediaDeviceKindAudioOutput, 216 "Built-in speakers", 217 "group1", 218 }, 219 { 220 "device3", 221 WebMediaDeviceInfo::MediaDeviceKindVideoInput, 222 "Build-in webcam", 223 "group2", 224 }, 225 }; 226 227 WebVector<WebMediaDeviceInfo> devices(ARRAYSIZE_UNSAFE(test_devices)); 228 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_devices); ++i) { 229 devices[i].initialize(WebString::fromUTF8(test_devices[i].device_id), 230 test_devices[i].kind, 231 WebString::fromUTF8(test_devices[i].label), 232 WebString::fromUTF8(test_devices[i].group_id)); 233 } 234 235 delegate_->PostTask(new MediaDevicesRequestTask(this, request, devices)); 236 } 237 238 void MockWebUserMediaClient::cancelMediaDevicesRequest( 239 const WebMediaDevicesRequest&) { 240 } 241 242 void MockWebUserMediaClient::requestSources( 243 const blink::WebMediaStreamTrackSourcesRequest& request) { 244 struct { 245 const char* id; 246 WebSourceInfo::SourceKind kind; 247 const char* label; 248 WebSourceInfo::VideoFacingMode facing; 249 } test_sources[] = { 250 { 251 "device1", 252 WebSourceInfo::SourceKindAudio, 253 "Built-in microphone", 254 WebSourceInfo::VideoFacingModeNone, 255 }, 256 { 257 "device2", 258 WebSourceInfo::SourceKindVideo, 259 "Build-in webcam", 260 WebSourceInfo::VideoFacingModeEnvironment, 261 }, 262 }; 263 264 WebVector<WebSourceInfo> sources(ARRAYSIZE_UNSAFE(test_sources)); 265 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_sources); ++i) { 266 sources[i].initialize(WebString::fromUTF8(test_sources[i].id), 267 test_sources[i].kind, 268 WebString::fromUTF8(test_sources[i].label), 269 test_sources[i].facing); 270 } 271 272 delegate_->PostTask(new SourcesRequestTask(this, request, sources)); 273 } 274 275 } // namespace content 276