Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/media/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
| 15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 16 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 16 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| 17 #include "content/browser/renderer_host/media/device_request_message_filter.h" | 17 #include "content/browser/renderer_host/media/device_request_message_filter.h" |
| 18 #include "content/browser/renderer_host/media/media_source_id_factory.h" | |
| 18 #include "content/browser/renderer_host/media/media_stream_requester.h" | 19 #include "content/browser/renderer_host/media/media_stream_requester.h" |
| 19 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" | 20 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
| 20 #include "content/browser/renderer_host/media/video_capture_manager.h" | 21 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 21 #include "content/browser/renderer_host/media/web_contents_capture_util.h" | 22 #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
| 22 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 23 #include "content/public/browser/content_browser_client.h" | 24 #include "content/public/browser/content_browser_client.h" |
| 24 #include "content/public/browser/media_observer.h" | 25 #include "content/public/browser/media_observer.h" |
| 25 #include "content/public/browser/media_request_state.h" | 26 #include "content/public/browser/media_request_state.h" |
| 26 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
| 27 #include "content/public/common/media_stream_request.h" | 28 #include "content/public/common/media_stream_request.h" |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 191 // Create a new request based on options. | 192 // Create a new request based on options. |
| 192 MediaStreamRequest stream_request( | 193 MediaStreamRequest stream_request( |
| 193 render_process_id, render_view_id, page_request_id, std::string(), | 194 render_process_id, render_view_id, page_request_id, std::string(), |
| 194 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), | 195 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), |
| 195 options.audio_type, options.video_type); | 196 options.audio_type, options.video_type); |
| 196 DeviceRequest* request = new DeviceRequest(NULL, stream_request); | 197 DeviceRequest* request = new DeviceRequest(NULL, stream_request); |
| 197 const std::string& label = AddRequest(request); | 198 const std::string& label = AddRequest(request); |
| 198 | 199 |
| 199 request->callback = callback; | 200 request->callback = callback; |
| 200 | 201 BrowserThread::PostTask( |
| 201 HandleRequest(label); | 202 BrowserThread::IO, FROM_HERE, |
| 202 | 203 base::Bind(&MediaStreamManager::HandleRequest, |
|
no longer working on chromium
2013/10/25 08:16:39
I don't fully understand this change, how can't we
perkj_chrome
2013/10/25 13:33:50
Yes. the label is used in error reporting.
In orde
| |
| 204 base::Unretained(this), label)); | |
| 203 return label; | 205 return label; |
| 204 } | 206 } |
| 205 | 207 |
| 206 std::string MediaStreamManager::GenerateStream( | 208 std::string MediaStreamManager::GenerateStream( |
|
no longer working on chromium
2013/10/25 12:00:07
make remove the code in the dispatcher which handl
perkj_chrome
2013/10/25 13:33:50
Done.
| |
| 207 MediaStreamRequester* requester, | 209 MediaStreamRequester* requester, |
| 208 int render_process_id, | 210 int render_process_id, |
| 209 int render_view_id, | 211 int render_view_id, |
| 210 int page_request_id, | 212 int page_request_id, |
| 211 const StreamOptions& options, | 213 const StreamOptions& options, |
| 212 const GURL& security_origin) { | 214 const GURL& security_origin) { |
| 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 214 if (CommandLine::ForCurrentProcess()->HasSwitch( | 216 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 215 switches::kUseFakeDeviceForMediaStream)) { | 217 switches::kUseFakeDeviceForMediaStream)) { |
| 216 UseFakeDevice(); | 218 UseFakeDevice(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 241 if (!has_valid_device_id || | 243 if (!has_valid_device_id || |
| 242 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && | 244 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE && |
| 243 options.audio_type != MEDIA_NO_SERVICE) || | 245 options.audio_type != MEDIA_NO_SERVICE) || |
| 244 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && | 246 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE && |
| 245 options.video_type != MEDIA_NO_SERVICE)) { | 247 options.video_type != MEDIA_NO_SERVICE)) { |
| 246 LOG(ERROR) << "Invalid request."; | 248 LOG(ERROR) << "Invalid request."; |
| 247 return std::string(); | 249 return std::string(); |
| 248 } | 250 } |
| 249 } | 251 } |
| 250 | 252 |
| 251 std::string translated_audio_device_id; | |
| 252 std::string translated_video_device_id; | |
| 253 if (options.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) { | |
| 254 bool found_match = TranslateGUIDToRawId( | |
| 255 MEDIA_DEVICE_AUDIO_CAPTURE, security_origin, options.audio_device_id, | |
| 256 &translated_audio_device_id); | |
| 257 DCHECK(found_match || translated_audio_device_id.empty()); | |
| 258 } | |
| 259 | |
| 260 if (options.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) { | |
| 261 bool found_match = TranslateGUIDToRawId( | |
| 262 MEDIA_DEVICE_VIDEO_CAPTURE, security_origin, options.video_device_id, | |
| 263 &translated_video_device_id); | |
| 264 DCHECK(found_match || translated_video_device_id.empty()); | |
| 265 } | |
| 266 | |
| 267 if (options.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE || | 253 if (options.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE || |
| 268 options.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE) { | 254 options.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE) { |
| 269 // For screen capture we only support two valid combinations: | 255 // For screen capture we only support two valid combinations: |
| 270 // (1) screen video capture only, or | 256 // (1) screen video capture only, or |
| 271 // (2) screen video capture with loopback audio capture. | 257 // (2) screen video capture with loopback audio capture. |
| 272 if (options.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE || | 258 if (options.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE || |
| 273 (options.audio_type != MEDIA_NO_SERVICE && | 259 (options.audio_type != MEDIA_NO_SERVICE && |
| 274 options.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) { | 260 options.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) { |
| 275 // TODO(sergeyu): Surface error message to the calling JS code. | 261 // TODO(sergeyu): Surface error message to the calling JS code. |
| 276 LOG(ERROR) << "Invalid screen capture request."; | 262 LOG(ERROR) << "Invalid screen capture request."; |
| 277 return std::string(); | 263 return std::string(); |
| 278 } | 264 } |
| 279 translated_video_device_id = options.video_device_id; | |
| 280 } | 265 } |
| 281 | 266 |
| 282 // Create a new request based on options. | 267 // Create a new request based on options. |
| 283 MediaStreamRequest stream_request( | 268 MediaStreamRequest stream_request( |
| 284 target_render_process_id, target_render_view_id, page_request_id, | 269 target_render_process_id, target_render_view_id, page_request_id, |
| 285 tab_capture_device_id, security_origin, MEDIA_GENERATE_STREAM, | 270 tab_capture_device_id, security_origin, MEDIA_GENERATE_STREAM, |
| 286 translated_audio_device_id, translated_video_device_id, | 271 options.audio_device_id, options.video_device_id, |
| 287 options.audio_type, options.video_type); | 272 options.audio_type, options.video_type); |
| 288 DeviceRequest* request = new DeviceRequest(requester, stream_request); | 273 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
| 289 const std::string& label = AddRequest(request); | 274 const std::string& label = AddRequest(request); |
| 290 HandleRequest(label); | 275 |
| 276 // Need to post a task since the requester won't have label till | |
| 277 // this function returns. | |
| 278 BrowserThread::PostTask( | |
| 279 BrowserThread::IO, FROM_HERE, | |
| 280 base::Bind(&MediaStreamManager::HandleRequest, | |
| 281 base::Unretained(this), label)); | |
| 291 return label; | 282 return label; |
| 292 } | 283 } |
| 293 | 284 |
| 294 void MediaStreamManager::CancelRequest(const std::string& label) { | 285 void MediaStreamManager::CancelRequest(const std::string& label) { |
| 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 296 | 287 |
| 288 BrowserThread::PostTask( | |
| 289 BrowserThread::IO, FROM_HERE, | |
| 290 base::Bind(&MediaStreamManager::DoCancelRequest, | |
| 291 base::Unretained(this), label)); | |
| 292 } | |
| 293 | |
| 294 void MediaStreamManager::DoCancelRequest(const std::string& label) { | |
| 297 DeviceRequests::iterator request_it = requests_.find(label); | 295 DeviceRequests::iterator request_it = requests_.find(label); |
| 298 if (request_it == requests_.end()) { | 296 if (request_it == requests_.end()) { |
| 299 NOTREACHED(); | 297 NOTREACHED(); |
| 300 return; | 298 return; |
| 301 } | 299 } |
| 302 scoped_ptr<DeviceRequest> request(request_it->second); | |
| 303 RemoveRequest(request_it); | |
| 304 | 300 |
| 301 DeviceRequest* request(request_it->second); | |
| 305 if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) { | 302 if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) { |
| 303 DeleteRequest(request_it); | |
| 306 return; | 304 return; |
| 307 } | 305 } |
| 308 | 306 |
| 309 // This is a request for opening one or more devices. | 307 // This is a request for opening one or more devices. |
| 310 for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); | 308 for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); |
| 311 device_it != request->devices.end(); ++device_it) { | 309 device_it != request->devices.end(); ++device_it) { |
| 312 // If we have not yet requested the device to be opened - just ignore it. | 310 // If we have not yet requested the device to be opened - just ignore it. |
| 313 if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING | 311 if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING |
| 314 && | 312 && |
| 315 request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) { | 313 request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) { |
| 316 continue; | 314 continue; |
| 317 } | 315 } |
| 318 // Stop the opening/opened devices of the requests. | 316 // Stop the opening/opened devices of the requests. |
| 319 StopDevice(*device_it); | 317 StopDevice(*device_it); |
| 320 } | 318 } |
| 321 | 319 |
| 322 // Cancel the request if still pending at UI side. | 320 // Cancel the request if still pending at UI side. |
| 323 request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING); | 321 request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING); |
| 322 DeleteRequest(request_it); | |
| 324 } | 323 } |
| 325 | 324 |
| 326 void MediaStreamManager::CancelAllRequests(int render_process_id) { | 325 void MediaStreamManager::CancelAllRequests(int render_process_id) { |
| 327 DeviceRequests::iterator request_it = requests_.begin(); | 326 DeviceRequests::iterator request_it = requests_.begin(); |
| 328 while (request_it != requests_.end()) { | 327 while (request_it != requests_.end()) { |
| 329 if (request_it->second->request.render_process_id != render_process_id) { | 328 if (request_it->second->request.render_process_id != render_process_id) { |
| 330 ++request_it; | 329 ++request_it; |
| 331 continue; | 330 continue; |
| 332 } | 331 } |
| 333 | 332 |
| 334 std::string label = request_it->first; | 333 std::string label = request_it->first; |
| 335 ++request_it; | 334 ++request_it; |
| 336 CancelRequest(label); | 335 BrowserThread::PostTask( |
| 336 BrowserThread::IO, FROM_HERE, | |
| 337 base::Bind(&MediaStreamManager::DoCancelRequest, | |
|
no longer working on chromium
2013/10/25 08:16:39
same question here too.
perkj_chrome
2013/10/25 13:33:50
Same answer- we need to post always or never.
| |
| 338 base::Unretained(this), label)); | |
| 337 } | 339 } |
| 338 } | 340 } |
| 339 | 341 |
| 340 void MediaStreamManager::StopStreamDevice(int render_process_id, | 342 void MediaStreamManager::StopStreamDevice(int render_process_id, |
| 341 int render_view_id, | 343 int render_view_id, |
| 342 const std::string& device_id) { | 344 const std::string& device_id) { |
| 343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 344 DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} " | 346 DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} " |
| 345 << ", {device_id = " << device_id << "})"; | 347 << ", {device_id = " << device_id << "})"; |
| 348 BrowserThread::PostTask( | |
| 349 BrowserThread::IO, FROM_HERE, | |
| 350 base::Bind(&MediaStreamManager::DoStopStreamDevice, | |
| 351 base::Unretained(this), render_process_id, render_view_id, | |
| 352 device_id)); | |
| 353 } | |
| 346 | 354 |
| 355 void MediaStreamManager::DoStopStreamDevice(int render_process_id, | |
| 356 int render_view_id, | |
| 357 const std::string& device_id) { | |
| 347 // Find all requests for this |render_process_id| and |render_view_id| of type | 358 // Find all requests for this |render_process_id| and |render_view_id| of type |
| 348 // MEDIA_GENERATE_STREAM that has requested to use |device_id|. | 359 // MEDIA_GENERATE_STREAM that has requested to use |device_id|. |
| 349 DeviceRequests::iterator request_it = requests_.begin(); | 360 DeviceRequests::iterator request_it = requests_.begin(); |
| 350 while (request_it != requests_.end()) { | 361 while (request_it != requests_.end()) { |
| 351 const MediaStreamRequest& ms_request = request_it->second->request; | 362 const MediaStreamRequest& ms_request = request_it->second->request; |
| 352 if (ms_request.render_process_id != render_process_id || | 363 if (ms_request.render_process_id != render_process_id || |
| 353 ms_request.render_view_id != render_view_id || | 364 ms_request.render_view_id != render_view_id || |
| 354 ms_request.request_type != MEDIA_GENERATE_STREAM) { | 365 ms_request.request_type != MEDIA_GENERATE_STREAM) { |
| 355 ++request_it; | 366 ++request_it; |
| 356 continue; | 367 continue; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 368 device_it = devices->erase(device_it); | 379 device_it = devices->erase(device_it); |
| 369 } else { | 380 } else { |
| 370 ++device_it; | 381 ++device_it; |
| 371 } | 382 } |
| 372 } | 383 } |
| 373 | 384 |
| 374 // If this request doesn't have any active devices, remove the request. | 385 // If this request doesn't have any active devices, remove the request. |
| 375 if (devices->empty()) { | 386 if (devices->empty()) { |
| 376 DeviceRequests::iterator del_itor(request_it); | 387 DeviceRequests::iterator del_itor(request_it); |
| 377 ++request_it; | 388 ++request_it; |
| 378 scoped_ptr<DeviceRequest> request(del_itor->second); | 389 DeleteRequest(del_itor); |
| 379 RemoveRequest(del_itor); | |
| 380 } else { | 390 } else { |
| 381 ++request_it; | 391 ++request_it; |
| 382 } | 392 } |
| 383 } | 393 } |
| 384 } | 394 } |
| 385 | 395 |
| 386 void MediaStreamManager::StopDevice(const StreamDeviceInfo& device_info) { | 396 void MediaStreamManager::StopDevice(const StreamDeviceInfo& device_info) { |
| 387 DVLOG(1) << "StopDevice(" | 397 DVLOG(1) << "StopDevice(" |
| 388 << "{device_info.session_id = " << device_info.session_id << "} " | 398 << "{device_info.session_id = " << device_info.session_id << "} " |
| 389 << "{device_id = " << device_info.device.id << "})"; | 399 << "{device_id = " << device_info.device.id << "})"; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 420 // starts monitoring devices. | 430 // starts monitoring devices. |
| 421 if (!requester) { | 431 if (!requester) { |
| 422 if (!monitoring_started_) | 432 if (!monitoring_started_) |
| 423 StartMonitoring(); | 433 StartMonitoring(); |
| 424 | 434 |
| 425 return std::string(); | 435 return std::string(); |
| 426 } | 436 } |
| 427 | 437 |
| 428 // Create a new request. | 438 // Create a new request. |
| 429 StreamOptions options; | 439 StreamOptions options; |
| 430 EnumerationCache* cache = NULL; | |
| 431 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { | 440 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { |
| 432 options.audio_type = type; | 441 options.audio_type = type; |
| 433 cache = &audio_enumeration_cache_; | |
| 434 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 442 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
| 435 options.video_type = type; | 443 options.video_type = type; |
| 436 cache = &video_enumeration_cache_; | |
| 437 } else { | 444 } else { |
| 438 NOTREACHED(); | 445 NOTREACHED(); |
| 439 return std::string(); | 446 return std::string(); |
| 440 } | 447 } |
| 441 | 448 |
| 442 MediaStreamRequest stream_request( | 449 MediaStreamRequest stream_request( |
| 443 render_process_id, render_view_id, page_request_id, std::string(), | 450 render_process_id, render_view_id, page_request_id, std::string(), |
| 444 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), | 451 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), |
| 445 options.audio_type, options.video_type); | 452 options.audio_type, options.video_type); |
| 446 DeviceRequest* request = new DeviceRequest(requester, stream_request); | 453 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
| 447 const std::string& label = AddRequest(request); | 454 const std::string& label = AddRequest(request); |
| 455 BrowserThread::PostTask( | |
| 456 BrowserThread::IO, FROM_HERE, | |
| 457 base::Bind(&MediaStreamManager::DoEnumerateDevices, | |
| 458 base::Unretained(this), label)); | |
| 459 | |
| 460 return label; | |
| 461 } | |
| 462 | |
| 463 void MediaStreamManager::DoEnumerateDevices(const std::string& label) { | |
| 464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 465 DeviceRequest* request = requests_[label]; | |
| 466 | |
| 467 const MediaStreamType type = | |
| 468 request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | |
| 469 MEDIA_DEVICE_AUDIO_CAPTURE : MEDIA_DEVICE_VIDEO_CAPTURE; | |
| 470 | |
| 471 EnumerationCache* cache = | |
| 472 request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | |
| 473 &audio_enumeration_cache_ : &video_enumeration_cache_; | |
| 448 | 474 |
| 449 if (cache->valid) { | 475 if (cache->valid) { |
| 450 // Cached device list of this type exists. Just send it out. | 476 // Cached device list of this type exists. Just send it out. |
| 451 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); | 477 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); |
| 452 | 478 request->devices = cache->devices; |
| 453 // Need to post a task since the requester won't have label till | 479 FinalizeEnumerateDevices(label, request); |
| 454 // this function returns. | |
| 455 BrowserThread::PostTask( | |
| 456 BrowserThread::IO, FROM_HERE, | |
| 457 base::Bind(&MediaStreamManager::SendCachedDeviceList, | |
| 458 base::Unretained(this), cache, label)); | |
| 459 } else { | 480 } else { |
| 460 StartEnumeration(request); | 481 StartEnumeration(request); |
| 461 } | 482 } |
| 462 | |
| 463 return label; | |
| 464 } | 483 } |
| 465 | 484 |
| 466 std::string MediaStreamManager::OpenDevice( | 485 std::string MediaStreamManager::OpenDevice( |
| 467 MediaStreamRequester* requester, | 486 MediaStreamRequester* requester, |
| 468 int render_process_id, | 487 int render_process_id, |
| 469 int render_view_id, | 488 int render_view_id, |
| 470 int page_request_id, | 489 int page_request_id, |
| 471 const std::string& device_id, | 490 const std::string& device_id, |
| 472 MediaStreamType type, | 491 MediaStreamType type, |
| 473 const GURL& security_origin) { | 492 const GURL& security_origin) { |
| 474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 475 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 494 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 476 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 495 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| 477 | 496 |
| 478 // Create a new request. | 497 // Create a new request. |
| 479 StreamOptions options; | 498 StreamOptions options; |
| 480 if (IsAudioMediaType(type)) { | 499 if (IsAudioMediaType(type)) { |
| 481 options.audio_type = type; | 500 options.audio_type = type; |
| 482 options.audio_device_id = device_id; | 501 options.audio_device_id = device_id; |
| 483 } else if (IsVideoMediaType(type)) { | 502 } else if (IsVideoMediaType(type)) { |
| 484 options.video_type = type; | 503 options.video_type = type; |
| 485 options.video_device_id = device_id; | 504 options.video_device_id = device_id; |
| 486 } else { | 505 } else { |
| 487 NOTREACHED(); | 506 NOTREACHED(); |
| 488 return std::string(); | 507 return std::string(); |
| 489 } | 508 } |
| 490 | 509 |
| 491 MediaStreamRequest stream_request( | 510 MediaStreamRequest stream_request( |
| 492 render_process_id, render_view_id, page_request_id, std::string(), | 511 render_process_id, render_view_id, page_request_id, std::string(), |
| 493 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, | 512 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, |
| 494 options.video_device_id, options.audio_type, options.video_type); | 513 options.video_device_id, options.audio_type, options.video_type); |
| 495 DeviceRequest* request = new DeviceRequest(requester, stream_request); | 514 DeviceRequest* request = new DeviceRequest(requester, stream_request); |
| 496 const std::string& label = AddRequest(request); | 515 const std::string& label = AddRequest(request); |
| 497 StartEnumeration(request); | 516 BrowserThread::PostTask( |
| 517 BrowserThread::IO, FROM_HERE, | |
| 518 base::Bind(&MediaStreamManager::HandleRequest, | |
| 519 base::Unretained(this), label)); | |
| 498 | 520 |
| 499 return label; | 521 return label; |
| 500 } | 522 } |
| 501 | 523 |
| 502 void MediaStreamManager::SendCachedDeviceList( | |
| 503 EnumerationCache* cache, | |
| 504 const std::string& label) { | |
| 505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 506 if (cache->valid) { | |
| 507 DeviceRequests::iterator it = requests_.find(label); | |
| 508 if (it != requests_.end()) { | |
| 509 it->second->requester->DevicesEnumerated(label, cache->devices); | |
| 510 } | |
| 511 } | |
| 512 } | |
| 513 | |
| 514 void MediaStreamManager::StartMonitoring() { | 524 void MediaStreamManager::StartMonitoring() { |
| 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 516 if (!base::SystemMonitor::Get()) | 526 if (!base::SystemMonitor::Get()) |
| 517 return; | 527 return; |
| 518 | 528 |
| 519 if (!monitoring_started_) { | 529 if (!monitoring_started_) { |
| 520 monitoring_started_ = true; | 530 monitoring_started_ = true; |
| 521 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); | 531 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); |
| 522 | 532 |
| 523 // Enumerate both the audio and video devices to cache the device lists | 533 // Enumerate both the audio and video devices to cache the device lists |
| 524 // and send them to media observer. | 534 // and send them to media observer. |
| 525 ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE]; | 535 ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE]; |
| 526 audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE); | 536 audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE); |
| 527 ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE]; | 537 ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE]; |
| 528 video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE); | 538 video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE); |
| 529 } | 539 } |
| 530 } | 540 } |
| 531 | 541 |
| 532 void MediaStreamManager::StopMonitoring() { | 542 void MediaStreamManager::StopMonitoring() { |
| 533 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 543 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
| 534 if (monitoring_started_) { | 544 if (monitoring_started_) { |
| 535 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); | 545 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); |
| 536 monitoring_started_ = false; | 546 monitoring_started_ = false; |
| 537 ClearEnumerationCache(&audio_enumeration_cache_); | 547 ClearEnumerationCache(&audio_enumeration_cache_); |
| 538 ClearEnumerationCache(&video_enumeration_cache_); | 548 ClearEnumerationCache(&video_enumeration_cache_); |
| 539 } | 549 } |
| 540 } | 550 } |
| 541 | 551 |
| 542 bool MediaStreamManager::TranslateGUIDToRawId(MediaStreamType stream_type, | 552 bool MediaStreamManager::TransLateRequestedSourceIdToDeviceId( |
| 543 const GURL& security_origin, | 553 MediaStreamRequest* request) { |
| 544 const std::string& device_guid, | 554 // If a specific device has been requested we need to find the real device id. |
| 545 std::string* raw_device_id) { | 555 if (request->audio_type == MEDIA_DEVICE_AUDIO_CAPTURE && |
| 556 !request->requested_audio_device_id.empty()) { | |
| 557 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_AUDIO_CAPTURE, | |
| 558 request->security_origin, | |
| 559 request->requested_audio_device_id, | |
| 560 &request->requested_audio_device_id)) { | |
| 561 // TODO(perkj): guM should support mandatory and optional constraints. | |
|
no longer working on chromium
2013/10/25 12:00:07
nit, gUM
perkj_chrome
2013/10/25 13:33:50
Done.
| |
| 562 // Ie - if the sourceId is optional but it does not match - guM should | |
| 563 // not fail. For now we treat sourceId as a mandatory constraint. | |
| 564 return false; | |
| 565 } | |
| 566 } | |
| 567 | |
| 568 if (request->video_type == MEDIA_DEVICE_VIDEO_CAPTURE && | |
| 569 !request->requested_video_device_id.empty()) { | |
| 570 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_VIDEO_CAPTURE, | |
| 571 request->security_origin, | |
| 572 request->requested_video_device_id, | |
| 573 &request->requested_video_device_id)) { | |
| 574 // TODO(perkj): guM should support mandatory and optional constraints. | |
| 575 // Ie - if the sourceId is optional but it does not match - guM should | |
| 576 // not fail. For now we treat sourceId as a mandatory constraint. | |
| 577 return false; | |
| 578 } | |
| 579 } | |
| 580 DVLOG(1) << "Requested audio device " << request->requested_audio_device_id; | |
| 581 DVLOG(1) << "Requested video device " << request->requested_video_device_id; | |
| 582 return true; | |
| 583 } | |
| 584 | |
| 585 | |
| 586 bool MediaStreamManager::TranslateSourceIdToDeviceId( | |
| 587 MediaStreamType stream_type, | |
| 588 const GURL& security_origin, | |
| 589 const std::string& source_id, | |
| 590 std::string* device_id) { | |
| 546 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 591 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 547 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 592 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| 548 if (device_guid.empty()) | 593 if (source_id.empty()) |
| 549 return false; | 594 return false; |
| 550 | 595 |
| 551 EnumerationCache* cache = | 596 EnumerationCache* cache = |
| 552 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 597 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
| 553 &audio_enumeration_cache_ : &video_enumeration_cache_; | 598 &audio_enumeration_cache_ : &video_enumeration_cache_; |
| 554 | 599 |
| 555 // If device monitoring hasn't started, the |device_guid| is not valid. | 600 // If device monitoring hasn't started, the |device_guid| is not valid. |
| 556 if (!cache->valid) | 601 if (!cache->valid) |
| 557 return false; | 602 return false; |
| 558 | 603 |
| 559 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); | 604 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); |
| 560 it != cache->devices.end(); | 605 it != cache->devices.end(); |
| 561 ++it) { | 606 ++it) { |
| 562 if (DeviceRequestMessageFilter::DoesRawIdMatchGuid( | 607 if (MediaSourceIdFactory::DoesSourceIdMatchDeviceId( |
| 563 security_origin, device_guid, it->device.id)) { | 608 security_origin, source_id, it->device.id)) { |
| 564 *raw_device_id = it->device.id; | 609 *device_id = it->device.id; |
| 565 return true; | 610 return true; |
| 566 } | 611 } |
| 567 } | 612 } |
| 568 return false; | 613 return false; |
| 569 } | 614 } |
| 570 | 615 |
| 571 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 616 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
| 572 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 617 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
| 573 cache->valid = false; | 618 cache->valid = false; |
| 574 } | 619 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 602 std::string unique_label; | 647 std::string unique_label; |
| 603 do { | 648 do { |
| 604 unique_label = RandomLabel(); | 649 unique_label = RandomLabel(); |
| 605 } while (requests_.find(unique_label) != requests_.end()); | 650 } while (requests_.find(unique_label) != requests_.end()); |
| 606 | 651 |
| 607 requests_.insert(std::make_pair(unique_label, request)); | 652 requests_.insert(std::make_pair(unique_label, request)); |
| 608 | 653 |
| 609 return unique_label; | 654 return unique_label; |
| 610 } | 655 } |
| 611 | 656 |
| 612 void MediaStreamManager::RemoveRequest(DeviceRequests::iterator it) { | 657 void MediaStreamManager::DeleteRequest(DeviceRequests::iterator it) { |
| 658 delete it->second; | |
|
no longer working on chromium
2013/10/25 12:00:07
I think it is safer to use smart pointer to do the
perkj_chrome
2013/10/25 13:33:50
ok- but I think delete NULL is ok.
| |
| 613 requests_.erase(it); | 659 requests_.erase(it); |
| 614 } | 660 } |
| 615 | 661 |
| 616 void MediaStreamManager::PostRequestToUI(const std::string& label) { | 662 void MediaStreamManager::PostRequestToUI(const std::string& label) { |
| 617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 663 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 618 DeviceRequest* request = requests_[label]; | 664 DeviceRequest* request = requests_[label]; |
| 619 | 665 |
| 620 if (use_fake_ui_) { | 666 if (use_fake_ui_) { |
| 621 if (!fake_ui_) | 667 if (!fake_ui_) |
| 622 fake_ui_.reset(new FakeMediaStreamUIProxy()); | 668 fake_ui_.reset(new FakeMediaStreamUIProxy()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 | 712 |
| 667 if (!is_web_contents_capture && | 713 if (!is_web_contents_capture && |
| 668 !is_screen_capture && | 714 !is_screen_capture && |
| 669 ((IsAudioMediaType(audio_type) && !audio_enumeration_cache_.valid) || | 715 ((IsAudioMediaType(audio_type) && !audio_enumeration_cache_.valid) || |
| 670 (IsVideoMediaType(video_type) && !video_enumeration_cache_.valid))) { | 716 (IsVideoMediaType(video_type) && !video_enumeration_cache_.valid))) { |
| 671 // Enumerate the devices if there is no valid device lists to be used. | 717 // Enumerate the devices if there is no valid device lists to be used. |
| 672 StartEnumeration(request); | 718 StartEnumeration(request); |
| 673 return; | 719 return; |
| 674 } | 720 } |
| 675 | 721 |
| 722 // If a specific device has been requested we need to find the real device id. | |
| 723 if (!TransLateRequestedSourceIdToDeviceId(&request->request)) { | |
| 724 FinalizeRequestFailed(label); | |
| 725 return; | |
| 726 } | |
| 727 | |
| 676 // No need to do new device enumerations, post the request to UI | 728 // No need to do new device enumerations, post the request to UI |
| 677 // immediately. | 729 // immediately. |
| 678 if (IsAudioMediaType(audio_type)) | 730 if (IsAudioMediaType(audio_type)) |
| 679 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 731 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 680 if (IsVideoMediaType(video_type)) | 732 if (IsVideoMediaType(video_type)) |
| 681 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 733 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 682 | 734 |
| 683 PostRequestToUI(label); | 735 PostRequestToUI(label); |
| 684 } | 736 } |
| 685 | 737 |
| 738 bool MediaStreamManager::FindRequestedDeviceInfo( | |
| 739 const std::string& source_id, | |
| 740 int render_process_id, | |
| 741 int render_view_id, | |
| 742 MediaStreamRequestType type, | |
| 743 StreamDeviceInfo* device_info) { | |
| 744 for (DeviceRequests::const_iterator it = requests_.begin(); | |
| 745 it != requests_.end() ; ++it) { | |
| 746 const DeviceRequest* request = it->second; | |
| 747 if (request->request.render_process_id ==render_process_id && | |
| 748 request->request.render_view_id == render_view_id && | |
| 749 request->request.request_type == type) { | |
| 750 for (StreamDeviceInfoArray::const_iterator device_it = | |
| 751 request->devices.begin(); | |
| 752 device_it != request->devices.end(); ++device_it) { | |
| 753 if (source_id == device_it->device.id) { | |
| 754 if (device_info) | |
| 755 *device_info = *device_it; | |
| 756 return true; | |
| 757 } | |
| 758 } | |
| 759 } | |
| 760 } | |
| 761 return false; | |
| 762 } | |
| 763 | |
| 686 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 764 bool MediaStreamManager::FindExistingRequestedDeviceInfo( |
| 687 int render_process_id, | 765 int render_process_id, |
| 688 int render_view_id, | 766 int render_view_id, |
| 767 GURL security_origin, | |
| 689 MediaStreamRequestType type, | 768 MediaStreamRequestType type, |
| 690 const std::string& device_id, | 769 const std::string& device_id, |
| 691 StreamDeviceInfo* device_info, | 770 StreamDeviceInfo* device_info, |
| 692 MediaRequestState* request_state) const { | 771 MediaRequestState* request_state) const { |
| 693 DCHECK(device_info); | 772 DCHECK(device_info); |
| 694 DCHECK(request_state); | 773 DCHECK(request_state); |
| 774 | |
| 775 std::string source_id; | |
| 776 MediaSourceIdFactory::GenerateSourceId(security_origin, | |
| 777 device_id, | |
| 778 &source_id); | |
| 779 | |
| 695 for (DeviceRequests::const_iterator it = requests_.begin(); | 780 for (DeviceRequests::const_iterator it = requests_.begin(); |
| 696 it != requests_.end() ; ++it) { | 781 it != requests_.end() ; ++it) { |
| 697 const DeviceRequest* request = it->second; | 782 const DeviceRequest* request = it->second; |
| 698 if (request->request.render_process_id ==render_process_id && | 783 if (request->request.render_process_id ==render_process_id && |
| 699 request->request.render_view_id == render_view_id && | 784 request->request.render_view_id == render_view_id && |
| 700 request->request.request_type == type) { | 785 request->request.request_type == type) { |
| 701 for (StreamDeviceInfoArray::const_iterator device_it = | 786 for (StreamDeviceInfoArray::const_iterator device_it = |
| 702 request->devices.begin(); | 787 request->devices.begin(); |
| 703 device_it != request->devices.end(); ++device_it) { | 788 device_it != request->devices.end(); ++device_it) { |
| 704 if (device_it->device.id == device_id) { | 789 if (device_it->device.id == source_id) { |
| 705 *device_info = *device_it; | 790 *device_info = *device_it; |
| 706 *request_state = request->state(device_it->device.type); | 791 *request_state = request->state(device_it->device.type); |
| 707 return true; | 792 return true; |
| 708 } | 793 } |
| 709 } | 794 } |
| 710 } | 795 } |
| 711 } | 796 } |
| 712 return false; | 797 return false; |
| 713 } | 798 } |
| 714 | 799 |
| 800 void MediaStreamManager::FinalizeGenerateStream(const std::string& label, | |
| 801 DeviceRequest* request) { | |
| 802 const StreamDeviceInfoArray& requested_devices = request->devices; | |
| 803 | |
| 804 // Partition the array of devices into audio vs video. | |
| 805 StreamDeviceInfoArray audio_devices, video_devices; | |
| 806 for (StreamDeviceInfoArray::const_iterator device_it = | |
| 807 requested_devices.begin(); | |
| 808 device_it != requested_devices.end(); ++device_it) { | |
| 809 if (IsAudioMediaType(device_it->device.type)) { | |
| 810 audio_devices.push_back(*device_it); | |
| 811 } else if (IsVideoMediaType(device_it->device.type)) { | |
| 812 video_devices.push_back(*device_it); | |
| 813 } else { | |
| 814 NOTREACHED(); | |
| 815 } | |
| 816 } | |
| 817 | |
| 818 request->requester->StreamGenerated(label, audio_devices, video_devices); | |
| 819 } | |
| 820 | |
| 821 void MediaStreamManager::FinalizeRequestFailed( | |
| 822 const std::string& label) { | |
| 823 DeviceRequests::iterator request_it = requests_.find(label); | |
| 824 if (request_it == requests_.end()) { | |
|
no longer working on chromium
2013/10/25 12:00:07
nit, no need {}
perkj_chrome
2013/10/25 13:33:50
Done.
| |
| 825 return; | |
| 826 } | |
| 827 DeviceRequest* request(request_it->second); | |
| 828 if (request->requester) | |
| 829 request->requester->StreamGenerationFailed(label); | |
| 830 | |
| 831 if (request->request.request_type == MEDIA_DEVICE_ACCESS && | |
| 832 !request->callback.is_null()) { | |
| 833 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass()); | |
| 834 } | |
| 835 | |
| 836 DeleteRequest(request_it); | |
| 837 } | |
| 838 | |
| 839 void MediaStreamManager::FinalizeOpenDevice(const std::string& label, | |
| 840 DeviceRequest* request) { | |
| 841 const StreamDeviceInfoArray& requested_devices = request->devices; | |
| 842 request->requester->DeviceOpened(label, requested_devices.front()); | |
| 843 } | |
| 844 | |
| 845 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, | |
| 846 DeviceRequest* request) { | |
| 847 StreamDeviceInfoArray hmaced_devices; | |
| 848 MediaSourceIdFactory::GenerateSourceIds(request->request.security_origin, | |
| 849 request->devices, | |
| 850 &hmaced_devices); | |
| 851 request->requester->DevicesEnumerated(label, hmaced_devices); | |
| 852 } | |
| 853 | |
| 854 void MediaStreamManager::FinalizeMediaAccessRequest( | |
| 855 const std::string& label, | |
| 856 const MediaStreamDevices& devices) { | |
| 857 DeviceRequests::iterator request_it = requests_.find(label); | |
| 858 if (request_it == requests_.end()) { | |
|
no longer working on chromium
2013/10/25 12:00:07
ditto
perkj_chrome
2013/10/25 13:33:50
Done.
| |
| 859 return; | |
| 860 } | |
| 861 DeviceRequest* request(request_it->second); | |
| 862 | |
| 863 if (!request->callback.is_null()) | |
| 864 request->callback.Run(devices, request->ui_proxy.Pass()); | |
| 865 | |
| 866 // Delete the request since it is done. | |
| 867 DeleteRequest(request_it); | |
| 868 return; | |
|
no longer working on chromium
2013/10/25 12:00:07
you don't need the return
perkj_chrome
2013/10/25 13:33:50
Done.
| |
| 869 } | |
| 870 | |
| 715 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { | 871 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { |
| 716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 717 if (device_thread_) | 873 if (device_thread_) |
| 718 return; | 874 return; |
| 719 | 875 |
| 720 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); | 876 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); |
| 721 #if defined(OS_WIN) | 877 #if defined(OS_WIN) |
| 722 device_thread_->init_com_with_mta(true); | 878 device_thread_->init_com_with_mta(true); |
| 723 #endif | 879 #endif |
| 724 CHECK(device_thread_->Start()); | 880 CHECK(device_thread_->Start()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE); | 915 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE); |
| 760 | 916 |
| 761 if (IsAudioMediaType(device_it->device.type)) { | 917 if (IsAudioMediaType(device_it->device.type)) { |
| 762 // Store the native audio parameters in the device struct. | 918 // Store the native audio parameters in the device struct. |
| 763 // TODO(xians): Handle the tab capture sample rate/channel layout | 919 // TODO(xians): Handle the tab capture sample rate/channel layout |
| 764 // in AudioInputDeviceManager::Open(). | 920 // in AudioInputDeviceManager::Open(). |
| 765 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { | 921 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { |
| 766 const StreamDeviceInfo* info = | 922 const StreamDeviceInfo* info = |
| 767 audio_input_device_manager_->GetOpenedDeviceInfoById( | 923 audio_input_device_manager_->GetOpenedDeviceInfoById( |
| 768 device_it->session_id); | 924 device_it->session_id); |
| 769 DCHECK_EQ(info->device.id, device_it->device.id); | |
| 770 device_it->device.input = info->device.input; | 925 device_it->device.input = info->device.input; |
| 771 device_it->device.matched_output = info->device.matched_output; | 926 device_it->device.matched_output = info->device.matched_output; |
| 772 } | 927 } |
| 773 } | 928 } |
| 774 if (RequestDone(*request)) | 929 if (RequestDone(*request)) |
| 775 HandleRequestDone(label, request); | 930 HandleRequestDone(label, request); |
| 776 break; | 931 break; |
| 777 } | 932 } |
| 778 } | 933 } |
| 779 } | 934 } |
| 780 } | 935 } |
| 781 | 936 |
| 782 void MediaStreamManager::HandleRequestDone(const std::string& label, | 937 void MediaStreamManager::HandleRequestDone(const std::string& label, |
| 783 DeviceRequest* request) { | 938 DeviceRequest* request) { |
| 784 DCHECK(RequestDone(*request)); | 939 DCHECK(RequestDone(*request)); |
| 785 DVLOG(1) << "HandleRequestDone(" | 940 DVLOG(1) << "HandleRequestDone(" |
| 786 << ", {label = " << label << "})"; | 941 << ", {label = " << label << "})"; |
| 787 | 942 |
| 788 const StreamDeviceInfoArray& requested_devices = request->devices; | |
| 789 switch (request->request.request_type) { | 943 switch (request->request.request_type) { |
| 790 case MEDIA_OPEN_DEVICE: | 944 case MEDIA_OPEN_DEVICE: |
| 791 request->requester->DeviceOpened(label, requested_devices.front()); | 945 FinalizeOpenDevice(label, request); |
| 792 break; | 946 break; |
| 793 case MEDIA_GENERATE_STREAM: { | 947 case MEDIA_GENERATE_STREAM: { |
| 794 // Partition the array of devices into audio vs video. | 948 FinalizeGenerateStream(label, request); |
| 795 StreamDeviceInfoArray audio_devices, video_devices; | |
| 796 for (StreamDeviceInfoArray::const_iterator device_it = | |
| 797 requested_devices.begin(); | |
| 798 device_it != requested_devices.end(); ++device_it) { | |
| 799 if (IsAudioMediaType(device_it->device.type)) { | |
| 800 audio_devices.push_back(*device_it); | |
| 801 } else if (IsVideoMediaType(device_it->device.type)) { | |
| 802 video_devices.push_back(*device_it); | |
| 803 } else { | |
| 804 NOTREACHED(); | |
| 805 } | |
| 806 } | |
| 807 | |
| 808 request->requester->StreamGenerated(label, audio_devices, video_devices); | |
| 809 break; | 949 break; |
| 810 } | 950 } |
| 811 default: | 951 default: |
| 812 NOTREACHED(); | 952 NOTREACHED(); |
| 813 break; | 953 break; |
| 814 } | 954 } |
| 815 | 955 |
| 816 if (request->ui_proxy.get()) { | 956 if (request->ui_proxy.get()) { |
| 817 request->ui_proxy->OnStarted( | 957 request->ui_proxy->OnStarted( |
| 818 base::Bind(&MediaStreamManager::StopStreamFromUI, | 958 base::Bind(&MediaStreamManager::StopStreamFromUI, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 858 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES) | 998 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES) |
| 859 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 999 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
| 860 label_list.push_back(it->first); | 1000 label_list.push_back(it->first); |
| 861 } | 1001 } |
| 862 } | 1002 } |
| 863 for (std::list<std::string>::iterator it = label_list.begin(); | 1003 for (std::list<std::string>::iterator it = label_list.begin(); |
| 864 it != label_list.end(); ++it) { | 1004 it != label_list.end(); ++it) { |
| 865 DeviceRequest* request = requests_[*it]; | 1005 DeviceRequest* request = requests_[*it]; |
| 866 switch (request->request.request_type) { | 1006 switch (request->request.request_type) { |
| 867 case MEDIA_ENUMERATE_DEVICES: | 1007 case MEDIA_ENUMERATE_DEVICES: |
| 868 if (need_update_clients && request->requester) | 1008 if (need_update_clients && request->requester) { |
| 869 request->requester->DevicesEnumerated(*it, devices); | 1009 request->devices = devices; |
| 1010 FinalizeEnumerateDevices(*it, request); | |
| 1011 } | |
| 870 break; | 1012 break; |
| 871 default: | 1013 default: |
| 872 if (request->state(request->request.audio_type) == | 1014 if (request->state(request->request.audio_type) == |
| 873 MEDIA_REQUEST_STATE_REQUESTED || | 1015 MEDIA_REQUEST_STATE_REQUESTED || |
| 874 request->state(request->request.video_type) == | 1016 request->state(request->request.video_type) == |
| 875 MEDIA_REQUEST_STATE_REQUESTED) { | 1017 MEDIA_REQUEST_STATE_REQUESTED) { |
| 876 // We are doing enumeration for other type of media, wait until it is | 1018 // We are doing enumeration for other type of media, wait until it is |
| 877 // all done before posting the request to UI because UI needs | 1019 // all done before posting the request to UI because UI needs |
| 878 // the device lists to handle the request. | 1020 // the device lists to handle the request. |
| 879 break; | 1021 break; |
| 880 } | 1022 } |
| 881 | 1023 |
| 882 // Post the request to UI for permission approval. | 1024 // Continue to handle the request. |
| 883 PostRequestToUI(*it); | 1025 HandleRequest(*it); |
| 884 break; | 1026 break; |
| 885 } | 1027 } |
| 886 } | 1028 } |
| 887 label_list.clear(); | 1029 label_list.clear(); |
| 888 --active_enumeration_ref_count_[stream_type]; | 1030 --active_enumeration_ref_count_[stream_type]; |
| 889 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 1031 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
| 890 } | 1032 } |
| 891 | 1033 |
| 892 void MediaStreamManager::Error(MediaStreamType stream_type, | |
| 893 int capture_session_id, | |
| 894 MediaStreamProviderError error) { | |
| 895 // Find the device for the error call. | |
| 896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 897 DVLOG(1) << "Error(" | |
| 898 << "{stream_type = " << stream_type << "} ," | |
| 899 << "{capture_session_id = " << capture_session_id << "})"; | |
| 900 | |
| 901 | |
| 902 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | |
| 903 ++it) { | |
| 904 StreamDeviceInfoArray& devices = it->second->devices; | |
| 905 | |
| 906 // TODO(miu): BUG. It's possible for the audio (or video) device array in | |
| 907 // the "requester" to become out-of-sync with the order of devices we have | |
| 908 // here. See http://crbug.com/147650 | |
| 909 int audio_device_idx = -1; | |
| 910 int video_device_idx = -1; | |
| 911 for (StreamDeviceInfoArray::iterator device_it = devices.begin(); | |
| 912 device_it != devices.end(); ++device_it) { | |
| 913 if (IsAudioMediaType(device_it->device.type)) { | |
| 914 ++audio_device_idx; | |
| 915 } else if (IsVideoMediaType(device_it->device.type)) { | |
| 916 ++video_device_idx; | |
| 917 } else { | |
| 918 NOTREACHED(); | |
| 919 continue; | |
| 920 } | |
| 921 if (device_it->device.type != stream_type || | |
| 922 device_it->session_id != capture_session_id) { | |
| 923 continue; | |
| 924 } | |
| 925 // We've found the failing device. Find the error case: | |
| 926 // An error should only be reported to the MediaStreamManager if | |
| 927 // the request has not been fulfilled yet. | |
| 928 DCHECK(it->second->state(stream_type) != MEDIA_REQUEST_STATE_DONE); | |
| 929 if (it->second->state(stream_type) != MEDIA_REQUEST_STATE_DONE) { | |
| 930 // Request is not done, devices are not opened in this case. | |
| 931 if (devices.size() <= 1) { | |
| 932 scoped_ptr<DeviceRequest> request(it->second); | |
| 933 // 1. Device not opened and no other devices for this request -> | |
| 934 // signal stream error and remove the request. | |
| 935 if (request->requester) | |
| 936 request->requester->StreamGenerationFailed(it->first); | |
| 937 | |
| 938 RemoveRequest(it); | |
| 939 } else { | |
| 940 // 2. Not opened but other devices exists for this request -> remove | |
| 941 // device from list, but don't signal an error. | |
| 942 devices.erase(device_it); // NOTE: This invalidates device_it! | |
| 943 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_ERROR); | |
| 944 DVLOG(1) << "Error(" | |
| 945 << ", {capture_session_id = " << capture_session_id << "})"; | |
| 946 } | |
| 947 } | |
| 948 if (RequestDone(*it->second)) | |
| 949 HandleRequestDone(it->first, it->second); | |
| 950 break; | |
| 951 } | |
| 952 } | |
| 953 } | |
| 954 | |
| 955 void MediaStreamManager::HandleAccessRequestResponse( | 1034 void MediaStreamManager::HandleAccessRequestResponse( |
| 956 const std::string& label, | 1035 const std::string& label, |
| 957 const MediaStreamDevices& devices) { | 1036 const MediaStreamDevices& devices) { |
| 958 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1037 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 959 DVLOG(1) << "HandleAccessRequestResponse(" | 1038 DVLOG(1) << "HandleAccessRequestResponse(" |
| 960 << ", {label = " << label << "})"; | 1039 << ", {label = " << label << "})"; |
| 961 | 1040 |
| 962 DeviceRequests::iterator request_it = requests_.find(label); | 1041 DeviceRequests::iterator request_it = requests_.find(label); |
| 963 if (request_it == requests_.end()) { | 1042 if (request_it == requests_.end()) { |
| 964 return; | 1043 return; |
| 965 } | 1044 } |
| 966 | 1045 |
| 1046 DeviceRequest* request = request_it->second; | |
| 1047 if (request->request.request_type == MEDIA_DEVICE_ACCESS) { | |
| 1048 FinalizeMediaAccessRequest(label, devices); | |
| 1049 return; | |
| 1050 } | |
| 1051 | |
| 967 // Handle the case when the request was denied. | 1052 // Handle the case when the request was denied. |
| 968 if (devices.empty()) { | 1053 if (devices.empty()) { |
| 969 // Notify the users about the request result. | 1054 FinalizeRequestFailed(label); |
| 970 scoped_ptr<DeviceRequest> request(request_it->second); | |
| 971 if (request->requester) | |
| 972 request->requester->StreamGenerationFailed(label); | |
| 973 | |
| 974 if (request->request.request_type == MEDIA_DEVICE_ACCESS && | |
| 975 !request->callback.is_null()) { | |
| 976 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass()); | |
| 977 } | |
| 978 | |
| 979 RemoveRequest(request_it); | |
| 980 return; | |
| 981 } | |
| 982 | |
| 983 if (request_it->second->request.request_type == MEDIA_DEVICE_ACCESS) { | |
| 984 scoped_ptr<DeviceRequest> request(request_it->second); | |
| 985 if (!request->callback.is_null()) | |
| 986 request->callback.Run(devices, request->ui_proxy.Pass()); | |
| 987 | |
| 988 // Delete the request since it is done. | |
| 989 RemoveRequest(request_it); | |
| 990 return; | 1055 return; |
| 991 } | 1056 } |
| 992 | 1057 |
| 993 // Process all newly-accepted devices for this request. | 1058 // Process all newly-accepted devices for this request. |
| 994 DeviceRequest* request = request_it->second; | |
| 995 bool found_audio = false; | 1059 bool found_audio = false; |
| 996 bool found_video = false; | 1060 bool found_video = false; |
| 997 for (MediaStreamDevices::const_iterator device_it = devices.begin(); | 1061 for (MediaStreamDevices::const_iterator device_it = devices.begin(); |
| 998 device_it != devices.end(); ++device_it) { | 1062 device_it != devices.end(); ++device_it) { |
| 999 StreamDeviceInfo device_info; | 1063 StreamDeviceInfo device_info; |
| 1000 device_info.device = *device_it; | 1064 device_info.device = *device_it; |
| 1001 | 1065 |
| 1002 // TODO(justinlin): Nicer way to do this? | 1066 // TODO(justinlin): Nicer way to do this? |
| 1003 // Re-append the device's id since we lost it when posting request to UI. | 1067 // Re-append the device's id since we lost it when posting request to UI. |
| 1004 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || | 1068 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1025 if (device_info.device.type == request->request.audio_type) { | 1089 if (device_info.device.type == request->request.audio_type) { |
| 1026 found_audio = true; | 1090 found_audio = true; |
| 1027 } else if (device_info.device.type == request->request.video_type) { | 1091 } else if (device_info.device.type == request->request.video_type) { |
| 1028 found_video = true; | 1092 found_video = true; |
| 1029 } | 1093 } |
| 1030 | 1094 |
| 1031 // If this is request for a new MediaStream, a device is only opened once | 1095 // If this is request for a new MediaStream, a device is only opened once |
| 1032 // per render view. This is so that the permission to use a device can be | 1096 // per render view. This is so that the permission to use a device can be |
| 1033 // revoked by a single call to StopStreamDevice regardless of how many | 1097 // revoked by a single call to StopStreamDevice regardless of how many |
| 1034 // MediaStreams it is being used in. | 1098 // MediaStreams it is being used in. |
| 1035 | |
| 1036 if (request->request.request_type == MEDIA_GENERATE_STREAM) { | 1099 if (request->request.request_type == MEDIA_GENERATE_STREAM) { |
| 1037 MediaRequestState state; | 1100 MediaRequestState state; |
| 1038 if (FindExistingRequestedDeviceInfo(request->request.render_process_id, | 1101 if (FindExistingRequestedDeviceInfo(request->request.render_process_id, |
| 1039 request->request.render_view_id, | 1102 request->request.render_view_id, |
| 1103 request->request.security_origin, | |
| 1040 request->request.request_type, | 1104 request->request.request_type, |
| 1041 device_it->id, | 1105 device_it->id, |
| 1042 &device_info, | 1106 &device_info, |
| 1043 &state)) { | 1107 &state)) { |
| 1044 request->devices.push_back(device_info); | 1108 request->devices.push_back(device_info); |
| 1045 request->SetState(device_info.device.type, state); | 1109 request->SetState(device_info.device.type, state); |
| 1046 DVLOG(1) << "HandleAccessRequestResponse - device already opened " | 1110 DVLOG(1) << "HandleAccessRequestResponse - device already opened " |
| 1047 << ", {label = " << label << "}" | 1111 << ", {label = " << label << "}" |
| 1048 << ", device_id = " << device_it->id << "}"; | 1112 << ", device_id = " << device_it->id << "}"; |
| 1049 continue; | 1113 continue; |
| 1050 } | 1114 } |
| 1051 } | 1115 } |
| 1052 device_info.session_id = | 1116 device_info.session_id = |
| 1053 GetDeviceManager(device_info.device.type)->Open(device_info); | 1117 GetDeviceManager(device_info.device.type)->Open(device_info); |
| 1118 MediaSourceIdFactory::GenerateSourceId( | |
| 1119 request->request.security_origin, | |
| 1120 device_it->id, | |
| 1121 &device_info.device.id); | |
| 1054 request->devices.push_back(device_info); | 1122 request->devices.push_back(device_info); |
| 1123 | |
| 1055 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); | 1124 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); |
| 1056 DVLOG(1) << "HandleAccessRequestResponse - opening device " | 1125 DVLOG(1) << "HandleAccessRequestResponse - opening device " |
| 1057 << ", {label = " << label << "}" | 1126 << ", {label = " << label << "}" |
| 1058 << ", {device_id = " << device_it->id << "}" | 1127 << ", {device_id = " << device_it->id << "}" |
| 1059 << ", {session_id = " << device_info.session_id << "}"; | 1128 << ", {session_id = " << device_info.session_id << "}"; |
| 1060 } | 1129 } |
| 1061 | 1130 |
| 1062 // Check whether we've received all stream types requested. | 1131 // Check whether we've received all stream types requested. |
| 1063 if (!found_audio && IsAudioMediaType(request->request.audio_type)) { | 1132 if (!found_audio && IsAudioMediaType(request->request.audio_type)) { |
| 1064 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR); | 1133 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1094 audio_input_device_manager()->UseFakeDevice(); | 1163 audio_input_device_manager()->UseFakeDevice(); |
| 1095 } | 1164 } |
| 1096 | 1165 |
| 1097 void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) { | 1166 void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) { |
| 1098 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1099 use_fake_ui_ = true; | 1168 use_fake_ui_ = true; |
| 1100 fake_ui_ = fake_ui.Pass(); | 1169 fake_ui_ = fake_ui.Pass(); |
| 1101 } | 1170 } |
| 1102 | 1171 |
| 1103 void MediaStreamManager::WillDestroyCurrentMessageLoop() { | 1172 void MediaStreamManager::WillDestroyCurrentMessageLoop() { |
| 1173 DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()"; | |
| 1104 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 1174 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
| 1105 DCHECK(requests_.empty()); | 1175 DCHECK(requests_.empty()); |
| 1106 if (device_thread_) { | 1176 if (device_thread_) { |
| 1107 StopMonitoring(); | 1177 StopMonitoring(); |
| 1108 | 1178 |
| 1109 video_capture_manager_->Unregister(); | 1179 video_capture_manager_->Unregister(); |
| 1110 audio_input_device_manager_->Unregister(); | 1180 audio_input_device_manager_->Unregister(); |
| 1111 device_thread_.reset(); | 1181 device_thread_.reset(); |
| 1112 } | 1182 } |
| 1113 | 1183 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1195 } | 1265 } |
| 1196 | 1266 |
| 1197 // Always do enumeration even though some enumeration is in progress, | 1267 // Always do enumeration even though some enumeration is in progress, |
| 1198 // because those enumeration commands could be sent before these devices | 1268 // because those enumeration commands could be sent before these devices |
| 1199 // change. | 1269 // change. |
| 1200 ++active_enumeration_ref_count_[stream_type]; | 1270 ++active_enumeration_ref_count_[stream_type]; |
| 1201 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); | 1271 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); |
| 1202 } | 1272 } |
| 1203 | 1273 |
| 1204 } // namespace content | 1274 } // namespace content |
| OLD | NEW |