Chromium Code Reviews| 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 |