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