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/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
13 #include "base/win/scoped_com_initializer.h" | 13 #include "base/win/scoped_com_initializer.h" |
14 #include "content/browser/browser_main_loop.h" | |
15 #include "content/browser/devices_monitor/devices_monitor.h" | |
14 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 16 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
15 #include "content/browser/renderer_host/media/media_stream_device_settings.h" | 17 #include "content/browser/renderer_host/media/media_stream_device_settings.h" |
16 #include "content/browser/renderer_host/media/media_stream_requester.h" | 18 #include "content/browser/renderer_host/media/media_stream_requester.h" |
17 #include "content/browser/renderer_host/media/video_capture_manager.h" | 19 #include "content/browser/renderer_host/media/video_capture_manager.h" |
18 #include "content/common/media/media_stream_options.h" | 20 #include "content/common/media/media_stream_options.h" |
19 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
21 #include "content/public/browser/media_observer.h" | 23 #include "content/public/browser/media_observer.h" |
22 #include "googleurl/src/gurl.h" | 24 #include "googleurl/src/gurl.h" |
23 | 25 |
(...skipping 16 matching lines...) Expand all Loading... | |
40 for (size_t i = 0; i < label.size(); ++i) { | 42 for (size_t i = 0; i < label.size(); ++i) { |
41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); | 43 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); |
42 label[i] = kAlphabet[random_char]; | 44 label[i] = kAlphabet[random_char]; |
43 } | 45 } |
44 return label; | 46 return label; |
45 } | 47 } |
46 | 48 |
47 // Helper to verify if a media stream type is part of options or not. | 49 // Helper to verify if a media stream type is part of options or not. |
48 static bool Requested(const StreamOptions& options, | 50 static bool Requested(const StreamOptions& options, |
49 MediaStreamType stream_type) { | 51 MediaStreamType stream_type) { |
50 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && | 52 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && |
tommi (sloooow) - chröme
2012/07/30 12:10:21
nit:
return (stream_type == content::MEDIA_STREAM
wjia(left Chromium)
2012/08/01 01:28:59
Done.
| |
51 options.video) { | 53 options.video) { |
52 return true; | 54 return true; |
53 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && | 55 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && |
54 options.audio) { | 56 options.audio) { |
55 return true; | 57 return true; |
56 } | 58 } |
57 return false; | 59 return false; |
58 } | 60 } |
59 | 61 |
60 DeviceThread::DeviceThread(const char* name) | 62 DeviceThread::DeviceThread(const char* name) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 std::vector<RequestState> state; | 126 std::vector<RequestState> state; |
125 RequestType type; | 127 RequestType type; |
126 int render_process_id; | 128 int render_process_id; |
127 int render_view_id; | 129 int render_view_id; |
128 GURL security_origin; | 130 GURL security_origin; |
129 std::string requested_device_id; | 131 std::string requested_device_id; |
130 StreamDeviceInfoArray audio_devices; | 132 StreamDeviceInfoArray audio_devices; |
131 StreamDeviceInfoArray video_devices; | 133 StreamDeviceInfoArray video_devices; |
132 }; | 134 }; |
133 | 135 |
136 MediaStreamManager::EnumerationCache::EnumerationCache() | |
137 : valid(false) { | |
138 } | |
139 | |
134 MediaStreamManager::MediaStreamManager( | 140 MediaStreamManager::MediaStreamManager( |
135 AudioInputDeviceManager* audio_input_device_manager, | 141 AudioInputDeviceManager* audio_input_device_manager, |
136 VideoCaptureManager* video_capture_manager) | 142 VideoCaptureManager* video_capture_manager) |
137 : ALLOW_THIS_IN_INITIALIZER_LIST( | 143 : ALLOW_THIS_IN_INITIALIZER_LIST( |
138 device_settings_(new MediaStreamDeviceSettings(this))), | 144 device_settings_(new MediaStreamDeviceSettings(this))), |
139 audio_input_device_manager_(audio_input_device_manager), | 145 audio_input_device_manager_(audio_input_device_manager), |
140 video_capture_manager_(video_capture_manager), | 146 video_capture_manager_(video_capture_manager), |
147 monitoring_started_(false), | |
141 enumeration_in_progress_(content::NUM_MEDIA_STREAM_DEVICE_TYPES, false), | 148 enumeration_in_progress_(content::NUM_MEDIA_STREAM_DEVICE_TYPES, false), |
tommi (sloooow) - chröme
2012/07/30 12:10:21
This array seems to be used in conjunction with th
wjia(left Chromium)
2012/08/01 01:28:59
This |enumeration_in_progress_| also include other
| |
142 io_loop_(NULL) { | 149 io_loop_(NULL) { |
143 } | 150 } |
144 | 151 |
145 MediaStreamManager::~MediaStreamManager() { | 152 MediaStreamManager::~MediaStreamManager() { |
146 DCHECK(requests_.empty()); | 153 DCHECK(requests_.empty()); |
147 DCHECK(!device_thread_.get()); | 154 DCHECK(!device_thread_.get()); |
148 DCHECK(!io_loop_); | 155 DCHECK(!io_loop_); |
149 } | 156 } |
150 | 157 |
151 VideoCaptureManager* MediaStreamManager::video_capture_manager() { | 158 VideoCaptureManager* MediaStreamManager::video_capture_manager() { |
(...skipping 17 matching lines...) Expand all Loading... | |
169 const GURL& security_origin, | 176 const GURL& security_origin, |
170 std::string* label) { | 177 std::string* label) { |
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
172 | 179 |
173 // Create a new request based on options. | 180 // Create a new request based on options. |
174 DeviceRequest new_request(requester, options, | 181 DeviceRequest new_request(requester, options, |
175 render_process_id, | 182 render_process_id, |
176 render_view_id, | 183 render_view_id, |
177 security_origin); | 184 security_origin); |
178 StartEnumeration(&new_request, label); | 185 StartEnumeration(&new_request, label); |
186 | |
187 // Get user confirmation to use capture devices. | |
188 // Need to make an asynchronous call to make sure the |requester| gets the | |
189 // |label| before it would receive any event. | |
190 BrowserThread::PostTask(BrowserThread::IO, | |
191 FROM_HERE, | |
192 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | |
193 base::Unretained(device_settings_.get()), | |
194 *label, render_process_id, | |
195 render_view_id, options, | |
196 security_origin)); | |
179 } | 197 } |
180 | 198 |
181 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { | 199 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) { |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
183 DeviceRequests::iterator it = requests_.begin(); | 201 DeviceRequests::iterator it = requests_.begin(); |
184 while (it != requests_.end()) { | 202 while (it != requests_.end()) { |
185 if (it->second.requester == requester && !RequestDone(it->second)) { | 203 if (it->second.requester == requester && !RequestDone(it->second)) { |
186 // The request isn't complete, but there might be some devices already | 204 // The request isn't complete, but there might be some devices already |
187 // opened -> close them. | 205 // opened -> close them. |
188 DeviceRequest* request = &(it->second); | 206 DeviceRequest* request = &(it->second); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 } | 257 } |
240 device_settings_->RemovePendingCaptureRequest(label); | 258 device_settings_->RemovePendingCaptureRequest(label); |
241 } | 259 } |
242 } | 260 } |
243 | 261 |
244 void MediaStreamManager::StopGeneratedStream(const std::string& label) { | 262 void MediaStreamManager::StopGeneratedStream(const std::string& label) { |
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
246 // Find the request and close all open devices for the request. | 264 // Find the request and close all open devices for the request. |
247 DeviceRequests::iterator it = requests_.find(label); | 265 DeviceRequests::iterator it = requests_.find(label); |
248 if (it != requests_.end()) { | 266 if (it != requests_.end()) { |
267 if (it->second.type == DeviceRequest::kEnumerateDevices) { | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
kEnumerateDevices -> ENUMERATE_DEVICES
wjia(left Chromium)
2012/08/01 01:28:59
Done.
| |
268 StopEnumerateDevices(label); | |
269 return; | |
270 } | |
249 for (StreamDeviceInfoArray::iterator audio_it = | 271 for (StreamDeviceInfoArray::iterator audio_it = |
250 it->second.audio_devices.begin(); | 272 it->second.audio_devices.begin(); |
251 audio_it != it->second.audio_devices.end(); ++audio_it) { | 273 audio_it != it->second.audio_devices.end(); ++audio_it) { |
252 audio_input_device_manager()->Close(audio_it->session_id); | 274 audio_input_device_manager()->Close(audio_it->session_id); |
253 } | 275 } |
254 for (StreamDeviceInfoArray::iterator video_it = | 276 for (StreamDeviceInfoArray::iterator video_it = |
255 it->second.video_devices.begin(); | 277 it->second.video_devices.begin(); |
256 video_it != it->second.video_devices.end(); ++video_it) { | 278 video_it != it->second.video_devices.end(); ++video_it) { |
257 video_capture_manager()->Close(video_it->session_id); | 279 video_capture_manager()->Close(video_it->session_id); |
258 } | 280 } |
259 if (it->second.type == DeviceRequest::kGenerateStream) { | 281 if (it->second.type == DeviceRequest::kGenerateStream) { |
260 NotifyObserverDevicesClosed(&(it->second)); | 282 NotifyObserverDevicesClosed(&(it->second)); |
261 } | 283 } |
262 requests_.erase(it); | 284 requests_.erase(it); |
263 return; | |
264 } | 285 } |
265 } | 286 } |
266 | 287 |
267 void MediaStreamManager::EnumerateDevices( | 288 void MediaStreamManager::EnumerateDevices( |
268 MediaStreamRequester* requester, | 289 MediaStreamRequester* requester, |
269 int render_process_id, | 290 int render_process_id, |
270 int render_view_id, | 291 int render_view_id, |
271 MediaStreamType type, | 292 MediaStreamType type, |
272 const GURL& security_origin, | 293 const GURL& security_origin, |
273 std::string* label) { | 294 std::string* label) { |
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
296 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || | |
297 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); | |
275 | 298 |
276 // Create a new request. | 299 // Create a new request. |
277 StreamOptions options; | 300 StreamOptions options; |
278 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 301 EnumerationCache* cache = NULL; |
302 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | |
279 options.audio = true; | 303 options.audio = true; |
280 else | 304 cache = &audio_enumeration_cache_; |
305 } else { | |
281 options.video = true; | 306 options.video = true; |
307 cache = &video_enumeration_cache_; | |
308 } | |
282 | 309 |
283 DeviceRequest new_request(requester, options, | 310 DeviceRequest new_request(requester, options, |
284 render_process_id, | 311 render_process_id, |
285 render_view_id, | 312 render_view_id, |
286 security_origin); | 313 security_origin); |
287 new_request.type = DeviceRequest::kEnumerateDevices; | 314 new_request.type = DeviceRequest::kEnumerateDevices; |
288 | 315 |
289 StartEnumeration(&new_request, label); | 316 if (cache->valid) { |
317 // Cached device list of this type exists. Just send it out. | |
318 new_request.state[type] = DeviceRequest::kRequested; | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
kRequested -> REQUESTED
wjia(left Chromium)
2012/08/01 01:28:59
Done.
| |
319 AddRequest(&new_request, label); | |
320 // Need to post a task since the requester won't have label till | |
321 // this function returns. | |
322 BrowserThread::PostTask(BrowserThread::IO, | |
323 FROM_HERE, | |
324 base::Bind(&MediaStreamManager::SendCachedDeviceList, | |
325 base::Unretained(this), cache, *label)); | |
326 } else { | |
327 StartEnumeration(&new_request, label); | |
328 StartMonitoring(); | |
329 } | |
330 } | |
331 | |
332 void MediaStreamManager::StopEnumerateDevices(const std::string& label) { | |
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
334 | |
335 DeviceRequests::iterator it = requests_.find(label); | |
336 if (it != requests_.end()) { | |
337 DCHECK_EQ(it->second.type, DeviceRequest::kEnumerateDevices); | |
338 requests_.erase(it); | |
339 if (!HasEnumerationRequest()) { | |
340 StopMonitoring(); | |
341 } | |
342 } | |
290 } | 343 } |
291 | 344 |
292 void MediaStreamManager::OpenDevice( | 345 void MediaStreamManager::OpenDevice( |
293 MediaStreamRequester* requester, | 346 MediaStreamRequester* requester, |
294 int render_process_id, | 347 int render_process_id, |
295 int render_view_id, | 348 int render_view_id, |
296 const std::string& device_id, | 349 const std::string& device_id, |
297 MediaStreamType type, | 350 MediaStreamType type, |
298 const GURL& security_origin, | 351 const GURL& security_origin, |
299 std::string* label) { | 352 std::string* label) { |
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
301 | 354 |
302 // Create a new request. | 355 // Create a new request. |
303 StreamOptions options; | 356 StreamOptions options; |
304 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 357 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) |
305 options.audio = true; | 358 options.audio = true; |
306 else | 359 else |
307 options.video = true; | 360 options.video = true; |
308 | 361 |
309 DeviceRequest new_request(requester, options, | 362 DeviceRequest new_request(requester, options, |
310 render_process_id, | 363 render_process_id, |
311 render_view_id, | 364 render_view_id, |
312 security_origin); | 365 security_origin); |
313 new_request.type = DeviceRequest::kOpenDevice; | 366 new_request.type = DeviceRequest::kOpenDevice; |
314 new_request.requested_device_id = device_id; | 367 new_request.requested_device_id = device_id; |
315 | 368 |
316 StartEnumeration(&new_request, label); | 369 StartEnumeration(&new_request, label); |
317 } | 370 } |
318 | 371 |
372 void MediaStreamManager::SendCachedDeviceList( | |
373 EnumerationCache* cache, | |
374 const std::string& label) { | |
375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
376 if (cache->valid && requests_.find(label) != requests_.end()) { | |
377 requests_[label].requester->DevicesEnumerated(label, cache->devices); | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
nit: you've already looked up the label so you cou
wjia(left Chromium)
2012/08/01 01:28:59
Done.
| |
378 } | |
379 } | |
380 | |
381 void MediaStreamManager::StartMonitoring() { | |
382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
383 if (!monitoring_started_) { | |
384 monitoring_started_ = true; | |
385 content::BrowserMainLoop::GetDevicesMonitor()->Start(this); | |
386 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
What do you think about this:
* Remove:
- Start
wjia(left Chromium)
2012/08/01 01:28:59
The start/stop of DeviceMonitor has been removed b
tommi (sloooow) - chröme
2012/08/01 10:21:37
Great. Thanks.
| |
387 } | |
388 } | |
389 | |
390 void MediaStreamManager::StopMonitoring() { | |
391 DCHECK_EQ(MessageLoop::current(), io_loop_); | |
392 if (monitoring_started_ && !HasEnumerationRequest()) { | |
393 content::BrowserMainLoop::GetDevicesMonitor()->Stop(this); | |
394 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); | |
395 monitoring_started_ = false; | |
396 ClearEnumerationCache(&audio_enumeration_cache_); | |
397 ClearEnumerationCache(&video_enumeration_cache_); | |
398 } | |
399 } | |
400 | |
401 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
could an empty cache mean valid == false?
if so, w
wjia(left Chromium)
2012/08/01 01:28:59
Unfortunately, empty cache doesn't mean valid or i
tommi (sloooow) - chröme
2012/08/01 10:21:37
sgtm.
| |
402 DCHECK_EQ(MessageLoop::current(), io_loop_); | |
403 if (cache->valid) { | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
no need to check it first. just set valid to fals
wjia(left Chromium)
2012/08/01 01:28:59
Done.
| |
404 cache->valid = false; | |
405 } | |
406 } | |
407 | |
319 void MediaStreamManager::StartEnumeration( | 408 void MediaStreamManager::StartEnumeration( |
320 DeviceRequest* new_request, | 409 DeviceRequest* new_request, |
321 std::string* label) { | 410 std::string* label) { |
322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
323 | 412 |
324 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | 413 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
325 if (Requested(new_request->options, stream_type)) { | 414 if (Requested(new_request->options, stream_type)) { |
326 new_request->state[stream_type] = DeviceRequest::kRequested; | 415 new_request->state[stream_type] = DeviceRequest::kRequested; |
327 if (!enumeration_in_progress_[stream_type]) { | 416 if (!enumeration_in_progress_[stream_type]) { |
328 enumeration_in_progress_[stream_type] = true; | 417 enumeration_in_progress_[stream_type] = true; |
329 GetDeviceManager(stream_type)->EnumerateDevices(); | 418 GetDeviceManager(stream_type)->EnumerateDevices(); |
330 } | 419 } |
331 } | 420 } |
332 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | 421 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
333 if (Requested(new_request->options, stream_type)) { | 422 if (Requested(new_request->options, stream_type)) { |
334 new_request->state[stream_type] = DeviceRequest::kRequested; | 423 new_request->state[stream_type] = DeviceRequest::kRequested; |
335 if (!enumeration_in_progress_[stream_type]) { | 424 if (!enumeration_in_progress_[stream_type]) { |
336 enumeration_in_progress_[stream_type] = true; | 425 enumeration_in_progress_[stream_type] = true; |
337 GetDeviceManager(stream_type)->EnumerateDevices(); | 426 GetDeviceManager(stream_type)->EnumerateDevices(); |
338 } | 427 } |
339 } | 428 } |
340 | 429 |
430 AddRequest(new_request, label); | |
431 } | |
432 | |
433 void MediaStreamManager::AddRequest( | |
434 DeviceRequest* new_request, | |
435 std::string* label) { | |
436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
437 | |
341 // Create a label for this request and verify it is unique. | 438 // Create a label for this request and verify it is unique. |
342 std::string request_label; | 439 std::string request_label; |
343 do { | 440 do { |
344 request_label = RandomLabel(); | 441 request_label = RandomLabel(); |
345 } while (requests_.find(request_label) != requests_.end()); | 442 } while (requests_.find(request_label) != requests_.end()); |
346 | 443 |
347 requests_.insert(std::make_pair(request_label, *new_request)); | 444 requests_.insert(std::make_pair(request_label, *new_request)); |
348 | 445 |
349 // Get user confirmation to use capture devices. | |
350 // Need to make an asynchronous call to make sure the |requester| gets the | |
351 // |label| before it would receive any event. | |
352 if (new_request->type == DeviceRequest::kGenerateStream) { | |
353 BrowserThread::PostTask(BrowserThread::IO, | |
354 FROM_HERE, | |
355 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, | |
356 base::Unretained(device_settings_.get()), | |
357 request_label, new_request->render_process_id, | |
358 new_request->render_view_id, new_request->options, | |
359 new_request->security_origin)); | |
360 } | |
361 | |
362 (*label) = request_label; | 446 (*label) = request_label; |
363 } | 447 } |
364 | 448 |
365 void MediaStreamManager::EnsureDeviceThreadAndListener() { | 449 void MediaStreamManager::EnsureDeviceThreadAndListener() { |
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 450 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
367 if (device_thread_.get()) | 451 if (device_thread_.get()) |
368 return; | 452 return; |
369 | 453 |
370 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); | 454 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); |
371 CHECK(device_thread_->Start()); | 455 CHECK(device_thread_->Start()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 | 532 |
449 void MediaStreamManager::Closed(MediaStreamType stream_type, | 533 void MediaStreamManager::Closed(MediaStreamType stream_type, |
450 int capture_session_id) { | 534 int capture_session_id) { |
451 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 535 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
452 } | 536 } |
453 | 537 |
454 void MediaStreamManager::DevicesEnumerated( | 538 void MediaStreamManager::DevicesEnumerated( |
455 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { | 539 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 540 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
457 | 541 |
542 // Only cache device list when there is EnumerateDevices request, since | |
543 // other requests don't turn on device monitoring. | |
544 bool need_update_clients = false; | |
545 EnumerationCache* cache = | |
546 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? | |
547 &audio_enumeration_cache_ : &video_enumeration_cache_); | |
548 if (HasEnumerationRequest(stream_type)) { | |
549 if (!cache->valid || cache->devices != devices) { | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
I think this is a case for not needing the |valid|
wjia(left Chromium)
2012/08/01 01:28:59
Without |valid| flag, we have to keep cache always
tommi (sloooow) - chröme
2012/08/01 10:21:37
sgtm
| |
550 cache->devices = devices; | |
551 need_update_clients = true; | |
552 } | |
553 } | |
554 | |
458 // Publish the result for all requests waiting for device list(s). | 555 // Publish the result for all requests waiting for device list(s). |
459 // Find the requests waiting for this device list, store their labels and | 556 // Find the requests waiting for this device list, store their labels and |
460 // release the iterator before calling device settings. We might get a call | 557 // release the iterator before calling device settings. We might get a call |
461 // back from device_settings that will need to iterate through devices. | 558 // back from device_settings that will need to iterate through devices. |
462 std::list<std::string> label_list; | 559 std::list<std::string> label_list; |
463 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 560 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
464 ++it) { | 561 ++it) { |
465 if (it->second.state[stream_type] == DeviceRequest::kRequested && | 562 if (it->second.state[stream_type] == DeviceRequest::kRequested && |
466 Requested(it->second.options, stream_type)) { | 563 Requested(it->second.options, stream_type)) { |
467 it->second.state[stream_type] = DeviceRequest::kPendingApproval; | 564 if (it->second.type != DeviceRequest::kEnumerateDevices) |
565 it->second.state[stream_type] = DeviceRequest::kPendingApproval; | |
468 label_list.push_back(it->first); | 566 label_list.push_back(it->first); |
469 } | 567 } |
470 } | 568 } |
471 for (std::list<std::string>::iterator it = label_list.begin(); | 569 for (std::list<std::string>::iterator it = label_list.begin(); |
472 it != label_list.end(); ++it) { | 570 it != label_list.end(); ++it) { |
473 DeviceRequest& request = requests_[*it]; | 571 DeviceRequest& request = requests_[*it]; |
474 switch (request.type) { | 572 switch (request.type) { |
475 case DeviceRequest::kEnumerateDevices: | 573 case DeviceRequest::kEnumerateDevices: |
476 request.requester->DevicesEnumerated(*it, devices); | 574 if (need_update_clients) |
477 requests_.erase(*it); | 575 request.requester->DevicesEnumerated(*it, devices); |
478 break; | 576 break; |
479 case DeviceRequest::kOpenDevice: | 577 case DeviceRequest::kOpenDevice: |
480 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 578 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
481 device_it != devices.end(); device_it++) { | 579 device_it != devices.end(); device_it++) { |
482 if (request.requested_device_id == device_it->device_id) { | 580 if (request.requested_device_id == device_it->device_id) { |
483 StreamDeviceInfo device = *device_it; | 581 StreamDeviceInfo device = *device_it; |
484 device.in_use = false; | 582 device.in_use = false; |
485 device.session_id = | 583 device.session_id = |
486 GetDeviceManager(device_it->stream_type)->Open(device); | 584 GetDeviceManager(device_it->stream_type)->Open(device); |
487 request.state[device_it->stream_type] = DeviceRequest::kOpening; | 585 request.state[device_it->stream_type] = DeviceRequest::kOpening; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 } | 719 } |
622 | 720 |
623 void MediaStreamManager::UseFakeDevice() { | 721 void MediaStreamManager::UseFakeDevice() { |
624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
625 video_capture_manager()->UseFakeDevice(); | 723 video_capture_manager()->UseFakeDevice(); |
626 device_settings_->UseFakeUI(); | 724 device_settings_->UseFakeUI(); |
627 } | 725 } |
628 | 726 |
629 void MediaStreamManager::WillDestroyCurrentMessageLoop() { | 727 void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
630 DCHECK_EQ(MessageLoop::current(), io_loop_); | 728 DCHECK_EQ(MessageLoop::current(), io_loop_); |
729 DCHECK(requests_.empty()); | |
631 if (device_thread_.get()) { | 730 if (device_thread_.get()) { |
731 StopMonitoring(); | |
732 | |
632 video_capture_manager_->Unregister(); | 733 video_capture_manager_->Unregister(); |
633 audio_input_device_manager_->Unregister(); | 734 audio_input_device_manager_->Unregister(); |
634 device_thread_.reset(); | 735 device_thread_.reset(); |
635 } | 736 } |
636 | 737 |
637 audio_input_device_manager_ = NULL; | 738 audio_input_device_manager_ = NULL; |
638 video_capture_manager_ = NULL; | 739 video_capture_manager_ = NULL; |
639 io_loop_ = NULL; | 740 io_loop_ = NULL; |
640 device_settings_.reset(); | 741 device_settings_.reset(); |
641 } | 742 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 MediaStreamType stream_type) { | 815 MediaStreamType stream_type) { |
715 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 816 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
716 return video_capture_manager(); | 817 return video_capture_manager(); |
717 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 818 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { |
718 return audio_input_device_manager(); | 819 return audio_input_device_manager(); |
719 } | 820 } |
720 NOTREACHED(); | 821 NOTREACHED(); |
721 return NULL; | 822 return NULL; |
722 } | 823 } |
723 | 824 |
825 void MediaStreamManager::OnDevicesChanged( | |
826 base::SystemMonitor::DeviceType device_type) { | |
827 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
828 MediaStreamType stream_type; | |
829 EnumerationCache* cache; | |
830 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { | |
831 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | |
832 cache = &audio_enumeration_cache_; | |
833 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { | |
834 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | |
835 cache = &video_enumeration_cache_; | |
836 } else { | |
837 return; // Uninterested device change. | |
tommi (sloooow) - chröme
2012/07/30 12:10:21
s/Uninterested/Uninteresting.
wjia(left Chromium)
2012/08/01 01:28:59
Done.
| |
838 } | |
839 | |
840 if (!HasEnumerationRequest(stream_type)) { | |
841 // There is no request for that type, No need to enumerate devices. | |
842 // Therefore, invalidate the cache of that type. | |
843 ClearEnumerationCache(cache); | |
844 } else if (!enumeration_in_progress_[stream_type]) { | |
845 enumeration_in_progress_[stream_type] = true; | |
846 GetDeviceManager(stream_type)->EnumerateDevices(); | |
847 } | |
848 } | |
849 | |
850 bool MediaStreamManager::HasEnumerationRequest() { | |
851 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
852 for (DeviceRequests::iterator it = requests_.begin(); | |
853 it != requests_.end(); ++it) { | |
854 DeviceRequest& request = it->second; | |
855 if (request.type == DeviceRequest::kEnumerateDevices) { | |
856 return true; | |
857 } | |
858 } | |
859 return false; | |
860 } | |
861 | |
862 bool MediaStreamManager::HasEnumerationRequest( | |
863 MediaStreamType stream_type) { | |
864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
865 for (DeviceRequests::iterator it = requests_.begin(); | |
866 it != requests_.end(); ++it) { | |
867 DeviceRequest& request = it->second; | |
868 if (request.type == DeviceRequest::kEnumerateDevices && | |
869 Requested(request.options, stream_type)) { | |
870 return true; | |
871 } | |
872 } | |
873 return false; | |
874 } | |
875 | |
724 } // namespace media_stream | 876 } // namespace media_stream |
OLD | NEW |