OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/media/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
15 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 15 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
16 #include "content/browser/renderer_host/media/media_stream_requester.h" | 16 #include "content/browser/renderer_host/media/media_stream_requester.h" |
17 #include "content/browser/renderer_host/media/media_stream_ui_controller.h" | 17 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
18 #include "content/browser/renderer_host/media/video_capture_manager.h" | 18 #include "content/browser/renderer_host/media/video_capture_manager.h" |
19 #include "content/browser/renderer_host/media/web_contents_capture_util.h" | 19 #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
21 #include "content/public/browser/content_browser_client.h" | 21 #include "content/public/browser/content_browser_client.h" |
22 #include "content/public/browser/media_observer.h" | 22 #include "content/public/browser/media_observer.h" |
23 #include "content/public/browser/media_request_state.h" | 23 #include "content/public/browser/media_request_state.h" |
24 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
25 #include "content/public/common/media_stream_request.h" | 25 #include "content/public/common/media_stream_request.h" |
26 #include "googleurl/src/gurl.h" | 26 #include "googleurl/src/gurl.h" |
27 #include "media/audio/audio_manager_base.h" | 27 #include "media/audio/audio_manager_base.h" |
(...skipping 19 matching lines...) Expand all Loading... |
47 | 47 |
48 std::string label(36, ' '); | 48 std::string label(36, ' '); |
49 for (size_t i = 0; i < label.size(); ++i) { | 49 for (size_t i = 0; i < label.size(); ++i) { |
50 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); | 50 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); |
51 label[i] = kAlphabet[random_char]; | 51 label[i] = kAlphabet[random_char]; |
52 } | 52 } |
53 return label; | 53 return label; |
54 } | 54 } |
55 | 55 |
56 // Helper to verify if a media stream type is part of options or not. | 56 // Helper to verify if a media stream type is part of options or not. |
57 static bool Requested(const StreamOptions& options, | 57 static bool Requested(const MediaStreamRequest& request, |
58 MediaStreamType stream_type) { | 58 MediaStreamType stream_type) { |
59 return (options.audio_type == stream_type || | 59 return (request.audio_type == stream_type || |
60 options.video_type == stream_type); | 60 request.video_type == stream_type); |
61 } | 61 } |
62 | 62 |
63 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. | 63 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. |
64 class MediaStreamManager::DeviceRequest { | 64 class MediaStreamManager::DeviceRequest { |
65 public: | 65 public: |
66 DeviceRequest() | 66 DeviceRequest(MediaStreamRequester* requester, |
67 : requester(NULL), | 67 const MediaStreamRequest& request) |
68 type(MEDIA_GENERATE_STREAM), | 68 : requester(requester), |
69 render_process_id(-1), | 69 request(request), |
70 render_view_id(-1), | |
71 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { | 70 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { |
72 } | 71 } |
73 | 72 |
74 DeviceRequest(MediaStreamRequester* requester, | |
75 const StreamOptions& request_options, | |
76 MediaStreamRequestType request_type, | |
77 int render_process_id, | |
78 int render_view_id, | |
79 const GURL& request_security_origin, | |
80 const std::string& requested_device_id) | |
81 : requester(requester), | |
82 options(request_options), | |
83 type(request_type), | |
84 render_process_id(render_process_id), | |
85 render_view_id(render_view_id), | |
86 security_origin(request_security_origin), | |
87 requested_device_id(requested_device_id), | |
88 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { | |
89 } | |
90 | |
91 ~DeviceRequest() {} | 73 ~DeviceRequest() {} |
92 | 74 |
93 // Update the request state and notify observers. | 75 // Update the request state and notify observers. |
94 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { | 76 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { |
95 state_[stream_type] = new_state; | 77 state_[stream_type] = new_state; |
96 | 78 |
97 if (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && | 79 if (request.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
98 options.audio_type != MEDIA_TAB_AUDIO_CAPTURE) { | 80 request.audio_type != MEDIA_TAB_AUDIO_CAPTURE) { |
99 return; | 81 return; |
100 } | 82 } |
101 | 83 |
102 MediaObserver* media_observer = | 84 MediaObserver* media_observer = |
103 GetContentClient()->browser()->GetMediaObserver(); | 85 GetContentClient()->browser()->GetMediaObserver(); |
104 if (media_observer == NULL) | 86 if (media_observer == NULL) |
105 return; | 87 return; |
106 | 88 |
107 // If we appended a device_id scheme, we want to remove it when notifying | 89 // If we appended a device_id scheme, we want to remove it when notifying |
108 // observers which may be in different modules since this scheme is only | 90 // observers which may be in different modules since this scheme is only |
109 // used internally within the content module. | 91 // used internally within the content module. |
110 std::string device_id = | 92 std::string device_id = |
111 WebContentsCaptureUtil::StripWebContentsDeviceScheme( | 93 WebContentsCaptureUtil::StripWebContentsDeviceScheme( |
112 requested_device_id); | 94 request.requested_device_id); |
113 | 95 |
114 media_observer->OnMediaRequestStateChanged( | 96 media_observer->OnMediaRequestStateChanged( |
115 render_process_id, render_view_id, | 97 request.render_process_id, request.render_view_id, |
116 MediaStreamDevice( | 98 MediaStreamDevice(stream_type, device_id, device_id), new_state); |
117 stream_type, device_id, device_id), new_state); | |
118 } | 99 } |
119 | 100 |
120 MediaRequestState state(MediaStreamType stream_type) const { | 101 MediaRequestState state(MediaStreamType stream_type) const { |
121 return state_[stream_type]; | 102 return state_[stream_type]; |
122 } | 103 } |
123 | 104 |
124 MediaStreamRequester* const requester; // Can be NULL. | 105 MediaStreamRequester* const requester; // Can be NULL. |
125 const StreamOptions options; | 106 MediaStreamRequest request; |
126 const MediaStreamRequestType type; | 107 |
127 const int render_process_id; | |
128 const int render_view_id; | |
129 const GURL security_origin; | |
130 const std::string requested_device_id; | |
131 StreamDeviceInfoArray devices; | 108 StreamDeviceInfoArray devices; |
132 | 109 |
133 // Callback to the requester which audio/video devices have been selected. | 110 // Callback to the requester which audio/video devices have been selected. |
134 // It can be null if the requester has no interest to know the result. | 111 // It can be null if the requester has no interest to know the result. |
135 // Currently it is only used by |DEVICE_ACCESS| type. | 112 // Currently it is only used by |DEVICE_ACCESS| type. |
136 MediaRequestResponseCallback callback; | 113 MediaStreamManager::MediaRequestResponseCallback callback; |
| 114 |
| 115 scoped_ptr<MediaStreamUIProxy> ui_proxy; |
137 | 116 |
138 private: | 117 private: |
139 std::vector<MediaRequestState> state_; | 118 std::vector<MediaRequestState> state_; |
140 }; | 119 }; |
141 | 120 |
142 MediaStreamManager::EnumerationCache::EnumerationCache() | 121 MediaStreamManager::EnumerationCache::EnumerationCache() |
143 : valid(false) { | 122 : valid(false) { |
144 } | 123 } |
145 | 124 |
146 MediaStreamManager::EnumerationCache::~EnumerationCache() { | 125 MediaStreamManager::EnumerationCache::~EnumerationCache() { |
147 } | 126 } |
148 | 127 |
149 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) | 128 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) |
150 : ALLOW_THIS_IN_INITIALIZER_LIST( | 129 : audio_manager_(audio_manager), |
151 ui_controller_(new MediaStreamUIController(this))), | |
152 audio_manager_(audio_manager), | |
153 monitoring_started_(false), | 130 monitoring_started_(false), |
154 io_loop_(NULL), | 131 io_loop_(NULL), |
155 screen_capture_active_(false) { | 132 screen_capture_active_(false), |
| 133 use_fake_ui_(false) { |
156 DCHECK(audio_manager_); | 134 DCHECK(audio_manager_); |
157 memset(active_enumeration_ref_count_, 0, | 135 memset(active_enumeration_ref_count_, 0, |
158 sizeof(active_enumeration_ref_count_)); | 136 sizeof(active_enumeration_ref_count_)); |
159 | 137 |
160 // Some unit tests create the MSM in the IO thread and assumes the | 138 // Some unit tests create the MSM in the IO thread and assumes the |
161 // initialization is done synchronously. | 139 // initialization is done synchronously. |
162 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 140 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
163 InitializeDeviceManagersOnIOThread(); | 141 InitializeDeviceManagersOnIOThread(); |
164 } else { | 142 } else { |
165 BrowserThread::PostTask( | 143 BrowserThread::PostTask( |
(...skipping 22 matching lines...) Expand all Loading... |
188 } | 166 } |
189 | 167 |
190 std::string MediaStreamManager::MakeMediaAccessRequest( | 168 std::string MediaStreamManager::MakeMediaAccessRequest( |
191 int render_process_id, | 169 int render_process_id, |
192 int render_view_id, | 170 int render_view_id, |
193 const StreamOptions& options, | 171 const StreamOptions& options, |
194 const GURL& security_origin, | 172 const GURL& security_origin, |
195 const MediaRequestResponseCallback& callback) { | 173 const MediaRequestResponseCallback& callback) { |
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
197 // Create a new request based on options. | 175 // Create a new request based on options. |
198 DeviceRequest* request = new DeviceRequest(NULL, | 176 MediaStreamRequest stream_request( |
199 options, | 177 render_process_id, render_view_id, security_origin, |
200 MEDIA_DEVICE_ACCESS, | 178 MEDIA_DEVICE_ACCESS, std::string(), |
201 render_process_id, | 179 options.audio_type, options.video_type); |
202 render_view_id, | 180 DeviceRequest* request = new DeviceRequest(NULL, stream_request); |
203 security_origin, | |
204 std::string()); | |
205 const std::string& label = AddRequest(request); | 181 const std::string& label = AddRequest(request); |
206 | 182 |
207 request->callback = callback; | 183 request->callback = callback; |
208 | 184 |
209 HandleRequest(label); | 185 HandleRequest(label); |
210 | 186 |
211 return label; | 187 return label; |
212 } | 188 } |
213 | 189 |
214 std::string MediaStreamManager::GenerateStream( | 190 std::string MediaStreamManager::GenerateStream( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // TODO(sergeyu): Implement support for more than one concurrent screen | 237 // TODO(sergeyu): Implement support for more than one concurrent screen |
262 // capture streams. | 238 // capture streams. |
263 LOG(ERROR) << "Another screen capture stream is active."; | 239 LOG(ERROR) << "Another screen capture stream is active."; |
264 return std::string(); | 240 return std::string(); |
265 } | 241 } |
266 | 242 |
267 screen_capture_active_ = true; | 243 screen_capture_active_ = true; |
268 } | 244 } |
269 | 245 |
270 // Create a new request based on options. | 246 // Create a new request based on options. |
271 DeviceRequest* request = new DeviceRequest(requester, | 247 MediaStreamRequest stream_request( |
272 options, | 248 target_render_process_id, target_render_view_id, security_origin, |
273 MEDIA_GENERATE_STREAM, | 249 MEDIA_GENERATE_STREAM, requested_device_id, |
274 target_render_process_id, | 250 options.audio_type, options.video_type); |
275 target_render_view_id, | 251 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
276 security_origin, | |
277 requested_device_id); | |
278 const std::string& label = AddRequest(request); | 252 const std::string& label = AddRequest(request); |
279 HandleRequest(label); | 253 HandleRequest(label); |
280 return label; | 254 return label; |
281 } | 255 } |
282 | 256 |
283 void MediaStreamManager::CancelRequest(const std::string& label) { | 257 void MediaStreamManager::CancelRequest(const std::string& label) { |
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
285 | 259 |
286 DeviceRequests::iterator it = requests_.find(label); | 260 DeviceRequests::iterator it = requests_.find(label); |
287 if (it != requests_.end()) { | 261 if (it != requests_.end()) { |
288 // The request isn't complete, notify the UI immediately. | |
289 ui_controller_->CancelUIRequest(label); | |
290 | |
291 if (!RequestDone(*it->second)) { | 262 if (!RequestDone(*it->second)) { |
292 // TODO(xians): update the |state| to STATE_DONE to trigger a state | 263 // TODO(xians): update the |state| to STATE_DONE to trigger a state |
293 // changed notification to UI before deleting the request? | 264 // changed notification to UI before deleting the request? |
294 scoped_ptr<DeviceRequest> request(it->second); | 265 scoped_ptr<DeviceRequest> request(it->second); |
295 RemoveRequest(it); | 266 RemoveRequest(it); |
296 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { | 267 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { |
297 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 268 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
298 MediaStreamProvider* device_manager = GetDeviceManager(stream_type); | 269 MediaStreamProvider* device_manager = GetDeviceManager(stream_type); |
299 if (!device_manager) | 270 if (!device_manager) |
300 continue; | 271 continue; |
(...skipping 13 matching lines...) Expand all Loading... |
314 } | 285 } |
315 } | 286 } |
316 } | 287 } |
317 | 288 |
318 void MediaStreamManager::StopGeneratedStream(const std::string& label) { | 289 void MediaStreamManager::StopGeneratedStream(const std::string& label) { |
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
320 | 291 |
321 // Find the request and close all open devices for the request. | 292 // Find the request and close all open devices for the request. |
322 DeviceRequests::iterator it = requests_.find(label); | 293 DeviceRequests::iterator it = requests_.find(label); |
323 if (it != requests_.end()) { | 294 if (it != requests_.end()) { |
324 if (it->second->type == MEDIA_ENUMERATE_DEVICES) { | 295 if (it->second->request.request_type == MEDIA_ENUMERATE_DEVICES) { |
325 StopEnumerateDevices(label); | 296 StopEnumerateDevices(label); |
326 return; | 297 return; |
327 } | 298 } |
328 | 299 |
329 scoped_ptr<DeviceRequest> request(it->second); | 300 scoped_ptr<DeviceRequest> request(it->second); |
330 RemoveRequest(it); | 301 RemoveRequest(it); |
331 for (StreamDeviceInfoArray::const_iterator device_it = | 302 for (StreamDeviceInfoArray::const_iterator device_it = |
332 request->devices.begin(); | 303 request->devices.begin(); |
333 device_it != request->devices.end(); ++device_it) { | 304 device_it != request->devices.end(); ++device_it) { |
334 GetDeviceManager(device_it->device.type)->Close(device_it->session_id); | 305 GetDeviceManager(device_it->device.type)->Close(device_it->session_id); |
335 } | 306 } |
336 if (request->type == MEDIA_GENERATE_STREAM && | 307 if (request->request.request_type == MEDIA_GENERATE_STREAM && |
337 RequestDone(*request)) { | 308 RequestDone(*request)) { |
338 // Notify observers that this device is being closed. | 309 // Notify observers that this device is being closed. |
339 for (int i = MEDIA_NO_SERVICE + 1; i != NUM_MEDIA_TYPES; ++i) { | 310 for (int i = MEDIA_NO_SERVICE + 1; i != NUM_MEDIA_TYPES; ++i) { |
340 if (request->state(static_cast<MediaStreamType>(i)) != | 311 if (request->state(static_cast<MediaStreamType>(i)) != |
341 MEDIA_REQUEST_STATE_NOT_REQUESTED) { | 312 MEDIA_REQUEST_STATE_NOT_REQUESTED) { |
342 request->SetState(static_cast<MediaStreamType>(i), | 313 request->SetState(static_cast<MediaStreamType>(i), |
343 MEDIA_REQUEST_STATE_CLOSING); | 314 MEDIA_REQUEST_STATE_CLOSING); |
344 } | 315 } |
345 } | 316 } |
346 NotifyUIDevicesClosed(label); | |
347 } | 317 } |
348 | |
349 // If request isn't complete, notify the UI on the cancellation. And it | |
350 // is also safe to call CancelUIRequest if the request has been done. | |
351 ui_controller_->CancelUIRequest(label); | |
352 } | 318 } |
353 } | 319 } |
354 | 320 |
355 std::string MediaStreamManager::EnumerateDevices( | 321 std::string MediaStreamManager::EnumerateDevices( |
356 MediaStreamRequester* requester, | 322 MediaStreamRequester* requester, |
357 int render_process_id, | 323 int render_process_id, |
358 int render_view_id, | 324 int render_view_id, |
359 MediaStreamType type, | 325 MediaStreamType type, |
360 const GURL& security_origin) { | 326 const GURL& security_origin) { |
361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 16 matching lines...) Expand all Loading... |
378 options.audio_type = type; | 344 options.audio_type = type; |
379 cache = &audio_enumeration_cache_; | 345 cache = &audio_enumeration_cache_; |
380 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 346 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
381 options.video_type = type; | 347 options.video_type = type; |
382 cache = &video_enumeration_cache_; | 348 cache = &video_enumeration_cache_; |
383 } else { | 349 } else { |
384 NOTREACHED(); | 350 NOTREACHED(); |
385 return std::string(); | 351 return std::string(); |
386 } | 352 } |
387 | 353 |
388 DeviceRequest* request = new DeviceRequest(requester, | 354 MediaStreamRequest stream_request( |
389 options, | 355 render_process_id, render_view_id, security_origin, |
390 MEDIA_ENUMERATE_DEVICES, | 356 MEDIA_ENUMERATE_DEVICES, std::string(), |
391 render_process_id, | 357 options.audio_type, options.video_type); |
392 render_view_id, | 358 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
393 security_origin, | |
394 std::string()); | |
395 const std::string& label = AddRequest(request); | 359 const std::string& label = AddRequest(request); |
396 | 360 |
397 if (cache->valid) { | 361 if (cache->valid) { |
398 // Cached device list of this type exists. Just send it out. | 362 // Cached device list of this type exists. Just send it out. |
399 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); | 363 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); |
400 | 364 |
401 // Need to post a task since the requester won't have label till | 365 // Need to post a task since the requester won't have label till |
402 // this function returns. | 366 // this function returns. |
403 BrowserThread::PostTask( | 367 BrowserThread::PostTask( |
404 BrowserThread::IO, FROM_HERE, | 368 BrowserThread::IO, FROM_HERE, |
405 base::Bind(&MediaStreamManager::SendCachedDeviceList, | 369 base::Bind(&MediaStreamManager::SendCachedDeviceList, |
406 base::Unretained(this), cache, label)); | 370 base::Unretained(this), cache, label)); |
407 } else { | 371 } else { |
408 StartEnumeration(request); | 372 StartEnumeration(request); |
409 } | 373 } |
410 | 374 |
411 return label; | 375 return label; |
412 } | 376 } |
413 | 377 |
414 void MediaStreamManager::StopEnumerateDevices(const std::string& label) { | 378 void MediaStreamManager::StopEnumerateDevices(const std::string& label) { |
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
416 | 380 |
417 DeviceRequests::iterator it = requests_.find(label); | 381 DeviceRequests::iterator it = requests_.find(label); |
418 if (it != requests_.end()) { | 382 if (it != requests_.end()) { |
419 DCHECK_EQ(it->second->type, MEDIA_ENUMERATE_DEVICES); | 383 DCHECK_EQ(it->second->request.request_type, MEDIA_ENUMERATE_DEVICES); |
420 // Delete the DeviceRequest. | 384 // Delete the DeviceRequest. |
421 scoped_ptr<DeviceRequest> request(it->second); | 385 scoped_ptr<DeviceRequest> request(it->second); |
422 RemoveRequest(it); | 386 RemoveRequest(it); |
423 } | 387 } |
424 } | 388 } |
425 | 389 |
426 std::string MediaStreamManager::OpenDevice( | 390 std::string MediaStreamManager::OpenDevice( |
427 MediaStreamRequester* requester, | 391 MediaStreamRequester* requester, |
428 int render_process_id, | 392 int render_process_id, |
429 int render_view_id, | 393 int render_view_id, |
430 const std::string& device_id, | 394 const std::string& device_id, |
431 MediaStreamType type, | 395 MediaStreamType type, |
432 const GURL& security_origin) { | 396 const GURL& security_origin) { |
433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
434 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 398 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
435 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 399 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
436 | 400 |
437 // Create a new request. | 401 // Create a new request. |
438 StreamOptions options; | 402 StreamOptions options; |
439 if (IsAudioMediaType(type)) { | 403 if (IsAudioMediaType(type)) { |
440 options.audio_type = type; | 404 options.audio_type = type; |
441 } else if (IsVideoMediaType(type)) { | 405 } else if (IsVideoMediaType(type)) { |
442 options.video_type = type; | 406 options.video_type = type; |
443 } else { | 407 } else { |
444 NOTREACHED(); | 408 NOTREACHED(); |
445 return std::string(); | 409 return std::string(); |
446 } | 410 } |
447 | 411 |
448 DeviceRequest* request = new DeviceRequest(requester, | 412 MediaStreamRequest stream_request( |
449 options, | 413 render_process_id, render_view_id, security_origin, |
450 MEDIA_OPEN_DEVICE, | 414 MEDIA_OPEN_DEVICE, device_id, |
451 render_process_id, | 415 options.audio_type, options.video_type); |
452 render_view_id, | 416 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
453 security_origin, | |
454 device_id); | |
455 const std::string& label = AddRequest(request); | 417 const std::string& label = AddRequest(request); |
456 StartEnumeration(request); | 418 StartEnumeration(request); |
457 | 419 |
458 return label; | 420 return label; |
459 } | 421 } |
460 | 422 |
461 void MediaStreamManager::NotifyUIDevicesOpened(const std::string& label) { | |
462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
463 ui_controller_->NotifyUIIndicatorDevicesOpened(label); | |
464 } | |
465 | |
466 void MediaStreamManager::NotifyUIDevicesClosed(const std::string& label) { | |
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
468 ui_controller_->NotifyUIIndicatorDevicesClosed(label); | |
469 } | |
470 | |
471 void MediaStreamManager::SendCachedDeviceList( | 423 void MediaStreamManager::SendCachedDeviceList( |
472 EnumerationCache* cache, | 424 EnumerationCache* cache, |
473 const std::string& label) { | 425 const std::string& label) { |
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
475 if (cache->valid) { | 427 if (cache->valid) { |
476 DeviceRequests::iterator it = requests_.find(label); | 428 DeviceRequests::iterator it = requests_.find(label); |
477 if (it != requests_.end()) { | 429 if (it != requests_.end()) { |
478 it->second->requester->DevicesEnumerated(label, cache->devices); | 430 it->second->requester->DevicesEnumerated(label, cache->devices); |
479 } | 431 } |
480 } | 432 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
518 | 470 |
519 // Start monitoring the devices when doing the first enumeration. | 471 // Start monitoring the devices when doing the first enumeration. |
520 if (!monitoring_started_ && base::SystemMonitor::Get()) { | 472 if (!monitoring_started_ && base::SystemMonitor::Get()) { |
521 StartMonitoring(); | 473 StartMonitoring(); |
522 } | 474 } |
523 | 475 |
524 // Start enumeration for devices of all requested device types. | 476 // Start enumeration for devices of all requested device types. |
525 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { | 477 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { |
526 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 478 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
527 if (Requested(request->options, stream_type)) { | 479 if (Requested(request->request, stream_type)) { |
528 request->SetState(stream_type, MEDIA_REQUEST_STATE_REQUESTED); | 480 request->SetState(stream_type, MEDIA_REQUEST_STATE_REQUESTED); |
529 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 481 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
530 if (active_enumeration_ref_count_[stream_type] == 0) { | 482 if (active_enumeration_ref_count_[stream_type] == 0) { |
531 ++active_enumeration_ref_count_[stream_type]; | 483 ++active_enumeration_ref_count_[stream_type]; |
532 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); | 484 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); |
533 } | 485 } |
534 } | 486 } |
535 } | 487 } |
536 } | 488 } |
537 | 489 |
538 std::string MediaStreamManager::AddRequest(DeviceRequest* request) { | 490 std::string MediaStreamManager::AddRequest(DeviceRequest* request) { |
539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
540 | 492 |
541 // Create a label for this request and verify it is unique. | 493 // Create a label for this request and verify it is unique. |
542 std::string unique_label; | 494 std::string unique_label; |
543 do { | 495 do { |
544 unique_label = RandomLabel(); | 496 unique_label = RandomLabel(); |
545 } while (requests_.find(unique_label) != requests_.end()); | 497 } while (requests_.find(unique_label) != requests_.end()); |
546 | 498 |
547 requests_.insert(std::make_pair(unique_label, request)); | 499 requests_.insert(std::make_pair(unique_label, request)); |
548 | 500 |
549 return unique_label; | 501 return unique_label; |
550 } | 502 } |
551 | 503 |
552 void MediaStreamManager::RemoveRequest(DeviceRequests::iterator it) { | 504 void MediaStreamManager::RemoveRequest(DeviceRequests::iterator it) { |
553 if (it->second->options.video_type == MEDIA_SCREEN_VIDEO_CAPTURE) { | 505 if (it->second->request.video_type == MEDIA_SCREEN_VIDEO_CAPTURE) { |
554 DCHECK(screen_capture_active_); | 506 DCHECK(screen_capture_active_); |
555 screen_capture_active_ = false; | 507 screen_capture_active_ = false; |
556 } | 508 } |
557 | 509 |
558 NotifyUIDevicesClosed(it->first); | |
559 | |
560 requests_.erase(it); | 510 requests_.erase(it); |
561 } | 511 } |
562 | 512 |
563 void MediaStreamManager::PostRequestToUI(const std::string& label) { | 513 void MediaStreamManager::PostRequestToUI(const std::string& label) { |
564 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
565 DeviceRequest* request = requests_[label]; | 515 DeviceRequest* request = requests_[label]; |
566 // Get user confirmation to use capture devices. | 516 |
567 ui_controller_->MakeUIRequest(label, | 517 if (use_fake_ui_) { |
568 request->render_process_id, | 518 if (!fake_ui_) |
569 request->render_view_id, | 519 fake_ui_.reset(new FakeMediaStreamUIProxy()); |
570 request->options, | 520 request->ui_proxy = fake_ui_.Pass(); |
571 request->security_origin, | 521 } else { |
572 request->type, | 522 request->ui_proxy.reset(new MediaStreamUIProxy()); |
573 request->requested_device_id); | 523 } |
| 524 |
| 525 request->ui_proxy->RequestAccess( |
| 526 request->request, |
| 527 base::Bind(&MediaStreamManager::HandleAccessRequestResponse, |
| 528 base::Unretained(this), label)); |
574 } | 529 } |
575 | 530 |
576 void MediaStreamManager::HandleRequest(const std::string& label) { | 531 void MediaStreamManager::HandleRequest(const std::string& label) { |
577 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
578 DeviceRequest* request = requests_[label]; | 533 DeviceRequest* request = requests_[label]; |
579 | 534 |
580 const MediaStreamType audio_type = request->options.audio_type; | 535 const MediaStreamType audio_type = request->request.audio_type; |
581 const MediaStreamType video_type = request->options.video_type; | 536 const MediaStreamType video_type = request->request.video_type; |
582 | 537 |
583 bool is_web_contents_capture = | 538 bool is_web_contents_capture = |
584 audio_type == MEDIA_TAB_AUDIO_CAPTURE || | 539 audio_type == MEDIA_TAB_AUDIO_CAPTURE || |
585 video_type == MEDIA_TAB_VIDEO_CAPTURE; | 540 video_type == MEDIA_TAB_VIDEO_CAPTURE; |
586 | 541 |
587 bool is_screen_capure = | 542 bool is_screen_capure = |
588 video_type == MEDIA_SCREEN_VIDEO_CAPTURE; | 543 video_type == MEDIA_SCREEN_VIDEO_CAPTURE; |
589 | 544 |
590 if (!is_web_contents_capture && | 545 if (!is_web_contents_capture && |
591 !is_screen_capure && | 546 !is_screen_capure && |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 } | 628 } |
674 } | 629 } |
675 | 630 |
676 request->SetState(stream_type, MEDIA_REQUEST_STATE_DONE); | 631 request->SetState(stream_type, MEDIA_REQUEST_STATE_DONE); |
677 | 632 |
678 if (!RequestDone(*request)) { | 633 if (!RequestDone(*request)) { |
679 // This stream_type is done, but not the other type. | 634 // This stream_type is done, but not the other type. |
680 return; | 635 return; |
681 } | 636 } |
682 | 637 |
683 switch (request->type) { | 638 switch (request->request.request_type) { |
684 case MEDIA_OPEN_DEVICE: | 639 case MEDIA_OPEN_DEVICE: |
685 request->requester->DeviceOpened(label, devices->front()); | 640 request->requester->DeviceOpened(label, devices->front()); |
686 break; | 641 break; |
687 case MEDIA_GENERATE_STREAM: { | 642 case MEDIA_GENERATE_STREAM: { |
688 // Partition the array of devices into audio vs video. | 643 // Partition the array of devices into audio vs video. |
689 StreamDeviceInfoArray audio_devices, video_devices; | 644 StreamDeviceInfoArray audio_devices, video_devices; |
690 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 645 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
691 device_it != devices->end(); ++device_it) { | 646 device_it != devices->end(); ++device_it) { |
692 if (IsAudioMediaType(device_it->device.type)) { | 647 if (IsAudioMediaType(device_it->device.type)) { |
693 // Store the native audio parameters in the device struct. | 648 // Store the native audio parameters in the device struct. |
694 // TODO(xians): Handle the tab capture sample rate/channel layout | 649 // TODO(xians): Handle the tab capture sample rate/channel layout |
695 // in AudioInputDeviceManager::Open(). | 650 // in AudioInputDeviceManager::Open(). |
696 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { | 651 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { |
697 const StreamDeviceInfo* info = | 652 const StreamDeviceInfo* info = |
698 audio_input_device_manager_->GetOpenedDeviceInfoById( | 653 audio_input_device_manager_->GetOpenedDeviceInfoById( |
699 device_it->session_id); | 654 device_it->session_id); |
700 DCHECK_EQ(info->device.id, device_it->device.id); | 655 DCHECK_EQ(info->device.id, device_it->device.id); |
701 device_it->device.sample_rate = info->device.sample_rate; | 656 device_it->device.sample_rate = info->device.sample_rate; |
702 device_it->device.channel_layout = info->device.channel_layout; | 657 device_it->device.channel_layout = info->device.channel_layout; |
703 } | 658 } |
704 audio_devices.push_back(*device_it); | 659 audio_devices.push_back(*device_it); |
705 } else if (IsVideoMediaType(device_it->device.type)) { | 660 } else if (IsVideoMediaType(device_it->device.type)) { |
706 video_devices.push_back(*device_it); | 661 video_devices.push_back(*device_it); |
707 } else { | 662 } else { |
708 NOTREACHED(); | 663 NOTREACHED(); |
709 } | 664 } |
710 } | 665 } |
711 | 666 |
712 request->requester->StreamGenerated(label, audio_devices, video_devices); | 667 request->requester->StreamGenerated(label, audio_devices, video_devices); |
713 NotifyUIDevicesOpened(label); | 668 request->ui_proxy->OnStarted( |
| 669 base::Bind(&MediaStreamManager::StopStreamFromUI, |
| 670 base::Unretained(this), label)); |
714 break; | 671 break; |
715 } | 672 } |
716 default: | 673 default: |
717 NOTREACHED(); | 674 NOTREACHED(); |
718 break; | 675 break; |
719 } | 676 } |
720 } | 677 } |
721 | 678 |
722 void MediaStreamManager::Closed(MediaStreamType stream_type, | 679 void MediaStreamManager::Closed(MediaStreamType stream_type, |
723 int capture_session_id) { | 680 int capture_session_id) { |
(...skipping 21 matching lines...) Expand all Loading... |
745 if (need_update_clients && monitoring_started_) | 702 if (need_update_clients && monitoring_started_) |
746 NotifyDevicesChanged(stream_type, devices); | 703 NotifyDevicesChanged(stream_type, devices); |
747 | 704 |
748 // Publish the result for all requests waiting for device list(s). | 705 // Publish the result for all requests waiting for device list(s). |
749 // Find the requests waiting for this device list, store their labels and | 706 // Find the requests waiting for this device list, store their labels and |
750 // release the iterator before calling device settings. We might get a call | 707 // release the iterator before calling device settings. We might get a call |
751 // back from device_settings that will need to iterate through devices. | 708 // back from device_settings that will need to iterate through devices. |
752 std::list<std::string> label_list; | 709 std::list<std::string> label_list; |
753 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 710 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
754 ++it) { | 711 ++it) { |
755 if (it->second->state(stream_type) == | 712 if (it->second->state(stream_type) == MEDIA_REQUEST_STATE_REQUESTED && |
756 MEDIA_REQUEST_STATE_REQUESTED && | 713 Requested(it->second->request, stream_type)) { |
757 Requested(it->second->options, stream_type)) { | 714 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES) |
758 if (it->second->type != MEDIA_ENUMERATE_DEVICES) | |
759 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 715 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
760 label_list.push_back(it->first); | 716 label_list.push_back(it->first); |
761 } | 717 } |
762 } | 718 } |
763 for (std::list<std::string>::iterator it = label_list.begin(); | 719 for (std::list<std::string>::iterator it = label_list.begin(); |
764 it != label_list.end(); ++it) { | 720 it != label_list.end(); ++it) { |
765 DeviceRequest* request = requests_[*it]; | 721 DeviceRequest* request = requests_[*it]; |
766 switch (request->type) { | 722 switch (request->request.request_type) { |
767 case MEDIA_ENUMERATE_DEVICES: | 723 case MEDIA_ENUMERATE_DEVICES: |
768 if (need_update_clients && request->requester) | 724 if (need_update_clients && request->requester) |
769 request->requester->DevicesEnumerated(*it, devices); | 725 request->requester->DevicesEnumerated(*it, devices); |
770 break; | 726 break; |
771 default: | 727 default: |
772 if (request->state(request->options.audio_type) == | 728 if (request->state(request->request.audio_type) == |
773 MEDIA_REQUEST_STATE_REQUESTED || | 729 MEDIA_REQUEST_STATE_REQUESTED || |
774 request->state(request->options.video_type) == | 730 request->state(request->request.video_type) == |
775 MEDIA_REQUEST_STATE_REQUESTED) { | 731 MEDIA_REQUEST_STATE_REQUESTED) { |
776 // We are doing enumeration for other type of media, wait until it is | 732 // We are doing enumeration for other type of media, wait until it is |
777 // all done before posting the request to UI because UI needs | 733 // all done before posting the request to UI because UI needs |
778 // the device lists to handle the request. | 734 // the device lists to handle the request. |
779 break; | 735 break; |
780 } | 736 } |
781 | 737 |
782 // Post the request to UI for permission approval. | 738 // Post the request to UI for permission approval. |
783 PostRequestToUI(*it); | 739 PostRequestToUI(*it); |
784 break; | 740 break; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 // 2. Not opened but other devices exists for this request -> remove | 792 // 2. Not opened but other devices exists for this request -> remove |
837 // device from list, but don't signal an error. | 793 // device from list, but don't signal an error. |
838 devices.erase(device_it); // NOTE: This invalidates device_it! | 794 devices.erase(device_it); // NOTE: This invalidates device_it! |
839 } | 795 } |
840 } | 796 } |
841 return; | 797 return; |
842 } | 798 } |
843 } | 799 } |
844 } | 800 } |
845 | 801 |
846 void MediaStreamManager::DevicesAccepted(const std::string& label, | 802 void MediaStreamManager::HandleAccessRequestResponse( |
847 const StreamDeviceInfoArray& devices) { | 803 const std::string& label, |
| 804 const MediaStreamDevices& devices) { |
848 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
849 DCHECK(!devices.empty()); | 806 |
850 DeviceRequests::iterator request_it = requests_.find(label); | 807 DeviceRequests::iterator request_it = requests_.find(label); |
851 if (request_it == requests_.end()) { | 808 if (request_it == requests_.end()) { |
852 return; | 809 return; |
853 } | 810 } |
854 | 811 |
855 if (request_it->second->type == MEDIA_DEVICE_ACCESS) { | 812 // Handle the case when the request was denied. |
| 813 if (devices.empty()) { |
| 814 // Notify the users about the request result. |
856 scoped_ptr<DeviceRequest> request(request_it->second); | 815 scoped_ptr<DeviceRequest> request(request_it->second); |
857 if (!request->callback.is_null()) { | 816 if (request->requester) |
858 // Map the devices to MediaStreamDevices. | 817 request->requester->StreamGenerationFailed(label); |
859 MediaStreamDevices selected_devices; | |
860 for (StreamDeviceInfoArray::const_iterator it = devices.begin(); | |
861 it != devices.end(); ++it) { | |
862 selected_devices.push_back(it->device); | |
863 } | |
864 | 818 |
865 request->callback.Run(label, selected_devices); | 819 if (request->request.request_type == MEDIA_DEVICE_ACCESS && |
| 820 !request->callback.is_null()) { |
| 821 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass()); |
866 } | 822 } |
867 | 823 |
| 824 RemoveRequest(request_it); |
| 825 return; |
| 826 } |
| 827 |
| 828 if (request_it->second->request.request_type == MEDIA_DEVICE_ACCESS) { |
| 829 scoped_ptr<DeviceRequest> request(request_it->second); |
| 830 if (!request->callback.is_null()) |
| 831 request->callback.Run(devices, request->ui_proxy.Pass()); |
| 832 |
868 // Delete the request since it is done. | 833 // Delete the request since it is done. |
869 RemoveRequest(request_it); | 834 RemoveRequest(request_it); |
870 return; | 835 return; |
871 } | 836 } |
872 | 837 |
873 // Process all newly-accepted devices for this request. | 838 // Process all newly-accepted devices for this request. |
874 DeviceRequest* request = request_it->second; | 839 DeviceRequest* request = request_it->second; |
875 bool found_audio = false, found_video = false; | 840 bool found_audio = false; |
876 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 841 bool found_video = false; |
| 842 for (MediaStreamDevices::const_iterator device_it = devices.begin(); |
877 device_it != devices.end(); ++device_it) { | 843 device_it != devices.end(); ++device_it) { |
878 StreamDeviceInfo device_info = *device_it; // Make a copy. | 844 StreamDeviceInfo device_info; |
| 845 device_info.device = *device_it; |
879 | 846 |
880 // TODO(justinlin): Nicer way to do this? | 847 // TODO(justinlin): Nicer way to do this? |
881 // Re-append the device's id since we lost it when posting request to UI. | 848 // Re-append the device's id since we lost it when posting request to UI. |
882 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || | 849 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || |
883 device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { | 850 device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { |
884 device_info.device.id = request->requested_device_id; | 851 device_info.device.id = request->request.requested_device_id; |
885 | 852 |
886 // Initialize the sample_rate and channel_layout here since for audio | 853 // Initialize the sample_rate and channel_layout here since for audio |
887 // mirroring, we don't go through EnumerateDevices where these are usually | 854 // mirroring, we don't go through EnumerateDevices where these are usually |
888 // initialized. | 855 // initialized. |
889 if (device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { | 856 if (device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { |
890 const media::AudioParameters parameters = | 857 const media::AudioParameters parameters = |
891 audio_manager_->GetDefaultOutputStreamParameters(); | 858 audio_manager_->GetDefaultOutputStreamParameters(); |
892 int sample_rate = parameters.sample_rate(); | 859 int sample_rate = parameters.sample_rate(); |
893 // If we weren't able to get the native sampling rate or the sample_rate | 860 // If we weren't able to get the native sampling rate or the sample_rate |
894 // is outside the valid range for input devices set reasonable defaults. | 861 // is outside the valid range for input devices set reasonable defaults. |
895 if (sample_rate <= 0 || sample_rate > 96000) | 862 if (sample_rate <= 0 || sample_rate > 96000) |
896 sample_rate = 44100; | 863 sample_rate = 44100; |
897 | 864 |
898 device_info.device.sample_rate = sample_rate; | 865 device_info.device.sample_rate = sample_rate; |
899 device_info.device.channel_layout = media::CHANNEL_LAYOUT_STEREO; | 866 device_info.device.channel_layout = media::CHANNEL_LAYOUT_STEREO; |
900 } | 867 } |
901 } | 868 } |
902 | 869 |
903 // Set in_use to false to be able to track if this device has been | 870 // Set in_use to false to be able to track if this device has been |
904 // opened. in_use might be true if the device type can be used in more | 871 // opened. in_use might be true if the device type can be used in more |
905 // than one session. | 872 // than one session. |
906 DCHECK_EQ(request->state(device_it->device.type), | |
907 MEDIA_REQUEST_STATE_PENDING_APPROVAL); | |
908 device_info.in_use = false; | 873 device_info.in_use = false; |
909 | 874 |
910 device_info.session_id = | 875 device_info.session_id = |
911 GetDeviceManager(device_info.device.type)->Open(device_info); | 876 GetDeviceManager(device_info.device.type)->Open(device_info); |
912 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_OPENING); | 877 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); |
913 request->devices.push_back(device_info); | 878 request->devices.push_back(device_info); |
914 | 879 |
915 if (device_info.device.type == request->options.audio_type) { | 880 if (device_info.device.type == request->request.audio_type) { |
916 found_audio = true; | 881 found_audio = true; |
917 } else if (device_info.device.type == request->options.video_type) { | 882 } else if (device_info.device.type == request->request.video_type) { |
918 found_video = true; | 883 found_video = true; |
919 } | 884 } |
920 } | 885 } |
921 | 886 |
922 // Check whether we've received all stream types requested. | 887 // Check whether we've received all stream types requested. |
923 if (!found_audio && IsAudioMediaType(request->options.audio_type)) | 888 if (!found_audio && IsAudioMediaType(request->request.audio_type)) |
924 request->SetState(request->options.audio_type, MEDIA_REQUEST_STATE_ERROR); | 889 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR); |
925 | 890 |
926 if (!found_video && IsVideoMediaType(request->options.video_type)) | 891 if (!found_video && IsVideoMediaType(request->request.video_type)) |
927 request->SetState(request->options.video_type, MEDIA_REQUEST_STATE_ERROR); | 892 request->SetState(request->request.video_type, MEDIA_REQUEST_STATE_ERROR); |
928 } | |
929 | |
930 void MediaStreamManager::SettingsError(const std::string& label) { | |
931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
932 // Erase this request and report an error. | |
933 DeviceRequests::iterator it = requests_.find(label); | |
934 if (it == requests_.end()) | |
935 return; | |
936 | |
937 // Notify the users about the request result. | |
938 scoped_ptr<DeviceRequest> request(it->second); | |
939 if (request->requester) | |
940 request->requester->StreamGenerationFailed(label); | |
941 | |
942 if (request->type == MEDIA_DEVICE_ACCESS && | |
943 !request->callback.is_null()) { | |
944 request->callback.Run(label, MediaStreamDevices()); | |
945 } | |
946 | |
947 RemoveRequest(it); | |
948 } | 893 } |
949 | 894 |
950 void MediaStreamManager::StopStreamFromUI(const std::string& label) { | 895 void MediaStreamManager::StopStreamFromUI(const std::string& label) { |
951 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
952 | 897 |
953 DeviceRequests::iterator it = requests_.find(label); | 898 DeviceRequests::iterator it = requests_.find(label); |
954 if (it == requests_.end()) | 899 if (it == requests_.end()) |
955 return; | 900 return; |
956 | 901 |
957 // Notify renderers that the stream has been stopped. | 902 // Notify renderers that the stream has been stopped. |
958 if (it->second->requester) | 903 if (it->second->requester) |
959 it->second->requester->StreamGenerationFailed(label); | 904 it->second->requester->StreamGenerationFailed(label); |
960 | 905 |
961 StopGeneratedStream(label); | 906 StopGeneratedStream(label); |
962 } | 907 } |
963 | 908 |
964 void MediaStreamManager::GetAvailableDevices(MediaStreamDevices* devices) { | |
965 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
966 DCHECK(audio_enumeration_cache_.valid || video_enumeration_cache_.valid); | |
967 DCHECK(devices->empty()); | |
968 if (audio_enumeration_cache_.valid) { | |
969 for (StreamDeviceInfoArray::const_iterator it = | |
970 audio_enumeration_cache_.devices.begin(); | |
971 it != audio_enumeration_cache_.devices.end(); | |
972 ++it) { | |
973 devices->push_back(it->device); | |
974 } | |
975 } | |
976 | |
977 if (video_enumeration_cache_.valid) { | |
978 for (StreamDeviceInfoArray::const_iterator it = | |
979 video_enumeration_cache_.devices.begin(); | |
980 it != video_enumeration_cache_.devices.end(); | |
981 ++it) { | |
982 devices->push_back(it->device); | |
983 } | |
984 } | |
985 } | |
986 | |
987 void MediaStreamManager::UseFakeDevice() { | 909 void MediaStreamManager::UseFakeDevice() { |
988 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 910 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
989 video_capture_manager()->UseFakeDevice(); | 911 video_capture_manager()->UseFakeDevice(); |
990 audio_input_device_manager()->UseFakeDevice(); | 912 audio_input_device_manager()->UseFakeDevice(); |
991 UseFakeUI(scoped_ptr<MediaStreamUI>()); | 913 UseFakeUI(scoped_ptr<MediaStreamUIProxy>()); |
992 } | 914 } |
993 | 915 |
994 void MediaStreamManager::UseFakeUI(scoped_ptr<MediaStreamUI> fake_ui) { | 916 void MediaStreamManager::UseFakeUI(scoped_ptr<MediaStreamUIProxy> fake_ui) { |
995 ui_controller_->UseFakeUI(fake_ui.Pass()); | 917 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 918 use_fake_ui_ = true; |
| 919 fake_ui_ = fake_ui.Pass(); |
996 } | 920 } |
997 | 921 |
998 void MediaStreamManager::WillDestroyCurrentMessageLoop() { | 922 void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
999 DCHECK_EQ(MessageLoop::current(), io_loop_); | 923 DCHECK_EQ(MessageLoop::current(), io_loop_); |
1000 DCHECK(requests_.empty()); | 924 DCHECK(requests_.empty()); |
1001 if (device_thread_.get()) { | 925 if (device_thread_.get()) { |
1002 StopMonitoring(); | 926 StopMonitoring(); |
1003 | 927 |
1004 video_capture_manager_->Unregister(); | 928 video_capture_manager_->Unregister(); |
1005 audio_input_device_manager_->Unregister(); | 929 audio_input_device_manager_->Unregister(); |
1006 device_thread_.reset(); | 930 device_thread_.reset(); |
1007 } | 931 } |
1008 | 932 |
1009 audio_input_device_manager_ = NULL; | 933 audio_input_device_manager_ = NULL; |
1010 video_capture_manager_ = NULL; | 934 video_capture_manager_ = NULL; |
1011 io_loop_ = NULL; | 935 io_loop_ = NULL; |
1012 ui_controller_.reset(); | |
1013 } | 936 } |
1014 | 937 |
1015 void MediaStreamManager::NotifyDevicesChanged( | 938 void MediaStreamManager::NotifyDevicesChanged( |
1016 MediaStreamType stream_type, | 939 MediaStreamType stream_type, |
1017 const StreamDeviceInfoArray& devices) { | 940 const StreamDeviceInfoArray& devices) { |
1018 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 941 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
1019 MediaObserver* media_observer = | 942 MediaObserver* media_observer = |
1020 GetContentClient()->browser()->GetMediaObserver(); | 943 GetContentClient()->browser()->GetMediaObserver(); |
1021 if (media_observer == NULL) | 944 if (media_observer == NULL) |
1022 return; | 945 return; |
(...skipping 10 matching lines...) Expand all Loading... |
1033 } else if (IsVideoMediaType(stream_type)) { | 956 } else if (IsVideoMediaType(stream_type)) { |
1034 media_observer->OnVideoCaptureDevicesChanged(new_devices); | 957 media_observer->OnVideoCaptureDevicesChanged(new_devices); |
1035 } else { | 958 } else { |
1036 NOTREACHED(); | 959 NOTREACHED(); |
1037 } | 960 } |
1038 } | 961 } |
1039 | 962 |
1040 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 963 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
1041 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
1042 | 965 |
1043 const bool requested_audio = IsAudioMediaType(request.options.audio_type); | 966 const bool requested_audio = IsAudioMediaType(request.request.audio_type); |
1044 const bool requested_video = IsVideoMediaType(request.options.video_type); | 967 const bool requested_video = IsVideoMediaType(request.request.video_type); |
1045 | 968 |
1046 const bool audio_done = | 969 const bool audio_done = |
1047 !requested_audio || | 970 !requested_audio || |
1048 request.state(request.options.audio_type) == | 971 request.state(request.request.audio_type) == |
1049 MEDIA_REQUEST_STATE_DONE || | 972 MEDIA_REQUEST_STATE_DONE || |
1050 request.state(request.options.audio_type) == | 973 request.state(request.request.audio_type) == |
1051 MEDIA_REQUEST_STATE_ERROR; | 974 MEDIA_REQUEST_STATE_ERROR; |
1052 if (!audio_done) | 975 if (!audio_done) |
1053 return false; | 976 return false; |
1054 | 977 |
1055 const bool video_done = | 978 const bool video_done = |
1056 !requested_video || | 979 !requested_video || |
1057 request.state(request.options.video_type) == | 980 request.state(request.request.video_type) == |
1058 MEDIA_REQUEST_STATE_DONE || | 981 MEDIA_REQUEST_STATE_DONE || |
1059 request.state(request.options.video_type) == | 982 request.state(request.request.video_type) == |
1060 MEDIA_REQUEST_STATE_ERROR; | 983 MEDIA_REQUEST_STATE_ERROR; |
1061 if (!video_done) | 984 if (!video_done) |
1062 return false; | 985 return false; |
1063 | 986 |
1064 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 987 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
1065 it != request.devices.end(); ++it) { | 988 it != request.devices.end(); ++it) { |
1066 if (it->in_use == false) | 989 if (it->in_use == false) |
1067 return false; | 990 return false; |
1068 } | 991 } |
1069 | 992 |
(...skipping 28 matching lines...) Expand all Loading... |
1098 } | 1021 } |
1099 | 1022 |
1100 // Always do enumeration even though some enumeration is in progress, | 1023 // Always do enumeration even though some enumeration is in progress, |
1101 // because those enumeration commands could be sent before these devices | 1024 // because those enumeration commands could be sent before these devices |
1102 // change. | 1025 // change. |
1103 ++active_enumeration_ref_count_[stream_type]; | 1026 ++active_enumeration_ref_count_[stream_type]; |
1104 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); | 1027 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); |
1105 } | 1028 } |
1106 | 1029 |
1107 } // namespace content | 1030 } // namespace content |
OLD | NEW |