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