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