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/renderer_host/media/audio_input_device_manager.h" | 14 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| 15 #include "content/browser/renderer_host/media/media_stream_device_settings.h" | 15 #include "content/browser/renderer_host/media/media_stream_device_settings.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/video_capture_manager.h" | 17 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 18 #include "content/common/media/media_stream_options.h" | 18 #include "content/common/media/media_stream_options.h" |
| 19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
| 21 #include "content/public/browser/media_observer.h" | 21 #include "content/public/browser/media_observer.h" |
| 22 #include "googleurl/src/gurl.h" | 22 #include "googleurl/src/gurl.h" |
| 23 | 23 |
| 24 using content::BrowserThread; | 24 using content::BrowserThread; |
| 25 using content::MediaStreamRequest; | |
| 25 | 26 |
| 26 namespace media_stream { | 27 namespace media_stream { |
| 27 | 28 |
| 28 // Creates a random label used to identify requests. | 29 // Creates a random label used to identify requests. |
| 29 static std::string RandomLabel() { | 30 static std::string RandomLabel() { |
| 30 // An earlier PeerConnection spec, | 31 // An earlier PeerConnection spec, |
| 31 // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the | 32 // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the |
| 32 // MediaStream::label alphabet as containing 36 characters from | 33 // MediaStream::label alphabet as containing 36 characters from |
| 33 // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, | 34 // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, |
| 34 // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. | 35 // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 64 // Enter the multi-threaded apartment. | 65 // Enter the multi-threaded apartment. |
| 65 com_initializer_.reset(new ScopedCOMInitializer(ScopedCOMInitializer::kMTA)); | 66 com_initializer_.reset(new ScopedCOMInitializer(ScopedCOMInitializer::kMTA)); |
| 66 } | 67 } |
| 67 | 68 |
| 68 void DeviceThread::CleanUp() { | 69 void DeviceThread::CleanUp() { |
| 69 com_initializer_.reset(); | 70 com_initializer_.reset(); |
| 70 } | 71 } |
| 71 | 72 |
| 72 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. | 73 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. |
| 73 struct MediaStreamManager::DeviceRequest { | 74 struct MediaStreamManager::DeviceRequest { |
| 74 enum RequestState { | |
| 75 STATE_NOT_REQUESTED = 0, | |
| 76 STATE_REQUESTED, | |
| 77 STATE_PENDING_APPROVAL, | |
| 78 STATE_OPENING, | |
| 79 STATE_DONE, | |
| 80 STATE_ERROR | |
| 81 }; | |
| 82 | |
| 83 enum RequestType { | 75 enum RequestType { |
| 84 GENERATE_STREAM = 0, | 76 GENERATE_STREAM = 0, |
| 85 ENUMERATE_DEVICES, | 77 ENUMERATE_DEVICES, |
| 86 OPEN_DEVICE | 78 OPEN_DEVICE |
| 87 }; | 79 }; |
| 88 | 80 |
| 89 DeviceRequest() | 81 DeviceRequest() |
| 90 : requester(NULL), | 82 : requester(NULL), |
| 91 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), | 83 state(content::NUM_MEDIA_TYPES, |
| 84 MediaStreamRequest::STATE_NOT_REQUESTED), | |
| 92 type(GENERATE_STREAM), | 85 type(GENERATE_STREAM), |
| 93 render_process_id(-1), | 86 render_process_id(-1), |
| 94 render_view_id(-1) { | 87 render_view_id(-1) { |
| 95 } | 88 } |
| 96 | 89 |
| 97 DeviceRequest(MediaStreamRequester* requester, | 90 DeviceRequest(MediaStreamRequester* requester, |
| 98 const StreamOptions& request_options, | 91 const StreamOptions& request_options, |
| 99 int render_process_id, | 92 int render_process_id, |
| 100 int render_view_id, | 93 int render_view_id, |
| 101 const GURL& request_security_origin) | 94 const GURL& request_security_origin) |
| 102 : requester(requester), | 95 : requester(requester), |
| 103 options(request_options), | 96 options(request_options), |
| 104 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), | 97 state(content::NUM_MEDIA_TYPES, |
| 98 MediaStreamRequest::STATE_NOT_REQUESTED), | |
| 105 type(GENERATE_STREAM), | 99 type(GENERATE_STREAM), |
| 106 render_process_id(render_process_id), | 100 render_process_id(render_process_id), |
| 107 render_view_id(render_view_id), | 101 render_view_id(render_view_id), |
| 108 security_origin(request_security_origin) { | 102 security_origin(request_security_origin) { |
| 109 DCHECK(requester); | 103 DCHECK(requester); |
| 110 } | 104 } |
| 111 | 105 |
| 112 ~DeviceRequest() {} | 106 ~DeviceRequest() {} |
| 113 | 107 |
| 114 MediaStreamRequester* requester; | 108 MediaStreamRequester* requester; |
| 115 StreamOptions options; | 109 StreamOptions options; |
| 116 std::vector<RequestState> state; | 110 std::vector<MediaStreamRequest::RequestState> state; |
| 117 RequestType type; | 111 RequestType type; |
| 118 int render_process_id; | 112 int render_process_id; |
| 119 int render_view_id; | 113 int render_view_id; |
| 120 GURL security_origin; | 114 GURL security_origin; |
| 121 std::string requested_device_id; | 115 std::string requested_device_id; |
| 122 StreamDeviceInfoArray devices; | 116 StreamDeviceInfoArray devices; |
| 123 }; | 117 }; |
| 124 | 118 |
| 125 MediaStreamManager::EnumerationCache::EnumerationCache() | 119 MediaStreamManager::EnumerationCache::EnumerationCache() |
| 126 : valid(false) { | 120 : valid(false) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 device_settings_->RequestCaptureDeviceUsage(*label, | 203 device_settings_->RequestCaptureDeviceUsage(*label, |
| 210 render_process_id, | 204 render_process_id, |
| 211 render_view_id, | 205 render_view_id, |
| 212 options, | 206 options, |
| 213 security_origin); | 207 security_origin); |
| 214 // TODO(miu): We should ask the device manager whether a device with id | 208 // TODO(miu): We should ask the device manager whether a device with id |
| 215 // |device_id| actually exists. Note that no such MediaStreamProvider API for | 209 // |device_id| actually exists. Note that no such MediaStreamProvider API for |
| 216 // this currently exists. Also, we don't have a user-friendly device name for | 210 // this currently exists. Also, we don't have a user-friendly device name for |
| 217 // the infobar UI. | 211 // the infobar UI. |
| 218 if (content::IsAudioMediaType(options.audio_type)) { | 212 if (content::IsAudioMediaType(options.audio_type)) { |
| 219 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL; | 213 UpdateRequestState(&request, options.audio_type, |
| 214 MediaStreamRequest::STATE_PENDING_APPROVAL); | |
| 220 device_settings_->AvailableDevices( | 215 device_settings_->AvailableDevices( |
| 221 *label, options.audio_type, StreamDeviceInfoArray( | 216 *label, options.audio_type, StreamDeviceInfoArray( |
| 222 1, StreamDeviceInfo(options.audio_type, device_id, device_id, | 217 1, StreamDeviceInfo(options.audio_type, device_id, device_id, |
| 223 false))); | 218 false))); |
| 224 } | 219 } |
| 225 if (content::IsVideoMediaType(options.video_type)) { | 220 if (content::IsVideoMediaType(options.video_type)) { |
| 226 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL; | 221 request.state[options.video_type] = |
|
perkj_chrome
2012/09/27 13:21:48
Why is there two ways of setting the RequestState?
justinlin
2012/10/02 17:19:48
Done. Missed this one. Made the field private so a
| |
| 222 MediaStreamRequest::STATE_PENDING_APPROVAL; | |
| 227 device_settings_->AvailableDevices( | 223 device_settings_->AvailableDevices( |
| 228 *label, options.video_type, StreamDeviceInfoArray( | 224 *label, options.video_type, StreamDeviceInfoArray( |
| 229 1, StreamDeviceInfo(options.video_type, device_id, device_id, | 225 1, StreamDeviceInfo(options.video_type, device_id, device_id, |
| 230 false))); | 226 false))); |
| 231 } | 227 } |
| 232 } | 228 } |
| 233 | 229 |
| 234 void MediaStreamManager::CancelGenerateStream(const std::string& label) { | 230 void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
| 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 236 | 232 |
| 237 DeviceRequests::iterator it = requests_.find(label); | 233 DeviceRequests::iterator it = requests_.find(label); |
| 238 if (it != requests_.end()) { | 234 if (it != requests_.end()) { |
| 239 // The request isn't complete. | 235 // The request isn't complete. |
| 240 if (!RequestDone(it->second)) { | 236 if (!RequestDone(it->second)) { |
| 241 DeviceRequest& request = it->second; | 237 DeviceRequest& request = it->second; |
| 242 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; | 238 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
| 243 ++i) { | 239 ++i) { |
| 244 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 240 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| 245 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) { | 241 if (request.state[stream_type] != MediaStreamRequest::STATE_OPENING) { |
| 246 continue; | 242 continue; |
| 247 } | 243 } |
| 248 for (StreamDeviceInfoArray::const_iterator device_it = | 244 for (StreamDeviceInfoArray::const_iterator device_it = |
| 249 request.devices.begin(); | 245 request.devices.begin(); |
| 250 device_it != request.devices.end(); ++device_it) { | 246 device_it != request.devices.end(); ++device_it) { |
| 251 if (device_it->stream_type == stream_type) { | 247 if (device_it->stream_type == stream_type) { |
| 252 GetDeviceManager(stream_type)->Close(device_it->session_id); | 248 GetDeviceManager(stream_type)->Close(device_it->session_id); |
| 253 } | 249 } |
| 254 } | 250 } |
| 255 } | 251 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 } | 305 } |
| 310 | 306 |
| 311 DeviceRequest new_request(requester, options, | 307 DeviceRequest new_request(requester, options, |
| 312 render_process_id, | 308 render_process_id, |
| 313 render_view_id, | 309 render_view_id, |
| 314 security_origin); | 310 security_origin); |
| 315 new_request.type = DeviceRequest::ENUMERATE_DEVICES; | 311 new_request.type = DeviceRequest::ENUMERATE_DEVICES; |
| 316 | 312 |
| 317 if (cache->valid) { | 313 if (cache->valid) { |
| 318 // Cached device list of this type exists. Just send it out. | 314 // Cached device list of this type exists. Just send it out. |
| 319 new_request.state[type] = DeviceRequest::STATE_REQUESTED; | 315 new_request.state[type] = MediaStreamRequest::STATE_REQUESTED; |
| 320 AddRequest(new_request, label); | 316 AddRequest(new_request, label); |
| 321 // Need to post a task since the requester won't have label till | 317 // Need to post a task since the requester won't have label till |
| 322 // this function returns. | 318 // this function returns. |
| 323 BrowserThread::PostTask(BrowserThread::IO, | 319 BrowserThread::PostTask(BrowserThread::IO, |
| 324 FROM_HERE, | 320 FROM_HERE, |
| 325 base::Bind(&MediaStreamManager::SendCachedDeviceList, | 321 base::Bind(&MediaStreamManager::SendCachedDeviceList, |
| 326 base::Unretained(this), cache, *label)); | 322 base::Unretained(this), cache, *label)); |
| 327 } else { | 323 } else { |
| 328 StartEnumeration(&new_request, label); | 324 StartEnumeration(&new_request, label); |
| 329 StartMonitoring(); | 325 StartMonitoring(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 ClearEnumerationCache(&audio_enumeration_cache_); | 400 ClearEnumerationCache(&audio_enumeration_cache_); |
| 405 ClearEnumerationCache(&video_enumeration_cache_); | 401 ClearEnumerationCache(&video_enumeration_cache_); |
| 406 } | 402 } |
| 407 } | 403 } |
| 408 | 404 |
| 409 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 405 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
| 410 DCHECK_EQ(MessageLoop::current(), io_loop_); | 406 DCHECK_EQ(MessageLoop::current(), io_loop_); |
| 411 cache->valid = false; | 407 cache->valid = false; |
| 412 } | 408 } |
| 413 | 409 |
| 410 void MediaStreamManager::UpdateRequestState( | |
|
perkj_chrome
2012/09/27 13:21:48
No need to belong to MediaStreamManager. Can be st
justinlin
2012/10/02 17:19:48
Done.
| |
| 411 DeviceRequest* request, | |
| 412 MediaStreamType media_type_index, | |
| 413 const MediaStreamRequest::RequestState newState) { | |
| 414 request->state[media_type_index] = newState; | |
| 415 NotifyObserverRequestStateChange(request, media_type_index); | |
| 416 } | |
| 417 | |
| 414 void MediaStreamManager::StartEnumeration( | 418 void MediaStreamManager::StartEnumeration( |
| 415 DeviceRequest* new_request, | 419 DeviceRequest* new_request, |
| 416 std::string* label) { | 420 std::string* label) { |
| 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 418 | 422 |
| 419 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; | 423 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
| 420 ++i) { | 424 ++i) { |
| 421 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 425 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| 422 if (Requested(new_request->options, stream_type)) { | 426 if (Requested(new_request->options, stream_type)) { |
| 423 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; | 427 UpdateRequestState(new_request, stream_type, |
| 428 MediaStreamRequest::STATE_REQUESTED); | |
| 424 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 429 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
| 425 if (active_enumeration_ref_count_[stream_type] == 0) { | 430 if (active_enumeration_ref_count_[stream_type] == 0) { |
| 426 ++active_enumeration_ref_count_[stream_type]; | 431 ++active_enumeration_ref_count_[stream_type]; |
| 427 GetDeviceManager(stream_type)->EnumerateDevices(); | 432 GetDeviceManager(stream_type)->EnumerateDevices(); |
| 428 } | 433 } |
| 429 } | 434 } |
| 430 } | 435 } |
| 431 | 436 |
| 432 AddRequest(*new_request, label); | 437 AddRequest(*new_request, label); |
| 433 } | 438 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 request = &(request_it->second); | 497 request = &(request_it->second); |
| 493 break; | 498 break; |
| 494 } | 499 } |
| 495 } | 500 } |
| 496 } | 501 } |
| 497 if (request == NULL) { | 502 if (request == NULL) { |
| 498 // The request doesn't exist. | 503 // The request doesn't exist. |
| 499 return; | 504 return; |
| 500 } | 505 } |
| 501 | 506 |
| 502 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); | 507 DCHECK_NE(request->state[stream_type], MediaStreamRequest::STATE_REQUESTED); |
| 503 | 508 |
| 504 // Check if all devices for this stream type are opened. Update the state if | 509 // Check if all devices for this stream type are opened. Update the state if |
| 505 // they are. | 510 // they are. |
| 506 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 511 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
| 507 device_it != devices->end(); ++device_it) { | 512 device_it != devices->end(); ++device_it) { |
| 508 if (device_it->stream_type != stream_type) { | 513 if (device_it->stream_type != stream_type) { |
| 509 continue; | 514 continue; |
| 510 } | 515 } |
| 511 if (device_it->in_use == false) { | 516 if (device_it->in_use == false) { |
| 512 // Wait for more devices to be opened before we're done. | 517 // Wait for more devices to be opened before we're done. |
| 513 return; | 518 return; |
| 514 } | 519 } |
| 515 } | 520 } |
| 516 request->state[stream_type] = DeviceRequest::STATE_DONE; | 521 UpdateRequestState(request, stream_type, MediaStreamRequest::STATE_DONE); |
| 517 | 522 |
| 518 if (!RequestDone(*request)) { | 523 if (!RequestDone(*request)) { |
| 519 // This stream_type is done, but not the other type. | 524 // This stream_type is done, but not the other type. |
| 520 return; | 525 return; |
| 521 } | 526 } |
| 522 | 527 |
| 523 switch (request->type) { | 528 switch (request->type) { |
| 524 case DeviceRequest::OPEN_DEVICE: | 529 case DeviceRequest::OPEN_DEVICE: |
| 525 request->requester->DeviceOpened(label, devices->front()); | 530 request->requester->DeviceOpened(label, devices->front()); |
| 526 break; | 531 break; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 need_update_clients = true; | 578 need_update_clients = true; |
| 574 } | 579 } |
| 575 | 580 |
| 576 // Publish the result for all requests waiting for device list(s). | 581 // Publish the result for all requests waiting for device list(s). |
| 577 // Find the requests waiting for this device list, store their labels and | 582 // Find the requests waiting for this device list, store their labels and |
| 578 // release the iterator before calling device settings. We might get a call | 583 // release the iterator before calling device settings. We might get a call |
| 579 // back from device_settings that will need to iterate through devices. | 584 // back from device_settings that will need to iterate through devices. |
| 580 std::list<std::string> label_list; | 585 std::list<std::string> label_list; |
| 581 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 586 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
| 582 ++it) { | 587 ++it) { |
| 583 if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED && | 588 if (it->second.state[stream_type] == MediaStreamRequest::STATE_REQUESTED && |
| 584 Requested(it->second.options, stream_type)) { | 589 Requested(it->second.options, stream_type)) { |
| 585 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) | 590 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) |
| 586 it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL; | 591 UpdateRequestState(&it->second, stream_type, |
| 592 MediaStreamRequest::STATE_PENDING_APPROVAL); | |
| 587 label_list.push_back(it->first); | 593 label_list.push_back(it->first); |
| 588 } | 594 } |
| 589 } | 595 } |
| 590 for (std::list<std::string>::iterator it = label_list.begin(); | 596 for (std::list<std::string>::iterator it = label_list.begin(); |
| 591 it != label_list.end(); ++it) { | 597 it != label_list.end(); ++it) { |
| 592 DeviceRequest& request = requests_[*it]; | 598 DeviceRequest& request = requests_[*it]; |
| 593 switch (request.type) { | 599 switch (request.type) { |
| 594 case DeviceRequest::ENUMERATE_DEVICES: | 600 case DeviceRequest::ENUMERATE_DEVICES: |
| 595 if (need_update_clients) | 601 if (need_update_clients) |
| 596 request.requester->DevicesEnumerated(*it, devices); | 602 request.requester->DevicesEnumerated(*it, devices); |
| 597 break; | 603 break; |
| 598 case DeviceRequest::OPEN_DEVICE: | 604 case DeviceRequest::OPEN_DEVICE: |
| 599 DCHECK(!request.requested_device_id.empty()); | 605 DCHECK(!request.requested_device_id.empty()); |
| 600 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 606 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
| 601 device_it != devices.end(); ++device_it) { | 607 device_it != devices.end(); ++device_it) { |
| 602 if (request.requested_device_id == device_it->device_id) { | 608 if (request.requested_device_id == device_it->device_id) { |
| 603 StreamDeviceInfo device = *device_it; | 609 StreamDeviceInfo device = *device_it; |
| 604 device.in_use = false; | 610 device.in_use = false; |
| 605 device.session_id = | 611 device.session_id = |
| 606 GetDeviceManager(device_it->stream_type)->Open(device); | 612 GetDeviceManager(device_it->stream_type)->Open(device); |
| 607 request.state[device_it->stream_type] = | 613 UpdateRequestState(&request, device_it->stream_type, |
| 608 DeviceRequest::STATE_OPENING; | 614 MediaStreamRequest::STATE_OPENING); |
| 609 request.devices.push_back(device); | 615 request.devices.push_back(device); |
| 610 break; | 616 break; |
| 611 } | 617 } |
| 612 } | 618 } |
| 613 break; | 619 break; |
| 614 default: | 620 default: |
| 615 device_settings_->AvailableDevices(*it, stream_type, devices); | 621 device_settings_->AvailableDevices(*it, stream_type, devices); |
| 616 break; | 622 break; |
| 617 } | 623 } |
| 618 } | 624 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 644 ++video_device_idx; | 650 ++video_device_idx; |
| 645 } else { | 651 } else { |
| 646 NOTREACHED(); | 652 NOTREACHED(); |
| 647 continue; | 653 continue; |
| 648 } | 654 } |
| 649 if (device_it->stream_type != stream_type || | 655 if (device_it->stream_type != stream_type || |
| 650 device_it->session_id != capture_session_id) { | 656 device_it->session_id != capture_session_id) { |
| 651 continue; | 657 continue; |
| 652 } | 658 } |
| 653 // We've found the failing device. Find the error case: | 659 // We've found the failing device. Find the error case: |
| 654 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { | 660 if (it->second.state[stream_type] == MediaStreamRequest::STATE_DONE) { |
| 655 // 1. Already opened -> signal device failure and close device. | 661 // 1. Already opened -> signal device failure and close device. |
| 656 // Use device_idx to signal which of the devices encountered an | 662 // Use device_idx to signal which of the devices encountered an |
| 657 // error. | 663 // error. |
| 658 if (content::IsAudioMediaType(stream_type)) { | 664 if (content::IsAudioMediaType(stream_type)) { |
| 659 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx); | 665 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx); |
| 660 } else if (content::IsVideoMediaType(stream_type)) { | 666 } else if (content::IsVideoMediaType(stream_type)) { |
| 661 it->second.requester->VideoDeviceFailed(it->first, video_device_idx); | 667 it->second.requester->VideoDeviceFailed(it->first, video_device_idx); |
| 662 } else { | 668 } else { |
| 663 NOTREACHED(); | 669 NOTREACHED(); |
| 664 return; | 670 return; |
| 665 } | 671 } |
| 666 GetDeviceManager(stream_type)->Close(capture_session_id); | 672 GetDeviceManager(stream_type)->Close(capture_session_id); |
| 667 // We don't erase the devices here so that we can update the UI | 673 // We don't erase the devices here so that we can update the UI |
| 668 // properly in StopGeneratedStream(). | 674 // properly in StopGeneratedStream(). |
| 669 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | 675 UpdateRequestState(&it->second, stream_type, |
| 676 MediaStreamRequest::STATE_ERROR); | |
| 670 } else { | 677 } else { |
| 671 // Request is not done, devices are not opened in this case. | 678 // Request is not done, devices are not opened in this case. |
| 672 if (devices.size() <= 1) { | 679 if (devices.size() <= 1) { |
| 673 // 2. Device not opened and no other devices for this request -> | 680 // 2. Device not opened and no other devices for this request -> |
| 674 // signal stream error and remove the request. | 681 // signal stream error and remove the request. |
| 675 it->second.requester->StreamGenerationFailed(it->first); | 682 it->second.requester->StreamGenerationFailed(it->first); |
| 676 requests_.erase(it); | 683 requests_.erase(it); |
| 677 } else { | 684 } else { |
| 678 // 3. Not opened but other devices exists for this request -> remove | 685 // 3. Not opened but other devices exists for this request -> remove |
| 679 // device from list, but don't signal an error. | 686 // device from list, but don't signal an error. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 705 // Process all newly-accepted devices for this request. | 712 // Process all newly-accepted devices for this request. |
| 706 bool found_audio = false, found_video = false; | 713 bool found_audio = false, found_video = false; |
| 707 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 714 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
| 708 device_it != devices.end(); ++device_it) { | 715 device_it != devices.end(); ++device_it) { |
| 709 StreamDeviceInfo device_info = *device_it; // Make a copy. | 716 StreamDeviceInfo device_info = *device_it; // Make a copy. |
| 710 | 717 |
| 711 // Set in_use to false to be able to track if this device has been | 718 // Set in_use to false to be able to track if this device has been |
| 712 // opened. in_use might be true if the device type can be used in more | 719 // opened. in_use might be true if the device type can be used in more |
| 713 // than one session. | 720 // than one session. |
| 714 DCHECK_EQ(request.state[device_it->stream_type], | 721 DCHECK_EQ(request.state[device_it->stream_type], |
| 715 DeviceRequest::STATE_PENDING_APPROVAL); | 722 MediaStreamRequest::STATE_PENDING_APPROVAL); |
| 716 device_info.in_use = false; | 723 device_info.in_use = false; |
| 717 device_info.session_id = | 724 device_info.session_id = |
| 718 GetDeviceManager(device_info.stream_type)->Open(device_info); | 725 GetDeviceManager(device_info.stream_type)->Open(device_info); |
| 719 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING; | 726 UpdateRequestState(&request, device_it->stream_type, |
| 727 MediaStreamRequest::STATE_OPENING); | |
| 720 request.devices.push_back(device_info); | 728 request.devices.push_back(device_info); |
| 721 | 729 |
| 722 if (device_info.stream_type == request.options.audio_type) { | 730 if (device_info.stream_type == request.options.audio_type) { |
| 723 found_audio = true; | 731 found_audio = true; |
| 724 } else if (device_info.stream_type == request.options.video_type) { | 732 } else if (device_info.stream_type == request.options.video_type) { |
| 725 found_video = true; | 733 found_video = true; |
| 726 } | 734 } |
| 727 } | 735 } |
| 728 | 736 |
| 729 // Check whether we've received all stream types requested. | 737 // Check whether we've received all stream types requested. |
| 730 if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) { | 738 if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) { |
| 731 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR; | 739 UpdateRequestState(&request, request.options.audio_type, |
| 740 MediaStreamRequest::STATE_ERROR); | |
| 732 } | 741 } |
| 733 if (!found_video && content::IsVideoMediaType(request.options.video_type)) { | 742 if (!found_video && content::IsVideoMediaType(request.options.video_type)) { |
| 734 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR; | 743 UpdateRequestState(&request, request.options.video_type, |
| 744 MediaStreamRequest::STATE_ERROR); | |
| 735 } | 745 } |
| 736 } | 746 } |
| 737 | 747 |
| 738 void MediaStreamManager::SettingsError(const std::string& label) { | 748 void MediaStreamManager::SettingsError(const std::string& label) { |
| 739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 749 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 740 // Erase this request and report an error. | 750 // Erase this request and report an error. |
| 741 DeviceRequests::iterator it = requests_.find(label); | 751 DeviceRequests::iterator it = requests_.find(label); |
| 742 if (it != requests_.end()) { | 752 if (it != requests_.end()) { |
| 743 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); | 753 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); |
| 744 it->second.requester->StreamGenerationFailed(label); | 754 it->second.requester->StreamGenerationFailed(label); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 790 return; | 800 return; |
| 791 content::MediaStreamDevices closed_devices; | 801 content::MediaStreamDevices closed_devices; |
| 792 DevicesFromRequest(request, &closed_devices); | 802 DevicesFromRequest(request, &closed_devices); |
| 793 if (closed_devices.empty()) | 803 if (closed_devices.empty()) |
| 794 return; | 804 return; |
| 795 media_observer->OnCaptureDevicesClosed(request->render_process_id, | 805 media_observer->OnCaptureDevicesClosed(request->render_process_id, |
| 796 request->render_view_id, | 806 request->render_view_id, |
| 797 closed_devices); | 807 closed_devices); |
| 798 } | 808 } |
| 799 | 809 |
| 810 void MediaStreamManager::NotifyObserverRequestStateChange( | |
|
perkj_chrome
2012/09/27 13:21:48
No need to belong to MediaStreamManager- can be st
justinlin
2012/10/02 17:19:48
Done.
| |
| 811 DeviceRequest* request, MediaStreamType media_type) { | |
| 812 content::MediaObserver* media_observer = | |
| 813 content::GetContentClient()->browser()->GetMediaObserver(); | |
| 814 if (media_observer == NULL) | |
| 815 return; | |
| 816 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin(); | |
| 817 it != request->devices.end(); ++it) { | |
| 818 if (it->stream_type == media_type) { | |
| 819 media_observer->OnMediaRequestStateChange(request->render_process_id, | |
| 820 request->render_view_id, | |
| 821 content::MediaStreamDevice( | |
| 822 it->stream_type, | |
| 823 it->device_id, | |
| 824 it->name), | |
| 825 request->state[media_type]); | |
| 826 } | |
| 827 } | |
| 828 } | |
| 829 | |
| 800 void MediaStreamManager::DevicesFromRequest( | 830 void MediaStreamManager::DevicesFromRequest( |
| 801 DeviceRequest* request, content::MediaStreamDevices* devices) { | 831 DeviceRequest* request, content::MediaStreamDevices* devices) { |
| 802 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin(); | 832 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin(); |
| 803 it != request->devices.end(); ++it) { | 833 it != request->devices.end(); ++it) { |
| 804 devices->push_back(content::MediaStreamDevice( | 834 devices->push_back(content::MediaStreamDevice( |
| 805 it->stream_type, it->device_id, it->name)); | 835 it->stream_type, it->device_id, it->name)); |
| 806 } | 836 } |
| 807 } | 837 } |
| 808 | 838 |
| 809 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 839 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
| 810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 840 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 811 | 841 |
| 812 const bool requested_audio = | 842 const bool requested_audio = |
| 813 content::IsAudioMediaType(request.options.audio_type); | 843 content::IsAudioMediaType(request.options.audio_type); |
| 814 const bool requested_video = | 844 const bool requested_video = |
| 815 content::IsVideoMediaType(request.options.video_type); | 845 content::IsVideoMediaType(request.options.video_type); |
| 816 | 846 |
| 817 const bool audio_done = | 847 const bool audio_done = |
| 818 !requested_audio || | 848 !requested_audio || |
| 819 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE || | 849 request.state[request.options.audio_type] == |
| 820 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR; | 850 MediaStreamRequest::STATE_DONE || |
| 851 request.state[request.options.audio_type] == | |
| 852 MediaStreamRequest::STATE_ERROR; | |
| 821 if (!audio_done) { | 853 if (!audio_done) { |
| 822 return false; | 854 return false; |
| 823 } | 855 } |
| 824 | 856 |
| 825 const bool video_done = | 857 const bool video_done = |
| 826 !requested_video || | 858 !requested_video || |
| 827 request.state[request.options.video_type] == DeviceRequest::STATE_DONE || | 859 request.state[request.options.video_type] == |
| 828 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR; | 860 MediaStreamRequest::STATE_DONE || |
| 861 request.state[request.options.video_type] == | |
| 862 MediaStreamRequest::STATE_ERROR; | |
| 829 if (!video_done) { | 863 if (!video_done) { |
| 830 return false; | 864 return false; |
| 831 } | 865 } |
| 832 | 866 |
| 833 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 867 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
| 834 it != request.devices.end(); ++it) { | 868 it != request.devices.end(); ++it) { |
| 835 if (it->in_use == false) { | 869 if (it->in_use == false) { |
| 836 return false; | 870 return false; |
| 837 } | 871 } |
| 838 } | 872 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 902 it != requests_.end(); ++it) { | 936 it != requests_.end(); ++it) { |
| 903 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && | 937 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && |
| 904 Requested(it->second.options, stream_type)) { | 938 Requested(it->second.options, stream_type)) { |
| 905 return true; | 939 return true; |
| 906 } | 940 } |
| 907 } | 941 } |
| 908 return false; | 942 return false; |
| 909 } | 943 } |
| 910 | 944 |
| 911 } // namespace media_stream | 945 } // namespace media_stream |
| OLD | NEW |