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 "content/browser/renderer_host/media/audio_input_device_manager.h" | 13 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| 14 #include "content/browser/renderer_host/media/media_stream_device_settings.h" | 14 #include "content/browser/renderer_host/media/media_stream_device_settings.h" |
| 15 #include "content/browser/renderer_host/media/media_stream_requester.h" | 15 #include "content/browser/renderer_host/media/media_stream_requester.h" |
| 16 #include "content/browser/renderer_host/media/video_capture_manager.h" | 16 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 17 #include "content/common/media/media_stream_options.h" | 17 #include "content/common/media/media_stream_options.h" |
| 18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/browser/content_browser_client.h" | 19 #include "content/public/browser/content_browser_client.h" |
| 20 #include "content/public/browser/media_observer.h" | 20 #include "content/public/browser/media_observer.h" |
| 21 #include "googleurl/src/gurl.h" | 21 #include "googleurl/src/gurl.h" |
| 22 | 22 |
| 23 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
| 24 #include "base/win/scoped_com_initializer.h" | 24 #include "base/win/scoped_com_initializer.h" |
| 25 #endif | 25 #endif |
| 26 | 26 |
| 27 using content::BrowserThread; | 27 using content::BrowserThread; |
| 28 using content::MediaStreamRequest; | |
| 29 | |
| 30 namespace { | |
| 31 const char kExtensionScheme[] = "chrome-extension"; | |
| 32 } // namespace | |
| 28 | 33 |
| 29 namespace media_stream { | 34 namespace media_stream { |
| 30 | 35 |
| 31 // Creates a random label used to identify requests. | 36 // Creates a random label used to identify requests. |
| 32 static std::string RandomLabel() { | 37 static std::string RandomLabel() { |
| 33 // An earlier PeerConnection spec, | 38 // An earlier PeerConnection spec, |
| 34 // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the | 39 // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the |
| 35 // MediaStream::label alphabet as containing 36 characters from | 40 // MediaStream::label alphabet as containing 36 characters from |
| 36 // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, | 41 // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, |
| 37 // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. | 42 // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 66 com_initializer_.reset(new base::win::ScopedCOMInitializer( | 71 com_initializer_.reset(new base::win::ScopedCOMInitializer( |
| 67 base::win::ScopedCOMInitializer::kMTA)); | 72 base::win::ScopedCOMInitializer::kMTA)); |
| 68 } | 73 } |
| 69 | 74 |
| 70 void DeviceThread::CleanUp() { | 75 void DeviceThread::CleanUp() { |
| 71 com_initializer_.reset(); | 76 com_initializer_.reset(); |
| 72 } | 77 } |
| 73 #endif | 78 #endif |
| 74 | 79 |
| 75 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. | 80 // TODO(xians): Merge DeviceRequest with MediaStreamRequest. |
| 76 struct MediaStreamManager::DeviceRequest { | 81 class MediaStreamManager::DeviceRequest { |
| 77 enum RequestState { | 82 public: |
| 78 STATE_NOT_REQUESTED = 0, | |
| 79 STATE_REQUESTED, | |
| 80 STATE_PENDING_APPROVAL, | |
| 81 STATE_OPENING, | |
| 82 STATE_DONE, | |
| 83 STATE_ERROR | |
| 84 }; | |
| 85 | |
| 86 enum RequestType { | 83 enum RequestType { |
| 87 GENERATE_STREAM = 0, | 84 GENERATE_STREAM = 0, |
| 88 ENUMERATE_DEVICES, | 85 ENUMERATE_DEVICES, |
| 89 OPEN_DEVICE | 86 OPEN_DEVICE |
| 90 }; | 87 }; |
| 91 | 88 |
| 92 DeviceRequest() | 89 DeviceRequest() |
| 93 : requester(NULL), | 90 : requester(NULL), |
| 94 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), | |
| 95 type(GENERATE_STREAM), | 91 type(GENERATE_STREAM), |
| 96 render_process_id(-1), | 92 render_process_id(-1), |
| 97 render_view_id(-1) { | 93 render_view_id(-1), |
| 94 state_(content::NUM_MEDIA_TYPES, | |
| 95 MediaStreamRequest::STATE_NOT_REQUESTED) { | |
| 98 } | 96 } |
| 99 | 97 |
| 100 DeviceRequest(MediaStreamRequester* requester, | 98 DeviceRequest(MediaStreamRequester* requester, |
| 101 const StreamOptions& request_options, | 99 const StreamOptions& request_options, |
| 102 int render_process_id, | 100 int render_process_id, |
| 103 int render_view_id, | 101 int render_view_id, |
| 104 const GURL& request_security_origin) | 102 const GURL& request_security_origin) |
| 105 : requester(requester), | 103 : requester(requester), |
| 106 options(request_options), | 104 options(request_options), |
| 107 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), | |
| 108 type(GENERATE_STREAM), | 105 type(GENERATE_STREAM), |
| 109 render_process_id(render_process_id), | 106 render_process_id(render_process_id), |
| 110 render_view_id(render_view_id), | 107 render_view_id(render_view_id), |
| 111 security_origin(request_security_origin) { | 108 security_origin(request_security_origin), |
| 109 state_(content::NUM_MEDIA_TYPES, | |
| 110 MediaStreamRequest::STATE_NOT_REQUESTED) { | |
| 112 DCHECK(requester); | 111 DCHECK(requester); |
| 113 } | 112 } |
| 114 | 113 |
| 115 ~DeviceRequest() {} | 114 ~DeviceRequest() {} |
| 116 | 115 |
| 117 MediaStreamRequester* requester; | 116 MediaStreamRequester* requester; |
| 118 StreamOptions options; | 117 StreamOptions options; |
| 119 std::vector<RequestState> state; | |
| 120 RequestType type; | 118 RequestType type; |
| 121 int render_process_id; | 119 int render_process_id; |
| 122 int render_view_id; | 120 int render_view_id; |
| 123 GURL security_origin; | 121 GURL security_origin; |
| 124 std::string requested_device_id; | 122 std::string requested_device_id; |
| 125 StreamDeviceInfoArray devices; | 123 StreamDeviceInfoArray devices; |
| 124 | |
| 125 void setState(MediaStreamType stream_type, | |
| 126 MediaStreamRequest::RequestState new_state) { | |
| 127 state_[stream_type] = new_state; | |
| 128 } | |
| 129 | |
| 130 MediaStreamRequest::RequestState getState(MediaStreamType stream_type) const { | |
| 131 return state_[stream_type]; | |
| 132 } | |
| 133 | |
| 134 private: | |
| 135 std::vector<MediaStreamRequest::RequestState> state_; | |
| 126 }; | 136 }; |
| 127 | 137 |
| 138 // Helper to update the request state and notify observers. | |
| 139 static void UpdateRequestState( | |
|
miu
2012/10/12 01:10:50
Is there a reason this isn't just a method in Devi
justinlin
2012/10/12 03:02:31
Good question. Done.
| |
| 140 MediaStreamManager::DeviceRequest* request, | |
| 141 MediaStreamType stream_type, | |
| 142 const MediaStreamRequest::RequestState new_state) { | |
| 143 request->setState(stream_type, new_state); | |
| 144 | |
| 145 content::MediaObserver* media_observer = | |
| 146 content::GetContentClient()->browser()->GetMediaObserver(); | |
| 147 if (media_observer == NULL) | |
| 148 return; | |
| 149 if (request->options.video_type != content::MEDIA_TAB_VIDEO_CAPTURE && | |
|
wjia(left Chromium)
2012/10/11 22:13:27
could you merge these 2 if's?
justinlin
2012/10/12 00:50:22
Done.
| |
| 150 request->options.audio_type != content::MEDIA_TAB_AUDIO_CAPTURE) | |
| 151 return; | |
| 152 media_observer->OnMediaRequestStateChanged( | |
| 153 request->render_process_id, | |
| 154 request->render_view_id, | |
| 155 content::MediaStreamDevice(stream_type, | |
| 156 request->requested_device_id, | |
| 157 request->requested_device_id), | |
| 158 new_state); | |
| 159 } | |
| 160 | |
| 128 MediaStreamManager::EnumerationCache::EnumerationCache() | 161 MediaStreamManager::EnumerationCache::EnumerationCache() |
| 129 : valid(false) { | 162 : valid(false) { |
| 130 } | 163 } |
| 131 | 164 |
| 132 MediaStreamManager::EnumerationCache::~EnumerationCache() { | 165 MediaStreamManager::EnumerationCache::~EnumerationCache() { |
| 133 } | 166 } |
| 134 | 167 |
| 135 bool MediaStreamManager::always_use_fake_devices_ = false; | 168 bool MediaStreamManager::always_use_fake_devices_ = false; |
| 136 | 169 |
| 137 // static | 170 // static |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 const StreamOptions& options, const std::string& device_id, | 233 const StreamOptions& options, const std::string& device_id, |
| 201 const GURL& security_origin, std::string* label) { | 234 const GURL& security_origin, std::string* label) { |
| 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 203 | 236 |
| 204 // Create a new request based on options. | 237 // Create a new request based on options. |
| 205 AddRequest(DeviceRequest(requester, options, | 238 AddRequest(DeviceRequest(requester, options, |
| 206 render_process_id, render_view_id, | 239 render_process_id, render_view_id, |
| 207 security_origin), | 240 security_origin), |
| 208 label); | 241 label); |
| 209 DeviceRequest& request = requests_[*label]; | 242 DeviceRequest& request = requests_[*label]; |
| 243 request.requested_device_id = device_id; | |
| 210 | 244 |
| 211 // Get user confirmation to use the capture device. | 245 // Get user confirmation to use the capture device. |
| 212 device_settings_->RequestCaptureDeviceUsage(*label, | 246 device_settings_->RequestCaptureDeviceUsage(*label, |
| 213 render_process_id, | 247 render_process_id, |
| 214 render_view_id, | 248 render_view_id, |
| 215 options, | 249 options, |
| 216 security_origin); | 250 security_origin); |
| 251 | |
| 252 if (!security_origin.SchemeIs(kExtensionScheme)) { | |
| 253 CancelGenerateStream(*label); | |
|
justinlin
2012/10/12 00:50:22
Changed this to also PostTask for the same reason
| |
| 254 LOG(ERROR) << "Tried to use tab capture outside extension API."; | |
| 255 return; | |
| 256 } | |
| 257 | |
| 217 // TODO(miu): We should ask the device manager whether a device with id | 258 // TODO(miu): We should ask the device manager whether a device with id |
| 218 // |device_id| actually exists. Note that no such MediaStreamProvider API for | 259 // |device_id| actually exists. Note that no such MediaStreamProvider API for |
| 219 // this currently exists. Also, we don't have a user-friendly device name for | 260 // this currently exists. Also, we don't have a user-friendly device name for |
| 220 // the infobar UI. | 261 // the infobar UI. |
| 262 StreamDeviceInfoArray devices; | |
| 221 if (content::IsAudioMediaType(options.audio_type)) { | 263 if (content::IsAudioMediaType(options.audio_type)) { |
| 222 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL; | 264 // TODO(justinlin): Updating the state to requested and pending are no-ops |
| 223 device_settings_->AvailableDevices( | 265 // in terms of the media manager, but these are the state changes we want to |
| 224 *label, options.audio_type, StreamDeviceInfoArray( | 266 // support in terms of extensions (which is registered as an observer). |
| 225 1, StreamDeviceInfo(options.audio_type, device_id, device_id, | 267 UpdateRequestState(&request, options.audio_type, |
| 226 false))); | 268 MediaStreamRequest::STATE_REQUESTED); |
| 269 UpdateRequestState(&request, options.audio_type, | |
| 270 MediaStreamRequest::STATE_PENDING_APPROVAL); | |
| 271 devices.push_back( | |
| 272 StreamDeviceInfo(options.audio_type, device_id, device_id, false)); | |
| 227 } | 273 } |
| 228 if (content::IsVideoMediaType(options.video_type)) { | 274 if (content::IsVideoMediaType(options.video_type)) { |
| 229 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL; | 275 UpdateRequestState(&request, options.video_type, |
| 230 device_settings_->AvailableDevices( | 276 MediaStreamRequest::STATE_REQUESTED); |
| 231 *label, options.video_type, StreamDeviceInfoArray( | 277 UpdateRequestState(&request, options.video_type, |
| 232 1, StreamDeviceInfo(options.video_type, device_id, device_id, | 278 MediaStreamRequest::STATE_PENDING_APPROVAL); |
| 233 false))); | 279 devices.push_back( |
| 280 StreamDeviceInfo(options.video_type, device_id, device_id, false)); | |
| 234 } | 281 } |
| 282 | |
| 283 // Bypass the user authorization dropdown for tab capture. | |
| 284 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 285 base::Bind(&MediaStreamManager::DevicesAccepted, | |
| 286 base::Unretained(this), *label, devices)); | |
| 235 } | 287 } |
| 236 | 288 |
| 237 void MediaStreamManager::CancelGenerateStream(const std::string& label) { | 289 void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
| 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 239 | 291 |
| 240 DeviceRequests::iterator it = requests_.find(label); | 292 DeviceRequests::iterator it = requests_.find(label); |
| 241 if (it != requests_.end()) { | 293 if (it != requests_.end()) { |
| 242 // The request isn't complete. | 294 // The request isn't complete. |
| 243 if (!RequestDone(it->second)) { | 295 if (!RequestDone(it->second)) { |
| 244 DeviceRequest& request = it->second; | 296 DeviceRequest& request = it->second; |
| 245 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; | 297 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
| 246 ++i) { | 298 ++i) { |
| 247 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 299 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| 248 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) { | 300 if (request.getState(stream_type) != |
| 301 MediaStreamRequest::STATE_OPENING) { | |
| 249 continue; | 302 continue; |
| 250 } | 303 } |
| 251 for (StreamDeviceInfoArray::const_iterator device_it = | 304 for (StreamDeviceInfoArray::const_iterator device_it = |
| 252 request.devices.begin(); | 305 request.devices.begin(); |
| 253 device_it != request.devices.end(); ++device_it) { | 306 device_it != request.devices.end(); ++device_it) { |
| 254 if (device_it->stream_type == stream_type) { | 307 if (device_it->stream_type == stream_type) { |
| 255 GetDeviceManager(stream_type)->Close(device_it->session_id); | 308 GetDeviceManager(stream_type)->Close(device_it->session_id); |
| 256 } | 309 } |
| 257 } | 310 } |
| 258 } | 311 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 273 StopEnumerateDevices(label); | 326 StopEnumerateDevices(label); |
| 274 return; | 327 return; |
| 275 } | 328 } |
| 276 for (StreamDeviceInfoArray::const_iterator device_it = | 329 for (StreamDeviceInfoArray::const_iterator device_it = |
| 277 it->second.devices.begin(); | 330 it->second.devices.begin(); |
| 278 device_it != it->second.devices.end(); ++device_it) { | 331 device_it != it->second.devices.end(); ++device_it) { |
| 279 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id); | 332 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id); |
| 280 } | 333 } |
| 281 if (it->second.type == DeviceRequest::GENERATE_STREAM && | 334 if (it->second.type == DeviceRequest::GENERATE_STREAM && |
| 282 RequestDone(it->second)) { | 335 RequestDone(it->second)) { |
| 336 // Notify observers that this device is being closed. | |
| 337 for (MediaStreamType i = content::MEDIA_NO_SERVICE; | |
|
wjia(left Chromium)
2012/10/11 22:13:27
you probably want to start with content::MEDIA_NO_
justinlin
2012/10/12 00:50:22
Done.
| |
| 338 i != content::NUM_MEDIA_TYPES; ++i) { | |
| 339 if (it->second.getState(i) != MediaStreamRequest::STATE_NOT_REQUESTED) | |
| 340 UpdateRequestState(&it->second, i, MediaStreamRequest::STATE_CLOSING); | |
| 341 } | |
| 283 NotifyObserverDevicesClosed(&(it->second)); | 342 NotifyObserverDevicesClosed(&(it->second)); |
| 284 } | 343 } |
| 285 requests_.erase(it); | 344 requests_.erase(it); |
| 286 } | 345 } |
| 287 } | 346 } |
| 288 | 347 |
| 289 void MediaStreamManager::EnumerateDevices( | 348 void MediaStreamManager::EnumerateDevices( |
| 290 MediaStreamRequester* requester, | 349 MediaStreamRequester* requester, |
| 291 int render_process_id, | 350 int render_process_id, |
| 292 int render_view_id, | 351 int render_view_id, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 312 } | 371 } |
| 313 | 372 |
| 314 DeviceRequest new_request(requester, options, | 373 DeviceRequest new_request(requester, options, |
| 315 render_process_id, | 374 render_process_id, |
| 316 render_view_id, | 375 render_view_id, |
| 317 security_origin); | 376 security_origin); |
| 318 new_request.type = DeviceRequest::ENUMERATE_DEVICES; | 377 new_request.type = DeviceRequest::ENUMERATE_DEVICES; |
| 319 | 378 |
| 320 if (cache->valid) { | 379 if (cache->valid) { |
| 321 // Cached device list of this type exists. Just send it out. | 380 // Cached device list of this type exists. Just send it out. |
| 322 new_request.state[type] = DeviceRequest::STATE_REQUESTED; | 381 UpdateRequestState(&new_request, type, |
| 382 MediaStreamRequest::STATE_REQUESTED); | |
| 323 AddRequest(new_request, label); | 383 AddRequest(new_request, label); |
| 324 // Need to post a task since the requester won't have label till | 384 // Need to post a task since the requester won't have label till |
| 325 // this function returns. | 385 // this function returns. |
| 326 BrowserThread::PostTask(BrowserThread::IO, | 386 BrowserThread::PostTask(BrowserThread::IO, |
| 327 FROM_HERE, | 387 FROM_HERE, |
| 328 base::Bind(&MediaStreamManager::SendCachedDeviceList, | 388 base::Bind(&MediaStreamManager::SendCachedDeviceList, |
| 329 base::Unretained(this), cache, *label)); | 389 base::Unretained(this), cache, *label)); |
| 330 } else { | 390 } else { |
| 331 StartEnumeration(&new_request, label); | 391 StartEnumeration(&new_request, label); |
| 332 StartMonitoring(); | 392 StartMonitoring(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 | 476 |
| 417 void MediaStreamManager::StartEnumeration( | 477 void MediaStreamManager::StartEnumeration( |
| 418 DeviceRequest* new_request, | 478 DeviceRequest* new_request, |
| 419 std::string* label) { | 479 std::string* label) { |
| 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 421 | 481 |
| 422 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; | 482 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
| 423 ++i) { | 483 ++i) { |
| 424 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 484 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
| 425 if (Requested(new_request->options, stream_type)) { | 485 if (Requested(new_request->options, stream_type)) { |
| 426 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; | 486 UpdateRequestState(new_request, stream_type, |
| 487 MediaStreamRequest::STATE_REQUESTED); | |
| 427 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 488 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
| 428 if (active_enumeration_ref_count_[stream_type] == 0) { | 489 if (active_enumeration_ref_count_[stream_type] == 0) { |
| 429 ++active_enumeration_ref_count_[stream_type]; | 490 ++active_enumeration_ref_count_[stream_type]; |
| 430 GetDeviceManager(stream_type)->EnumerateDevices(); | 491 GetDeviceManager(stream_type)->EnumerateDevices(); |
| 431 } | 492 } |
| 432 } | 493 } |
| 433 } | 494 } |
| 434 | 495 |
| 435 AddRequest(*new_request, label); | 496 AddRequest(*new_request, label); |
| 436 } | 497 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 request = &(request_it->second); | 556 request = &(request_it->second); |
| 496 break; | 557 break; |
| 497 } | 558 } |
| 498 } | 559 } |
| 499 } | 560 } |
| 500 if (request == NULL) { | 561 if (request == NULL) { |
| 501 // The request doesn't exist. | 562 // The request doesn't exist. |
| 502 return; | 563 return; |
| 503 } | 564 } |
| 504 | 565 |
| 505 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); | 566 DCHECK_NE(request->getState(stream_type), |
| 567 MediaStreamRequest::STATE_REQUESTED); | |
| 506 | 568 |
| 507 // Check if all devices for this stream type are opened. Update the state if | 569 // Check if all devices for this stream type are opened. Update the state if |
| 508 // they are. | 570 // they are. |
| 509 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 571 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
| 510 device_it != devices->end(); ++device_it) { | 572 device_it != devices->end(); ++device_it) { |
| 511 if (device_it->stream_type != stream_type) { | 573 if (device_it->stream_type != stream_type) { |
| 512 continue; | 574 continue; |
| 513 } | 575 } |
| 514 if (device_it->in_use == false) { | 576 if (device_it->in_use == false) { |
| 515 // Wait for more devices to be opened before we're done. | 577 // Wait for more devices to be opened before we're done. |
| 516 return; | 578 return; |
| 517 } | 579 } |
| 518 } | 580 } |
| 519 request->state[stream_type] = DeviceRequest::STATE_DONE; | 581 |
| 582 UpdateRequestState(request, stream_type, MediaStreamRequest::STATE_DONE); | |
| 520 | 583 |
| 521 if (!RequestDone(*request)) { | 584 if (!RequestDone(*request)) { |
| 522 // This stream_type is done, but not the other type. | 585 // This stream_type is done, but not the other type. |
| 523 return; | 586 return; |
| 524 } | 587 } |
| 525 | 588 |
| 526 switch (request->type) { | 589 switch (request->type) { |
| 527 case DeviceRequest::OPEN_DEVICE: | 590 case DeviceRequest::OPEN_DEVICE: |
| 528 request->requester->DeviceOpened(label, devices->front()); | 591 request->requester->DeviceOpened(label, devices->front()); |
| 529 break; | 592 break; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 need_update_clients = true; | 639 need_update_clients = true; |
| 577 } | 640 } |
| 578 | 641 |
| 579 // Publish the result for all requests waiting for device list(s). | 642 // Publish the result for all requests waiting for device list(s). |
| 580 // Find the requests waiting for this device list, store their labels and | 643 // Find the requests waiting for this device list, store their labels and |
| 581 // release the iterator before calling device settings. We might get a call | 644 // release the iterator before calling device settings. We might get a call |
| 582 // back from device_settings that will need to iterate through devices. | 645 // back from device_settings that will need to iterate through devices. |
| 583 std::list<std::string> label_list; | 646 std::list<std::string> label_list; |
| 584 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 647 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
| 585 ++it) { | 648 ++it) { |
| 586 if (it->second.state[stream_type] == DeviceRequest::STATE_REQUESTED && | 649 if (it->second.getState(stream_type) == |
| 650 MediaStreamRequest::STATE_REQUESTED && | |
| 587 Requested(it->second.options, stream_type)) { | 651 Requested(it->second.options, stream_type)) { |
| 588 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) | 652 if (it->second.type != DeviceRequest::ENUMERATE_DEVICES) |
| 589 it->second.state[stream_type] = DeviceRequest::STATE_PENDING_APPROVAL; | 653 UpdateRequestState(&it->second, stream_type, |
| 654 MediaStreamRequest::STATE_PENDING_APPROVAL); | |
| 590 label_list.push_back(it->first); | 655 label_list.push_back(it->first); |
| 591 } | 656 } |
| 592 } | 657 } |
| 593 for (std::list<std::string>::iterator it = label_list.begin(); | 658 for (std::list<std::string>::iterator it = label_list.begin(); |
| 594 it != label_list.end(); ++it) { | 659 it != label_list.end(); ++it) { |
| 595 DeviceRequest& request = requests_[*it]; | 660 DeviceRequest& request = requests_[*it]; |
| 596 switch (request.type) { | 661 switch (request.type) { |
| 597 case DeviceRequest::ENUMERATE_DEVICES: | 662 case DeviceRequest::ENUMERATE_DEVICES: |
| 598 if (need_update_clients) | 663 if (need_update_clients) |
| 599 request.requester->DevicesEnumerated(*it, devices); | 664 request.requester->DevicesEnumerated(*it, devices); |
| 600 break; | 665 break; |
| 601 case DeviceRequest::OPEN_DEVICE: | 666 case DeviceRequest::OPEN_DEVICE: |
| 602 DCHECK(!request.requested_device_id.empty()); | 667 DCHECK(!request.requested_device_id.empty()); |
| 603 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 668 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
| 604 device_it != devices.end(); ++device_it) { | 669 device_it != devices.end(); ++device_it) { |
| 605 if (request.requested_device_id == device_it->device_id) { | 670 if (request.requested_device_id == device_it->device_id) { |
| 606 StreamDeviceInfo device = *device_it; | 671 StreamDeviceInfo device = *device_it; |
| 607 device.in_use = false; | 672 device.in_use = false; |
| 608 device.session_id = | 673 device.session_id = |
| 609 GetDeviceManager(device_it->stream_type)->Open(device); | 674 GetDeviceManager(device_it->stream_type)->Open(device); |
| 610 request.state[device_it->stream_type] = | 675 UpdateRequestState(&request, device_it->stream_type, |
| 611 DeviceRequest::STATE_OPENING; | 676 MediaStreamRequest::STATE_OPENING); |
| 612 request.devices.push_back(device); | 677 request.devices.push_back(device); |
| 613 break; | 678 break; |
| 614 } | 679 } |
| 615 } | 680 } |
| 616 break; | 681 break; |
| 617 default: | 682 default: |
| 618 device_settings_->AvailableDevices(*it, stream_type, devices); | 683 device_settings_->AvailableDevices(*it, stream_type, devices); |
| 619 break; | 684 break; |
| 620 } | 685 } |
| 621 } | 686 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 649 NOTREACHED(); | 714 NOTREACHED(); |
| 650 continue; | 715 continue; |
| 651 } | 716 } |
| 652 if (device_it->stream_type != stream_type || | 717 if (device_it->stream_type != stream_type || |
| 653 device_it->session_id != capture_session_id) { | 718 device_it->session_id != capture_session_id) { |
| 654 continue; | 719 continue; |
| 655 } | 720 } |
| 656 // We've found the failing device. Find the error case: | 721 // We've found the failing device. Find the error case: |
| 657 // An error should only be reported to the MediaStreamManager if | 722 // An error should only be reported to the MediaStreamManager if |
| 658 // the request has not been fulfilled yet. | 723 // the request has not been fulfilled yet. |
| 659 DCHECK(it->second.state[stream_type] != DeviceRequest::STATE_DONE); | 724 DCHECK(it->second.getState(stream_type) |
| 660 if (it->second.state[stream_type] != DeviceRequest::STATE_DONE) { | 725 != MediaStreamRequest::STATE_DONE); |
| 726 if (it->second.getState(stream_type) != MediaStreamRequest::STATE_DONE) { | |
| 661 // Request is not done, devices are not opened in this case. | 727 // Request is not done, devices are not opened in this case. |
| 662 if (devices.size() <= 1) { | 728 if (devices.size() <= 1) { |
| 663 // 1. Device not opened and no other devices for this request -> | 729 // 1. Device not opened and no other devices for this request -> |
| 664 // signal stream error and remove the request. | 730 // signal stream error and remove the request. |
| 665 it->second.requester->StreamGenerationFailed(it->first); | 731 it->second.requester->StreamGenerationFailed(it->first); |
| 666 requests_.erase(it); | 732 requests_.erase(it); |
| 667 } else { | 733 } else { |
| 668 // 2. Not opened but other devices exists for this request -> remove | 734 // 2. Not opened but other devices exists for this request -> remove |
| 669 // device from list, but don't signal an error. | 735 // device from list, but don't signal an error. |
| 670 devices.erase(device_it); // NOTE: This invalidates device_it! | 736 devices.erase(device_it); // NOTE: This invalidates device_it! |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 694 | 760 |
| 695 // Process all newly-accepted devices for this request. | 761 // Process all newly-accepted devices for this request. |
| 696 bool found_audio = false, found_video = false; | 762 bool found_audio = false, found_video = false; |
| 697 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 763 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
| 698 device_it != devices.end(); ++device_it) { | 764 device_it != devices.end(); ++device_it) { |
| 699 StreamDeviceInfo device_info = *device_it; // Make a copy. | 765 StreamDeviceInfo device_info = *device_it; // Make a copy. |
| 700 | 766 |
| 701 // Set in_use to false to be able to track if this device has been | 767 // Set in_use to false to be able to track if this device has been |
| 702 // opened. in_use might be true if the device type can be used in more | 768 // opened. in_use might be true if the device type can be used in more |
| 703 // than one session. | 769 // than one session. |
| 704 DCHECK_EQ(request.state[device_it->stream_type], | 770 DCHECK_EQ(request.getState(device_it->stream_type), |
| 705 DeviceRequest::STATE_PENDING_APPROVAL); | 771 MediaStreamRequest::STATE_PENDING_APPROVAL); |
| 706 device_info.in_use = false; | 772 device_info.in_use = false; |
| 773 | |
| 707 device_info.session_id = | 774 device_info.session_id = |
| 708 GetDeviceManager(device_info.stream_type)->Open(device_info); | 775 GetDeviceManager(device_info.stream_type)->Open(device_info); |
| 709 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING; | 776 UpdateRequestState(&request, device_it->stream_type, |
| 777 MediaStreamRequest::STATE_OPENING); | |
| 710 request.devices.push_back(device_info); | 778 request.devices.push_back(device_info); |
| 711 | 779 |
| 712 if (device_info.stream_type == request.options.audio_type) { | 780 if (device_info.stream_type == request.options.audio_type) { |
| 713 found_audio = true; | 781 found_audio = true; |
| 714 } else if (device_info.stream_type == request.options.video_type) { | 782 } else if (device_info.stream_type == request.options.video_type) { |
| 715 found_video = true; | 783 found_video = true; |
| 716 } | 784 } |
| 717 } | 785 } |
| 718 | 786 |
| 719 // Check whether we've received all stream types requested. | 787 // Check whether we've received all stream types requested. |
| 720 if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) { | 788 if (!found_audio && content::IsAudioMediaType(request.options.audio_type)) { |
| 721 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR; | 789 UpdateRequestState(&request, request.options.audio_type, |
| 790 MediaStreamRequest::STATE_ERROR); | |
| 722 } | 791 } |
| 723 if (!found_video && content::IsVideoMediaType(request.options.video_type)) { | 792 if (!found_video && content::IsVideoMediaType(request.options.video_type)) { |
| 724 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR; | 793 UpdateRequestState(&request, request.options.video_type, |
| 794 MediaStreamRequest::STATE_ERROR); | |
| 725 } | 795 } |
| 726 } | 796 } |
| 727 | 797 |
| 728 void MediaStreamManager::SettingsError(const std::string& label) { | 798 void MediaStreamManager::SettingsError(const std::string& label) { |
| 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 799 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 730 // Erase this request and report an error. | 800 // Erase this request and report an error. |
| 731 DeviceRequests::iterator it = requests_.find(label); | 801 DeviceRequests::iterator it = requests_.find(label); |
| 732 if (it != requests_.end()) { | 802 if (it != requests_.end()) { |
| 733 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); | 803 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); |
| 734 it->second.requester->StreamGenerationFailed(label); | 804 it->second.requester->StreamGenerationFailed(label); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 798 | 868 |
| 799 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 869 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
| 800 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 870 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 801 | 871 |
| 802 const bool requested_audio = | 872 const bool requested_audio = |
| 803 content::IsAudioMediaType(request.options.audio_type); | 873 content::IsAudioMediaType(request.options.audio_type); |
| 804 const bool requested_video = | 874 const bool requested_video = |
| 805 content::IsVideoMediaType(request.options.video_type); | 875 content::IsVideoMediaType(request.options.video_type); |
| 806 | 876 |
| 807 const bool audio_done = | 877 const bool audio_done = |
| 808 !requested_audio || | 878 !requested_audio || request.getState(request.options.audio_type) == |
|
miu
2012/10/12 01:10:50
This is a little confusing to read. Can you use m
justinlin
2012/10/12 03:02:31
Done.
| |
| 809 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE || | 879 MediaStreamRequest::STATE_DONE || |
| 810 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR; | 880 request.getState(request.options.audio_type) == |
| 881 MediaStreamRequest::STATE_ERROR; | |
| 811 if (!audio_done) { | 882 if (!audio_done) { |
| 812 return false; | 883 return false; |
| 813 } | 884 } |
| 814 | 885 |
| 815 const bool video_done = | 886 const bool video_done = |
| 816 !requested_video || | 887 !requested_video || request.getState(request.options.video_type) == |
|
miu
2012/10/12 01:10:50
Ditto on readability.
justinlin
2012/10/12 03:02:31
Done.
| |
| 817 request.state[request.options.video_type] == DeviceRequest::STATE_DONE || | 888 MediaStreamRequest::STATE_DONE || |
| 818 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR; | 889 request.getState(request.options.video_type) == |
| 890 MediaStreamRequest::STATE_ERROR; | |
| 819 if (!video_done) { | 891 if (!video_done) { |
| 820 return false; | 892 return false; |
| 821 } | 893 } |
| 822 | 894 |
| 823 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | 895 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); |
| 824 it != request.devices.end(); ++it) { | 896 it != request.devices.end(); ++it) { |
| 825 if (it->in_use == false) { | 897 if (it->in_use == false) { |
| 826 return false; | 898 return false; |
| 827 } | 899 } |
| 828 } | 900 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 892 it != requests_.end(); ++it) { | 964 it != requests_.end(); ++it) { |
| 893 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && | 965 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && |
| 894 Requested(it->second.options, stream_type)) { | 966 Requested(it->second.options, stream_type)) { |
| 895 return true; | 967 return true; |
| 896 } | 968 } |
| 897 } | 969 } |
| 898 return false; | 970 return false; |
| 899 } | 971 } |
| 900 | 972 |
| 901 } // namespace media_stream | 973 } // namespace media_stream |
| OLD | NEW |