15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/media_stream_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/power_monitor/power_monitor.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/run_loop.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/browser_main_loop.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/media/capture/web_contents_capture_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_device_manager.h" 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/renderer_host/media/device_request_message_filter.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/renderer_host/media/media_capture_devices_impl.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/media_stream_requester.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/video_capture_manager.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/content_browser_client.h" 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/media_device_id.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/media_observer.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/media_request_state.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/common/content_client.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/media_stream_request.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_manager_base.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_parameters.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/channel_layout.h" 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "media/base/media_switches.h" 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "media/video/capture/video_capture_device_factory.h" 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_com_initializer.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS) 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/audio/cras_audio_handler.h" 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Forward declaration of DeviceMonitorMac and its only useable method. 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class DeviceMonitorMac { 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void StartMonitoring( 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a random label used to identify requests. 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string RandomLabel() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An earlier PeerConnection spec, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://dev.w3.org/2011/webrtc/editor/webrtc.html, specified the 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MediaStream::label alphabet as containing 36 characters from 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // range: U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Here we use a safe subset. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kAlphabet[] = "0123456789" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string label(36, ' '); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < label.size(); ++i) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label[i] = kAlphabet[random_char]; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return label; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ParseStreamType(const StreamOptions& options, 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType* audio_type, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType* video_type) { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *audio_type = MEDIA_NO_SERVICE; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *video_type = MEDIA_NO_SERVICE; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (options.audio_requested) { 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string audio_stream_source; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool mandatory = false; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (options.GetFirstAudioConstraintByName(kMediaStreamSource, 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &audio_stream_source, 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &mandatory)) { 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(mandatory); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is tab or screen capture. 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (audio_stream_source == kMediaStreamSourceTab) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *audio_type = content::MEDIA_TAB_AUDIO_CAPTURE; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (audio_stream_source == kMediaStreamSourceSystem) { 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *audio_type = content::MEDIA_LOOPBACK_AUDIO_CAPTURE; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is normal audio device capture. 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *audio_type = MEDIA_DEVICE_AUDIO_CAPTURE; 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (options.video_requested) { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string video_stream_source; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool mandatory = false; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (options.GetFirstVideoConstraintByName(kMediaStreamSource, 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &video_stream_source, 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &mandatory)) { 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(mandatory); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is tab or screen capture. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (video_stream_source == kMediaStreamSourceTab) { 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *video_type = content::MEDIA_TAB_VIDEO_CAPTURE; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (video_stream_source == kMediaStreamSourceScreen) { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (video_stream_source == kMediaStreamSourceDesktop) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is normal video device capture. 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *video_type = MEDIA_DEVICE_VIDEO_CAPTURE; 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Turns off available audio effects (removes the flag) if the options 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// explicitly turn them off. 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void FilterAudioEffects(const StreamOptions& options, int* effects) { 1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(effects); 1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(ajm): Should we also handle ECHO_CANCELLER here? 1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::string value; 1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (options.GetFirstAudioConstraintByName( 1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) kMediaStreamAudioDucking, &value, NULL) && value == "false") { 1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *effects &= ~media::AudioParameters::DUCKING; 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Private helper method for SendMessageToNativeLog() that obtains the global 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MediaStreamManager instance on the UI thread before sending |message| to the 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// webrtcLoggingPrivate API. 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DoAddLogMessage(const std::string& message) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Must be on the UI thread to access BrowserMainLoop. 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // May be null in tests. 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(vrk): Handle this more elegantly by having native log messages become 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // no-ops until MediaStreamManager is aware that a renderer process has 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // started logging. crbug.com/333894 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (content::BrowserMainLoop::GetInstance()) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::IO, 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&MediaStreamManager::AddLogMessageOnIOThread, 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(content::BrowserMainLoop::GetInstance() 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->media_stream_manager()), 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message)); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Private helper method to generate a string for the log message that lists the 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// human readable names of |devices|. 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string GetLogMessageString(MediaStreamType stream_type, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StreamDeviceInfoArray& devices) { 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string output_string = 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::StringPrintf("Getting devices for stream type %d:\n", stream_type); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (devices.empty()) { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_string += "No devices found."; 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (StreamDeviceInfoArray::const_iterator it = devices.begin(); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != devices.end(); ++it) { 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_string += " " + it->device.name + "\n"; 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return output_string; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Needed for MediaStreamManager::GenerateStream below. 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ReturnEmptySalt() { 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return std::string(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Clears the MediaStreamDevice.name from all devices in |devices|. 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (content::StreamDeviceInfoArray::iterator device_itr = devices->begin(); 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_itr != devices->end(); 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++device_itr) { 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_itr->device.name.clear(); 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MediaStreamManager::DeviceRequest represents a request to either enumerate 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// available devices or open one or more devices. 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(perkj): MediaStreamManager still needs refactoring. I propose we create 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// several subclasses of DeviceRequest and move some of the responsibility of 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the MediaStreamManager to the subclasses to get rid of the way too many if 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// statements in MediaStreamManager. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MediaStreamManager::DeviceRequest { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceRequest(MediaStreamRequester* requester, 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int requesting_process_id, 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int requesting_frame_id, 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int page_request_id, 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& security_origin, 206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool user_gesture, 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamRequestType request_type, 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StreamOptions& options, 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ResourceContext::SaltCallback& salt_callback) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : requester(requester), 2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) requesting_process_id(requesting_process_id), 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch requesting_frame_id(requesting_frame_id), 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id(page_request_id), 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin(security_origin), 215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch user_gesture(user_gesture), 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_type(request_type), 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options(options), 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) salt_callback(salt_callback), 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_type_(MEDIA_NO_SERVICE), 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_type_(MEDIA_NO_SERVICE) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DeviceRequest() {} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetAudioType(MediaStreamType audio_type) { 22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(IsAudioInputMediaType(audio_type) || 22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) audio_type == MEDIA_DEVICE_AUDIO_OUTPUT || 22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) audio_type == MEDIA_NO_SERVICE); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_type_ = audio_type; 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType audio_type() const { return audio_type_; } 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetVideoType(MediaStreamType video_type) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(IsVideoMediaType(video_type) || video_type == MEDIA_NO_SERVICE); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_type_ = video_type; 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType video_type() const { return video_type_; } 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates a MediaStreamRequest object that is used by this request when UI 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is asked for permission and device selection. 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CreateUIRequest(const std::string& requested_audio_device_id, 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& requested_video_device_id) { 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!ui_request_); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_request_.reset(new MediaStreamRequest(requesting_process_id, 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch requesting_frame_id, 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id, 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin, 251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch user_gesture, 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_type, 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requested_audio_device_id, 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requested_video_device_id, 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_type_, 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_type_)); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates a tab capture specific MediaStreamRequest object that is used by 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this request when UI is asked for permission and device selection. 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void CreateTabCaptureUIRequest(int target_render_process_id, 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int target_render_frame_id, 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& tab_capture_id) { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!ui_request_); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_request_.reset(new MediaStreamRequest(target_render_process_id, 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch target_render_frame_id, 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id, 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin, 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch user_gesture, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_type, 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "", 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "", 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_type_, 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_type_)); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_request_->tab_capture_device_id = tab_capture_id; 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MediaStreamRequest* UIRequest() const { return ui_request_.get(); } 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the request state and notify observers. 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetState(MediaStreamType stream_type, MediaRequestState new_state) { 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (stream_type == NUM_MEDIA_TYPES) { 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { 2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const MediaStreamType stream_type = static_cast<MediaStreamType>(i); 2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch state_[stream_type] = new_state; 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch state_[stream_type] = new_state; 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaObserver* media_observer = 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContentClient()->browser()->GetMediaObserver(); 293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!media_observer) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If |ui_request_| doesn't exist, it means that the request has not yet 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // been setup fully and there are no valid observers. 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ui_request_) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media_observer->OnMediaRequestStateChanged( 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui_request_->render_process_id, ui_request_->render_frame_id, 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_request_->page_request_id, ui_request_->security_origin, 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stream_type, new_state); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaRequestState state(MediaStreamType stream_type) const { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state_[stream_type]; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaStreamRequester* const requester; // Can be NULL. 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The render process id that requested this stream to be generated and that 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // will receive a handle to the MediaStream. This may be different from 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // MediaStreamRequest::render_process_id which in the tab capture case 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // specifies the target renderer from which audio and video is captured. 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int requesting_process_id; 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The render frame id that requested this stream to be generated and that 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // will receive a handle to the MediaStream. This may be different from 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // MediaStreamRequest::render_frame_id which in the tab capture case 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // specifies the target renderer from which audio and video is captured. 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const int requesting_frame_id; 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // An ID the render frame provided to identify this request. 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int page_request_id; 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL security_origin; 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 331effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const bool user_gesture; 332effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MediaStreamRequestType request_type; 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StreamOptions options; 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceContext::SaltCallback salt_callback; 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamDeviceInfoArray devices; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback to the requester which audio/video devices have been selected. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It can be null if the requester has no interest to know the result. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently it is only used by |DEVICE_ACCESS| type. 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MediaStreamManager::MediaRequestResponseCallback callback; 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<MediaStreamUIProxy> ui_proxy; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<MediaRequestState> state_; 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<MediaStreamRequest> ui_request_; 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType audio_type_; 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType video_type_; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamManager::EnumerationCache::EnumerationCache() 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : valid(false) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamManager::EnumerationCache::~EnumerationCache() { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochMediaStreamManager::MediaStreamManager() 3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : audio_manager_(NULL), 3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch monitoring_started_(false), 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS) 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci has_checked_keyboard_mic_(false), 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch io_loop_(NULL), 3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch use_fake_ui_(false) {} 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : audio_manager_(audio_manager), 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitoring_started_(false), 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS) 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci has_checked_keyboard_mic_(false), 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_loop_(NULL), 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) use_fake_ui_(false) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(audio_manager_); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(active_enumeration_ref_count_, 0, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(active_enumeration_ref_count_)); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Some unit tests create the MSM in the IO thread and assumes the 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // initialization is done synchronously. 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InitializeDeviceManagersOnIOThread(); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::IO, FROM_HERE, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MediaStreamManager::InitializeDeviceManagersOnIOThread, 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 393effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); 395effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // BrowserMainLoop always creates the PowerMonitor instance before creating 396effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // MediaStreamManager, but power_monitor may be NULL in unit tests. 397effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (power_monitor) 398effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch power_monitor->AddObserver(this); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamManager::~MediaStreamManager() { 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "~MediaStreamManager"; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(requests_.empty()); 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!device_task_runner_.get()); 405effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 406effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); 407effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // The PowerMonitor instance owned by BrowserMainLoops always outlives the 408effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // MediaStreamManager, but it may be NULL in unit tests. 409effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (power_monitor) 410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch power_monitor->RemoveObserver(this); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoCaptureManager* MediaStreamManager::video_capture_manager() { 414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(video_capture_manager_.get()); 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return video_capture_manager_.get(); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { 420effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(audio_input_device_manager_.get()); 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return audio_input_device_manager_.get(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string MediaStreamManager::MakeMediaAccessRequest( 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_process_id, 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int page_request_id, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StreamOptions& options, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& security_origin, 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const MediaRequestResponseCallback& callback) { 432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(perkj): The argument list with NULL parameters to DeviceRequest 435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // suggests that this is the wrong design. Can this be refactored? 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceRequest* request = new DeviceRequest(NULL, 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_process_id, 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch render_frame_id, 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id, 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin, 441effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch false, // user gesture 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MEDIA_DEVICE_ACCESS, 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options, 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ReturnEmptySalt)); 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& label = AddRequest(request); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->callback = callback; 449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Post a task and handle the request asynchronously. The reason is that the 450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // requester won't have a label for the request until this function returns 451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // and thus can not handle a response. Using base::Unretained is safe since 452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // MediaStreamManager is deleted on the UI thread, after the IO thread has 453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // been stopped. 454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::PostTask( 455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MediaStreamManager::SetupRequest, 457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this), label)); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return label; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_process_id, 463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ResourceContext::SaltCallback& sc, 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int page_request_id, 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StreamOptions& options, 467effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const GURL& security_origin, 468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool user_gesture) { 469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "GenerateStream()"; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switches::kUseFakeUIForMediaStream)) { 473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); 474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceRequest* request = new DeviceRequest(requester, 4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) render_process_id, 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch render_frame_id, 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id, 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin, 481effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch user_gesture, 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MEDIA_GENERATE_STREAM, 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options, 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sc); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& label = AddRequest(request); 487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Post a task and handle the request asynchronously. The reason is that the 489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // requester won't have a label for the request until this function returns 490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // and thus can not handle a response. Using base::Unretained is safe since 491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // MediaStreamManager is deleted on the UI thread, after the IO thread has 492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // been stopped. 493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::PostTask( 494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MediaStreamManager::SetupRequest, 496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this), label)); 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamManager::CancelRequest(int render_process_id, 500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int page_request_id) { 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (DeviceRequests::const_iterator request_it = requests_.begin(); 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_it != requests_.end(); ++request_it) { 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const DeviceRequest* request = request_it->second; 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->requesting_process_id == render_process_id && 506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requesting_frame_id == render_frame_id && 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->page_request_id == page_request_id) { 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CancelRequest(request_it->first); 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::CancelRequest(const std::string& label) { 516effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "CancelRequest({label = " << label << "})"; 518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(label); 519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request) { 520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The request does not exist. 521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << "The request with label = " << label << " does not exist."; 5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->request_type == MEDIA_ENUMERATE_DEVICES) { 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // It isn't an ideal use of "CancelRequest" to make it a requirement 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // for enumeration requests to be deleted via "CancelRequest" _after_ 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the request has been successfully fulfilled. 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // See note in FinalizeEnumerateDevices for a recommendation on how 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we should refactor this. 531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeleteRequest(label); 5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // This is a request for opening one or more devices. 5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); 537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_it != request->devices.end(); ++device_it) { 538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MediaRequestState state = request->state(device_it->device.type); 5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If we have not yet requested the device to be opened - just ignore it. 540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (state != MEDIA_REQUEST_STATE_OPENING && 541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state != MEDIA_REQUEST_STATE_DONE) { 5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Stop the opening/opened devices of the requests. 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloseDevice(device_it->device.type, device_it->session_id); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Cancel the request if still pending at UI side. 5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING); 550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeleteRequest(label); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void MediaStreamManager::CancelAllRequests(int render_process_id) { 5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DeviceRequests::iterator request_it = requests_.begin(); 5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) while (request_it != requests_.end()) { 5561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (request_it->second->requesting_process_id != render_process_id) { 5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++request_it; 5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string label = request_it->first; 5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++request_it; 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CancelRequest(label); 5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void MediaStreamManager::StopStreamDevice(int render_process_id, 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 5698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string& device_id) { 570effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DVLOG(1) << "StopStreamDevice({render_frame_id = " << render_frame_id << "} " 5728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", {device_id = " << device_id << "})"; 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Find the first request for this |render_process_id| and |render_frame_id| 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // of type MEDIA_GENERATE_STREAM that has requested to use |device_id| and 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // stop it. 576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (DeviceRequests::iterator request_it = requests_.begin(); 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request_it != requests_.end(); ++request_it) { 5781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DeviceRequest* request = request_it->second; 5791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (request->requesting_process_id != render_process_id || 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requesting_frame_id != render_frame_id || 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->request_type != MEDIA_GENERATE_STREAM) { 5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 5838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StreamDeviceInfoArray& devices = request->devices; 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (StreamDeviceInfoArray::iterator device_it = devices.begin(); 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it != devices.end(); ++device_it) { 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (device_it->device.id == device_id) { 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopDevice(device_it->device.type, device_it->session_id); 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaStreamManager::StopDevice(MediaStreamType type, int session_id) { 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "StopDevice" 598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "{type = " << type << "}" 599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "{session_id = " << session_id << "}"; 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DeviceRequests::iterator request_it = requests_.begin(); 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (request_it != requests_.end()) { 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DeviceRequest* request = request_it->second; 6038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StreamDeviceInfoArray* devices = &request->devices; 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (devices->empty()) { 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There is no device in use yet by this request. 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++request_it; 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StreamDeviceInfoArray::iterator device_it = devices->begin(); 6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) while (device_it != devices->end()) { 611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (device_it->device.type != type || 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it->session_id != session_id) { 6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++device_it; 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (request->state(type) == MEDIA_REQUEST_STATE_DONE) 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloseDevice(type, session_id); 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it = devices->erase(device_it); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If this request doesn't have any active devices after a device 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // has been stopped above, remove the request. Note that the request is 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // only deleted if a device as been removed from |devices|. 6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (devices->empty()) { 626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string label = request_it->first; 6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++request_it; 628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeleteRequest(label); 6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 6308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++request_it; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 6348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaStreamManager::CloseDevice(MediaStreamType type, int session_id) { 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "CloseDevice(" 637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "{type = " << type << "} " 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "{session_id = " << session_id << "})"; 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetDeviceManager(type)->Close(session_id); 6408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (DeviceRequests::iterator request_it = requests_.begin(); 6428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request_it != requests_.end() ; ++request_it) { 6438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StreamDeviceInfoArray* devices = &request_it->second->devices; 6448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 6458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) device_it != devices->end(); ++device_it) { 646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (device_it->session_id == session_id && 647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it->device.type == type) { 6488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Notify observers that this device is being closed. 6498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Note that only one device per type can be opened. 650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_it->second->SetState(type, MEDIA_REQUEST_STATE_CLOSING); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string MediaStreamManager::EnumerateDevices( 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamRequester* requester, 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_process_id, 659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ResourceContext::SaltCallback& sc, 6617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int page_request_id, 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamType type, 6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& security_origin) { 664effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(requester); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || 66746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) type == MEDIA_DEVICE_VIDEO_CAPTURE || 66846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) type == MEDIA_DEVICE_AUDIO_OUTPUT); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceRequest* request = new DeviceRequest(requester, 6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_process_id, 672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch render_frame_id, 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id, 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin, 675effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch false, // user gesture 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MEDIA_ENUMERATE_DEVICES, 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamOptions(), 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sc); 67946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT) 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetAudioType(type); 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (IsVideoMediaType(type)) 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetVideoType(type); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& label = AddRequest(request); 685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Post a task and handle the request asynchronously. The reason is that the 686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // requester won't have a label for the request until this function returns 687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // and thus can not handle a response. Using base::Unretained is safe since 688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // MediaStreamManager is deleted on the UI thread, after the IO thread has 689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // been stopped. 690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::PostTask( 691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MediaStreamManager::DoEnumerateDevices, 693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this), label)); 694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return label; 695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::DoEnumerateDevices(const std::string& label) { 698effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(label); 700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request) 701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; // This can happen if the request has been canceled. 702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 70346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) { 70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type()); 70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); 70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request->SetState(MEDIA_DEVICE_AUDIO_OUTPUT, MEDIA_REQUEST_STATE_REQUESTED); 70746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT] == 0) { 70846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT]; 70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_task_runner_->PostTask( 71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 71146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&MediaStreamManager::EnumerateAudioOutputDevices, 71246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this), 71346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) label)); 71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 71546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 71646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 71746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MediaStreamType type; 719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EnumerationCache* cache; 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE) { 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type()); 722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) type = MEDIA_DEVICE_AUDIO_CAPTURE; 723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cache = &audio_enumeration_cache_; 724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, request->video_type()); 72646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(MEDIA_NO_SERVICE, request->audio_type()); 727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) type = MEDIA_DEVICE_VIDEO_CAPTURE; 728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cache = &video_enumeration_cache_; 729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!EnumerationRequired(cache, type)) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cached device list of this type exists. Just send it out. 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); 734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->devices = cache->devices; 735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FinalizeEnumerateDevices(label, request); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartEnumeration(request); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Enumerate Devices ({label = " << label << "})"; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 742116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MediaStreamManager::EnumerateAudioOutputDevices(const std::string& label) { 74346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(device_task_runner_->BelongsToCurrentThread()); 74446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 74546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<media::AudioDeviceNames> device_names( 74646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new media::AudioDeviceNames()); 74746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) audio_manager_->GetAudioOutputDeviceNames(device_names.get()); 74846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) StreamDeviceInfoArray devices; 74946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (media::AudioDeviceNames::iterator it = device_names->begin(); 75046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it != device_names->end(); ++it) { 75146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_OUTPUT, 75246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it->device_name, 75346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it->unique_id); 75446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) devices.push_back(device); 75546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 75646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 75746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BrowserThread::PostTask( 75846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BrowserThread::IO, FROM_HERE, 75946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&MediaStreamManager::AudioOutputDevicesEnumerated, 76046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this), 76146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) devices)); 76246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 76346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void MediaStreamManager::AudioOutputDevicesEnumerated( 76546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const StreamDeviceInfoArray& devices) { 76646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_CURRENTLY_ON(BrowserThread::IO); 76746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DVLOG(1) << "AudioOutputDevicesEnumerated()"; 76846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 76946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string log_message = "New device enumeration result:\n" + 77046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetLogMessageString(MEDIA_DEVICE_AUDIO_OUTPUT, 77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) devices); 77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SendMessageToNativeLog(log_message); 77346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 77446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Publish the result for all requests waiting for device list(s). 77546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 77646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++it) { 77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (it->second->state(MEDIA_DEVICE_AUDIO_OUTPUT) == 77846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MEDIA_REQUEST_STATE_REQUESTED && 77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it->second->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) { 78046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(MEDIA_ENUMERATE_DEVICES, it->second->request_type); 78146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it->second->SetState(MEDIA_DEVICE_AUDIO_OUTPUT, 78246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MEDIA_REQUEST_STATE_PENDING_APPROVAL); 78346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it->second->devices = devices; 78446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FinalizeEnumerateDevices(it->first, it->second); 78546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 78646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 78746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 78846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) --active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT]; 78946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); 79046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 79146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, 7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_process_id, 794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ResourceContext::SaltCallback& sc, 7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int page_request_id, 7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& device_id, 7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType type, 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& security_origin) { 800effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type == MEDIA_DEVICE_VIDEO_CAPTURE); 8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})"; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamOptions options; 80546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsAudioInputMediaType(type)) { 8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.audio_requested = true; 8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.mandatory_audio.push_back( 8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (IsVideoMediaType(type)) { 8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.video_requested = true; 8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.mandatory_video.push_back( 8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceRequest* request = new DeviceRequest(requester, 8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_process_id, 818116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch render_frame_id, 8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_request_id, 8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) security_origin, 821effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch false, // user gesture 8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MEDIA_OPEN_DEVICE, 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options, 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sc); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& label = AddRequest(request); 827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Post a task and handle the request asynchronously. The reason is that the 828a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // requester won't have a label for the request until this function returns 829a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // and thus can not handle a response. Using base::Unretained is safe since 830a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // MediaStreamManager is deleted on the UI thread, after the IO thread has 831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // been stopped. 832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::PostTask( 833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 834a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MediaStreamManager::SetupRequest, 835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this), label)); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool MediaStreamManager::TranslateSourceIdToDeviceId( 8395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MediaStreamType stream_type, 8405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ResourceContext::SaltCallback& sc, 8415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL& security_origin, 8425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& source_id, 8435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::string* device_id) const { 8445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || 8455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); 8465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The source_id can be empty if the constraint is set but empty. 8475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (source_id.empty()) 8485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const EnumerationCache* cache = 8515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? 8525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &audio_enumeration_cache_ : &video_enumeration_cache_; 8535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If device monitoring hasn't started, the |device_guid| is not valid. 8555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!cache->valid) 8565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); 8595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != cache->devices.end(); 8605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++it) { 8615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (content::DoesMediaDeviceIDMatchHMAC(sc, security_origin, source_id, 8625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it->device.id)) { 8635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *device_id = it->device.id; 8645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 8655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 8695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::EnsureDeviceMonitorStarted() { 871effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartMonitoring(); 873f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 874f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaStreamManager::StopRemovedDevices( 876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const StreamDeviceInfoArray& old_devices, 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const StreamDeviceInfoArray& new_devices) { 878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "StopRemovedDevices(" 879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "{#old_devices = " << old_devices.size() << "} " 880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "{#new_devices = " << new_devices.size() << "})"; 881f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (StreamDeviceInfoArray::const_iterator old_dev_it = old_devices.begin(); 882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) old_dev_it != old_devices.end(); ++old_dev_it) { 883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool device_found = false; 8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamDeviceInfoArray::const_iterator new_dev_it = new_devices.begin(); 8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (; new_dev_it != new_devices.end(); ++new_dev_it) { 886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (old_dev_it->device.id == new_dev_it->device.id) { 887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_found = true; 888f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 889f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 890f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 891f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!device_found) { 893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // A device has been removed. We need to check if it is used by a 894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // MediaStream and in that case cleanup and notify the render process. 895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopRemovedDevice(old_dev_it->device); 896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 899f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { 901f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<int> session_ids; 902f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (DeviceRequests::const_iterator it = requests_.begin(); 903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != requests_.end() ; ++it) { 904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const DeviceRequest* request = it->second; 905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (StreamDeviceInfoArray::const_iterator device_it = 906f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request->devices.begin(); 907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it != request->devices.end(); ++device_it) { 908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string source_id = content::GetHMACForMediaDeviceID( 9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->salt_callback, 9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->security_origin, 911a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device.id); 912a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (device_it->device.id == source_id && 913a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_it->device.type == device.type) { 914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) session_ids.push_back(device_it->session_id); 915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->second->requester) { 916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it->second->requester->DeviceStopped( 917116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->second->requesting_frame_id, 918f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it->first, 919f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *device_it); 920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 921f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::vector<int>::const_iterator it = session_ids.begin(); 925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != session_ids.end(); ++it) { 926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopDevice(device.type, *it); 927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 928e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 929e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::ostringstream oss; 930e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch oss << "Media input device removed: type = " << 931e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch (device.type == MEDIA_DEVICE_AUDIO_CAPTURE ? "audio" : "video") << 932e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ", id = " << device.id << ", name = " << device.name; 933e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch AddLogMessageOnIOThread(oss.str()); 934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 935f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::StartMonitoring() { 937effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 9385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (monitoring_started_) 9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::SystemMonitor::Get()) 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitoring_started_ = true; 9455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::SystemMonitor::Get()->AddDevicesChangedObserver(this); 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Enumerate both the audio and video devices to cache the device lists 9485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and send them to media observer. 9495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE]; 9505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE); 9515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE]; 9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE); 953a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 954a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_MACOSX) 955a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::PostTask( 956a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 957a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&MediaStreamManager::StartMonitoringOnUIThread, 958a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this))); 959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_MACOSX) 963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamManager::StartMonitoringOnUIThread() { 964effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 965a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserMainLoop* browser_main_loop = content::BrowserMainLoop::GetInstance(); 9665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (browser_main_loop) { 9675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu browser_main_loop->device_monitor_mac() 9685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ->StartMonitoring(audio_manager_->GetWorkerTaskRunner()); 9695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 971a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 972a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::StopMonitoring() { 974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), io_loop_); 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (monitoring_started_) { 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitoring_started_ = false; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearEnumerationCache(&audio_enumeration_cache_); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearEnumerationCache(&video_enumeration_cache_); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaStreamManager::GetRequestedDeviceCaptureId( 9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const DeviceRequest* request, 9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType type, 9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* device_id) const { 9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || 9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) type == MEDIA_DEVICE_VIDEO_CAPTURE); 9895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StreamOptions::Constraints* mandatory = 9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (type == MEDIA_DEVICE_AUDIO_CAPTURE) ? 9915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &request->options.mandatory_audio : &request->options.mandatory_video; 9925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StreamOptions::Constraints* optional = 9935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (type == MEDIA_DEVICE_AUDIO_CAPTURE) ? 9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &request->options.optional_audio : &request->options.optional_video; 9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> source_ids; 9975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamOptions::GetConstraintsByName(*mandatory, 9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kMediaStreamSourceInfoId, &source_ids); 9995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (source_ids.size() > 1) { 10005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "Only one mandatory " << kMediaStreamSourceInfoId 10015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " is supported."; 10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1003a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If a specific device has been requested we need to find the real device 10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // id. 10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (source_ids.size() == 1 && 10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !TranslateSourceIdToDeviceId(type, 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->salt_callback, 10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->security_origin, 10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) source_ids[0], device_id)) { 10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << "Invalid mandatory " << kMediaStreamSourceInfoId 10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " = " << source_ids[0] << "."; 10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check for optional audio sourceIDs. 10165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (device_id->empty()) { 10175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StreamOptions::GetConstraintsByName(*optional, 10185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kMediaStreamSourceInfoId, 10195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &source_ids); 10205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Find the first sourceID that translates to device. Note that only one 10215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // device per type can call to GenerateStream is ever opened. 10225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<std::string>::const_iterator it = source_ids.begin(); 10235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != source_ids.end(); ++it) { 10245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (TranslateSourceIdToDeviceId(type, 10255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->salt_callback, 10265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->security_origin, 10275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *it, 10285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_id)) { 10295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 10305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1031a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1033a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 1034a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1035a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1036a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::TranslateDeviceIdToSourceId( 1037a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request, 1038a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MediaStreamDevice* device) { 10395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || 104046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || 10415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { 1042a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device->id = content::GetHMACForMediaDeviceID( 10435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->salt_callback, 10445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->security_origin, 1045a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device->id); 1046a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1047a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1048a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), io_loop_); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache->valid = false; 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, 10555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType stream_type) { 10565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), io_loop_); 10575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (stream_type == MEDIA_NO_SERVICE) 10585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 10595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || 10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); 10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) 10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There's no SystemMonitor on Android that notifies us when devices are 10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // added or removed, so we need to populate the cache on every request. 10665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Fortunately, there is an already up-to-date cache in the browser side 10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // audio manager that we can rely on, so the performance impact of 10685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // invalidating the cache like this, is minimal. 10695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (stream_type == MEDIA_DEVICE_AUDIO_CAPTURE) { 10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Make sure the cache is marked as invalid so that FinalizeEnumerateDevices 10715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will be called at the end of the enumeration. 10725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ClearEnumerationCache(cache); 10735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 10755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the cache isn't valid, we need to start a full enumeration. 10765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return !cache->valid; 10775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 10785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaStreamManager::StartEnumeration(DeviceRequest* request) { 1080effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start monitoring the devices when doing the first enumeration. 10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartMonitoring(); 10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start enumeration for devices of all requested device types. 10865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MediaStreamType streams[] = { request->audio_type(), 10875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->video_type() }; 10885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(streams); ++i) { 10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (streams[i] == MEDIA_NO_SERVICE) 10905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 10915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetState(streams[i], MEDIA_REQUEST_STATE_REQUESTED); 10925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_GE(active_enumeration_ref_count_[streams[i]], 0); 10935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (active_enumeration_ref_count_[streams[i]] == 0) { 10945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++active_enumeration_ref_count_[streams[i]]; 10955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetDeviceManager(streams[i])->EnumerateDevices(streams[i]); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string MediaStreamManager::AddRequest(DeviceRequest* request) { 1101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a label for this request and verify it is unique. 11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string unique_label; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unique_label = RandomLabel(); 11076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } while (FindRequest(unique_label) != NULL); 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) requests_.push_back(std::make_pair(unique_label, request)); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return unique_label; 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MediaStreamManager::DeviceRequest* 1115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MediaStreamManager::FindRequest(const std::string& label) const { 11166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) for (DeviceRequests::const_iterator request_it = requests_.begin(); 11176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) request_it != requests_.end(); ++request_it) { 11186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (request_it->first == label) 11196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return request_it->second; 11206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 11216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return NULL; 1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::DeleteRequest(const std::string& label) { 11255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "DeleteRequest({label= " << label << "})"; 11266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) for (DeviceRequests::iterator request_it = requests_.begin(); 11276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) request_it != requests_.end(); ++request_it) { 11286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (request_it->first == label) { 11296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<DeviceRequest> request(request_it->second); 11306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) requests_.erase(request_it); 11316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 11326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 11336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 11346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) NOTREACHED(); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::PostRequestToUI(const std::string& label, 1138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request) { 1139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 11405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(request->UIRequest()); 1141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "PostRequestToUI({label= " << label << "})"; 1142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MediaStreamType audio_type = request->audio_type(); 11445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MediaStreamType video_type = request->video_type(); 1145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Post the request to UI and set the state. 114746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsAudioInputMediaType(audio_type)) 1148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 1149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (IsVideoMediaType(video_type)) 1150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (use_fake_ui_) { 1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!fake_ui_) 1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fake_ui_.reset(new FakeMediaStreamUIProxy()); 1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MediaStreamDevices devices; 1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (audio_enumeration_cache_.valid) { 1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (StreamDeviceInfoArray::const_iterator it = 1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) audio_enumeration_cache_.devices.begin(); 1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != audio_enumeration_cache_.devices.end(); ++it) { 1161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) devices.push_back(it->device); 1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (video_enumeration_cache_.valid) { 1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (StreamDeviceInfoArray::const_iterator it = 1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) video_enumeration_cache_.devices.begin(); 1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it != video_enumeration_cache_.devices.end(); ++it) { 1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) devices.push_back(it->device); 1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fake_ui_->SetAvailableDevices(devices); 1173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->ui_proxy = fake_ui_.Pass(); 1175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->ui_proxy = MediaStreamUIProxy::Create(); 1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->ui_proxy->RequestAccess( 11805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *request->UIRequest(), 1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&MediaStreamManager::HandleAccessRequestResponse, 1182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), label)); 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::SetupRequest(const std::string& label) { 1186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(label); 1188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request) { 1189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "SetupRequest label " << label << " doesn't exist!!"; 1190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; // This can happen if the request has been canceled. 1191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!request->security_origin.is_valid()) { 1194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << "Invalid security origin. " 11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << request->security_origin; 1196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FinalizeRequestFailed(label, 1197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request, 1198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MEDIA_DEVICE_INVALID_SECURITY_ORIGIN); 1199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 1200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType audio_type = MEDIA_NO_SERVICE; 12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamType video_type = MEDIA_NO_SERVICE; 12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ParseStreamType(request->options, &audio_type, &video_type); 12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetAudioType(audio_type); 12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetVideoType(video_type); 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_web_contents_capture = 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_type == MEDIA_TAB_AUDIO_CAPTURE || 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_type == MEDIA_TAB_VIDEO_CAPTURE; 1211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (is_web_contents_capture && !SetupTabCaptureRequest(request)) { 1212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FinalizeRequestFailed(label, 1213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request, 1214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MEDIA_DEVICE_TAB_CAPTURE_FAILURE); 1215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 1216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool is_screen_capture = 1219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch video_type == MEDIA_DESKTOP_VIDEO_CAPTURE; 1220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (is_screen_capture && !SetupScreenCaptureRequest(request)) { 1221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FinalizeRequestFailed(label, 1222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request, 1223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE); 1224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 1225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS) 12281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EnsureKeyboardMicChecked(); 12291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 12301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 12315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!is_web_contents_capture && !is_screen_capture) { 12325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (EnumerationRequired(&audio_enumeration_cache_, audio_type) || 12335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EnumerationRequired(&video_enumeration_cache_, video_type)) { 12345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Enumerate the devices if there is no valid device lists to be used. 12355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartEnumeration(request); 12365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 12375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Cache is valid, so log the cached devices for MediaStream requests. 12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->request_type == MEDIA_GENERATE_STREAM) { 12405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string log_message("Using cached devices for request.\n"); 12415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (audio_type != MEDIA_NO_SERVICE) { 12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_message += 12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetLogMessageString(audio_type, audio_enumeration_cache_.devices); 12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (video_type != MEDIA_NO_SERVICE) { 12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_message += 12475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetLogMessageString(video_type, video_enumeration_cache_.devices); 12485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendMessageToNativeLog(log_message); 12505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!SetupDeviceCaptureRequest(request)) { 125423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FinalizeRequestFailed(label, request, MEDIA_DEVICE_NO_HARDWARE); 12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 12565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PostRequestToUI(label, request); 1259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaStreamManager::SetupDeviceCaptureRequest(DeviceRequest* request) { 12625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK((request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || 12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->audio_type() == MEDIA_NO_SERVICE) && 12645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE || 12655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->video_type() == MEDIA_NO_SERVICE)); 12665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string audio_device_id; 1267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (request->options.audio_requested && 1268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !GetRequestedDeviceCaptureId(request, request->audio_type(), 126923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &audio_device_id)) { 1270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string video_device_id; 1274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (request->options.video_requested && 1275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !GetRequestedDeviceCaptureId(request, request->video_type(), 1276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &video_device_id)) { 1277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 12785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->CreateUIRequest(audio_device_id, video_device_id); 12805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(3) << "Audio requested " << request->options.audio_requested 12815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " device id = " << audio_device_id 12825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Video requested " << request->options.video_requested 12835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " device id = " << video_device_id; 12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) { 12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(request->audio_type() == MEDIA_TAB_AUDIO_CAPTURE || 12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->video_type() == MEDIA_TAB_VIDEO_CAPTURE); 12905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string capture_device_id; 12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool mandatory_audio = false; 12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool mandatory_video = false; 12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!request->options.GetFirstAudioConstraintByName(kMediaStreamSourceId, 12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &capture_device_id, 12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &mandatory_audio) && 12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !request->options.GetFirstVideoConstraintByName(kMediaStreamSourceId, 12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &capture_device_id, 12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &mandatory_video)) { 13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(mandatory_audio || mandatory_video); 1303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Customize options for a WebContents based capture. 1305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int target_render_process_id = 0; 1306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int target_render_frame_id = 0; 1307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget( 1309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch capture_device_id, &target_render_process_id, &target_render_frame_id); 1310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!has_valid_device_id || 13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (request->audio_type() != MEDIA_TAB_AUDIO_CAPTURE && 13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->audio_type() != MEDIA_NO_SERVICE) || 13135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (request->video_type() != MEDIA_TAB_VIDEO_CAPTURE && 13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->video_type() != MEDIA_NO_SERVICE)) { 1315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 1316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 13175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->CreateTabCaptureUIRequest(target_render_process_id, 1319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch target_render_frame_id, 1320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch capture_device_id); 13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(3) << "SetupTabCaptureRequest " 1323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << ", {capture_device_id = " << capture_device_id << "}" 1324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << ", {target_render_process_id = " << target_render_process_id 1325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << "}" 1326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch << ", {target_render_frame_id = " << target_render_frame_id << "}"; 1327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 1328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) { 13315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(request->audio_type() == MEDIA_LOOPBACK_AUDIO_CAPTURE || 13325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->video_type() == MEDIA_DESKTOP_VIDEO_CAPTURE); 1333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // For screen capture we only support two valid combinations: 1335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // (1) screen video capture only, or 1336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // (2) screen video capture with loopback audio capture. 13375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->video_type() != MEDIA_DESKTOP_VIDEO_CAPTURE || 13385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (request->audio_type() != MEDIA_NO_SERVICE && 13395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->audio_type() != MEDIA_LOOPBACK_AUDIO_CAPTURE)) { 1340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << "Invalid screen capture request."; 1341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 1342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 13435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string video_device_id; 13455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->video_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) { 13465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string video_stream_source; 13475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool mandatory = false; 13485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!request->options.GetFirstVideoConstraintByName( 13495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kMediaStreamSource, 13505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &video_stream_source, 13515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &mandatory)) { 13525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << kMediaStreamSource << " not found."; 13535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 13545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(mandatory); 13565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (video_stream_source == kMediaStreamSourceDesktop) { 13585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!request->options.GetFirstVideoConstraintByName( 13595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kMediaStreamSourceId, 13605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &video_device_id, 13615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &mandatory)) { 13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << kMediaStreamSourceId << " not found."; 13635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 13645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(mandatory); 13665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->CreateUIRequest("", video_device_id); 1370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 1371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)StreamDeviceInfoArray MediaStreamManager::GetDevicesOpenedByRequest( 1374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& label) const { 1375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(label); 1376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request) 1377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return StreamDeviceInfoArray(); 1378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return request->devices; 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool MediaStreamManager::FindExistingRequestedDeviceInfo( 1382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const DeviceRequest& new_request, 1383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const MediaStreamDevice& new_device_info, 1384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamDeviceInfo* existing_device_info, 1385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MediaRequestState* existing_request_state) const { 1386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(existing_device_info); 1387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(existing_request_state); 1388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string source_id = content::GetHMACForMediaDeviceID( 13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_request.salt_callback, 13915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_request.security_origin, 1392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new_device_info.id); 1393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 13948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (DeviceRequests::const_iterator it = requests_.begin(); 13958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it != requests_.end() ; ++it) { 13968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const DeviceRequest* request = it->second; 1397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (request->requesting_process_id == new_request.requesting_process_id && 1398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requesting_frame_id == new_request.requesting_frame_id && 13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->request_type == new_request.request_type) { 14008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (StreamDeviceInfoArray::const_iterator device_it = 14018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->devices.begin(); 14028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) device_it != request->devices.end(); ++device_it) { 1403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (device_it->device.id == source_id && 1404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_it->device.type == new_device_info.type) { 14056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *existing_device_info = *device_it; 14066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Make sure that the audio |effects| reflect what the request 14076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // is set to and not what the capabilities are. 14086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FilterAudioEffects(request->options, 14096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &existing_device_info->device.input.effects); 14106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *existing_request_state = request->state(device_it->device.type); 14118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 14128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 14138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 14148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 14158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 14168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 14178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 14188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::FinalizeGenerateStream(const std::string& label, 1420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request) { 1421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "FinalizeGenerateStream label " << label; 1422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const StreamDeviceInfoArray& requested_devices = request->devices; 1423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Partition the array of devices into audio vs video. 1425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) StreamDeviceInfoArray audio_devices, video_devices; 1426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (StreamDeviceInfoArray::const_iterator device_it = 1427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) requested_devices.begin(); 1428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_it != requested_devices.end(); ++device_it) { 142946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsAudioInputMediaType(device_it->device.type)) { 1430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) audio_devices.push_back(*device_it); 1431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (IsVideoMediaType(device_it->device.type)) { 1432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) video_devices.push_back(*device_it); 1433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 1434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 1435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->requester->StreamGenerated( 1439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requesting_frame_id, 14405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->page_request_id, 14415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label, audio_devices, video_devices); 1442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::FinalizeRequestFailed( 1445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& label, 1446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceRequest* request, 1447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::MediaStreamRequestResult result) { 1448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (request->requester) 14495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->requester->StreamGenerationFailed( 1450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requesting_frame_id, 1451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->page_request_id, 1452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result); 1453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->request_type == MEDIA_DEVICE_ACCESS && 1455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !request->callback.is_null()) { 1456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass()); 1457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeleteRequest(label); 1460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::FinalizeOpenDevice(const std::string& label, 1463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request) { 1464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const StreamDeviceInfoArray& requested_devices = request->devices; 1465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requester->DeviceOpened(request->requesting_frame_id, 14665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->page_request_id, 14675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label, requested_devices.front()); 1468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, 1471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request) { 1472effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 14735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES); 14741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(((request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || 14751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) && 14761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->video_type() == MEDIA_NO_SERVICE) || 14771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (request->audio_type() == MEDIA_NO_SERVICE && 14781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE)); 14795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->security_origin.is_valid()) { 14815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (StreamDeviceInfoArray::iterator it = request->devices.begin(); 14825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != request->devices.end(); ++it) { 14835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TranslateDeviceIdToSourceId(request, &it->device); 14845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 14855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 14865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->devices.clear(); 1487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 14885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (use_fake_ui_) { 14901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!fake_ui_) 14911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fake_ui_.reset(new FakeMediaStreamUIProxy()); 14921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->ui_proxy = fake_ui_.Pass(); 14931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 14941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->ui_proxy = MediaStreamUIProxy::Create(); 14951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 14961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 14971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Output label permissions are based on input permission. 14981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MediaStreamType type = 14991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || 15001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT 15011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? MEDIA_DEVICE_AUDIO_CAPTURE 15021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : MEDIA_DEVICE_VIDEO_CAPTURE; 15031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 15041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->ui_proxy->CheckAccess( 15051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->security_origin, 15061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci type, 15071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->requesting_process_id, 15081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->requesting_frame_id, 15091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&MediaStreamManager::HandleCheckMediaAccessResponse, 15101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this), 15111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci label)); 15121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 15131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 15141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaStreamManager::HandleCheckMediaAccessResponse( 15151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& label, 15161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool have_access) { 15171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_CURRENTLY_ON(BrowserThread::IO); 15181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 15191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DeviceRequest* request = FindRequest(label); 15201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!request) { 15211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This can happen if the request was cancelled. 15221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << "The request with label " << label << " does not exist."; 15231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 15241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 15251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 15261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!have_access) 152746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ClearDeviceLabels(&request->devices); 152846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->requester->DevicesEnumerated( 1530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requesting_frame_id, 15315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->page_request_id, 15325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label, 15335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->devices); 15345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 15355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(tommi): 15365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ideally enumeration requests should be deleted once they have been served 15375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (as any request). However, this implementation mixes requests and 15385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // notifications together so enumeration requests are kept open by some 15395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // implementations (only Pepper?) and enumerations are done again when 15405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // device notifications are fired. 15415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Implementations that just want to request the device list and be done 15425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (e.g. DeviceRequestMessageFilter), they must (confusingly) call 15435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // CancelRequest() after the request has been fulfilled. This is not 15445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // obvious, not consistent in this class (see e.g. FinalizeMediaAccessRequest) 15455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and can lead to subtle bugs (requests not deleted at all deleted too 15465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // early). 15475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 15485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Basically, it is not clear that using requests as an additional layer on 15495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // top of device notifications is necessary or good. 15505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 15515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // To add to this, MediaStreamManager currently relies on the external 15525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // implementations of MediaStreamRequester to delete enumeration requests via 15535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // CancelRequest and e.g. DeviceRequestMessageFilter does this. However the 15545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pepper implementation does not seem to to this at all (and from what I can 15555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // see, it is the only implementation that uses an enumeration request as a 15565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // notification mechanism). 15575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 15585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We should decouple notifications from enumeration requests and once that 15595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // has been done, remove the requirement to call CancelRequest() to delete 15605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // enumeration requests and uncomment the following line: 15615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // DeleteRequest(label); 1563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaStreamManager::FinalizeMediaAccessRequest( 1566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& label, 1567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request, 1568a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const MediaStreamDevices& devices) { 1569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request->callback.is_null()) 1570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->callback.Run(devices, request->ui_proxy.Pass()); 1571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Delete the request since it is done. 1573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeleteRequest(label); 1574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaStreamManager::InitializeDeviceManagersOnIOThread() { 1577effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 15781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (device_task_runner_.get()) 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_task_runner_ = audio_manager_->GetWorkerTaskRunner(); 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_input_device_manager_ = new AudioInputDeviceManager(audio_manager_); 15845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_input_device_manager_->Register(this, device_task_runner_); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to be notified of IO message loop destruction to delete the thread 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the device managers. 1588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) io_loop_ = base::MessageLoop::current(); 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop_->AddDestructionObserver(this); 15905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 15915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 1592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switches::kUseFakeDeviceForMediaStream)) { 15935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu audio_input_device_manager()->UseFakeDevice(); 15945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 159646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) video_capture_manager_ = 159746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new VideoCaptureManager(media::VideoCaptureDeviceFactory::CreateFactory( 159846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI))); 15995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu video_capture_manager_->Register(this, device_task_runner_); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::Opened(MediaStreamType stream_type, 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int capture_session_id) { 1604effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 16058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DVLOG(1) << "Opened({stream_type = " << stream_type << "} " 16068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << "{capture_session_id = " << capture_session_id << "})"; 16078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Find the request(s) containing this device and mark it as used. 16088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // It can be used in several requests since the same device can be 16098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // requested from the same web page. 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DeviceRequests::iterator request_it = requests_.begin(); 16118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request_it != requests_.end(); ++request_it) { 16128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string& label = request_it->first; 16138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DeviceRequest* request = request_it->second; 16148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StreamDeviceInfoArray* devices = &(request->devices); 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_it != devices->end(); ++device_it) { 16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (device_it->device.type == stream_type && 1618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it->session_id == capture_session_id) { 1619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(request->state(device_it->device.type) == 1620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MEDIA_REQUEST_STATE_OPENING); 16218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // We've found a matching request. 16228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsAudioInputMediaType(device_it->device.type)) { 16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Store the native audio parameters in the device struct. 16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(xians): Handle the tab capture sample rate/channel layout 16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in AudioInputDeviceManager::Open(). 16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { 16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StreamDeviceInfo* info = 16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_input_device_manager_->GetOpenedDeviceInfoById( 16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_it->session_id); 163258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_it->device.input = info->device.input; 16336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 16346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Since the audio input device manager will set the input 16356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // parameters to the default settings (including supported effects), 16366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // we need to adjust those settings here according to what the 16376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // request asks for. 16386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FilterAudioEffects(request->options, 16396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &device_it->device.input.effects); 16406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 164158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_it->device.matched_output = info->device.matched_output; 16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 16438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 16448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (RequestDone(*request)) 16458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) HandleRequestDone(label, request); 16468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 16478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 16488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 16498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 16508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 16518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 16528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void MediaStreamManager::HandleRequestDone(const std::string& label, 16538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DeviceRequest* request) { 16548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(RequestDone(*request)); 16558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DVLOG(1) << "HandleRequestDone(" 16568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", {label = " << label << "})"; 16578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 16585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (request->request_type) { 16598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case MEDIA_OPEN_DEVICE: 1660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FinalizeOpenDevice(label, request); 16618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 16628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case MEDIA_GENERATE_STREAM: { 1663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FinalizeGenerateStream(label, request); 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 16718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (request->ui_proxy.get()) { 16728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->ui_proxy->OnStarted( 1673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&MediaStreamManager::StopMediaStreamFromBrowser, 1674effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Unretained(this), 1675effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch label), 1676effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&MediaStreamManager::OnMediaStreamUIWindowId, 1677effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Unretained(this), 1678effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request->video_type(), 1679effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request->devices)); 16808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::Closed(MediaStreamType stream_type, 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int capture_session_id) { 1685effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::DevicesEnumerated( 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { 1690effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "DevicesEnumerated(" 16925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "{stream_type = " << stream_type << "})" << std::endl; 16935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 16945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string log_message = "New device enumeration result:\n" + 16955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetLogMessageString(stream_type, devices); 16965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendMessageToNativeLog(log_message); 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only cache the device list when the device list has been changed. 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool need_update_clients = false; 17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnumerationCache* cache = 17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? 17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &audio_enumeration_cache_ : &video_enumeration_cache_; 17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cache->valid || 17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) devices.size() != cache->devices.size() || 17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StreamDeviceInfo::IsEqual)) { 1707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopRemovedDevices(cache->devices, devices); 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache->devices = devices; 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_update_clients = true; 1710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The device might not be able to be enumerated when it is not warmed up, 1712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // for example, when the machine just wakes up from sleep. We set the cache 1713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // to be invalid so that the next media request will trigger the 1714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // enumeration again. See issue/317673. 1715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cache->valid = !devices.empty(); 17166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (need_update_clients && monitoring_started_) 17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyDevicesChanged(stream_type, devices); 17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Publish the result for all requests waiting for device list(s). 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the requests waiting for this device list, store their labels and 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release the iterator before calling device settings. We might get a call 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // back from device_settings that will need to iterate through devices. 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::string> label_list; 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 1728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it->second->state(stream_type) == MEDIA_REQUEST_STATE_REQUESTED && 17295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (it->second->audio_type() == stream_type || 17305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->second->video_type() == stream_type)) { 17315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (it->second->request_type != MEDIA_ENUMERATE_DEVICES) 17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_list.push_back(it->first); 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::list<std::string>::iterator it = label_list.begin(); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != label_list.end(); ++it) { 1739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(*it); 17405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (request->request_type) { 17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case MEDIA_ENUMERATE_DEVICES: 1742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (need_update_clients && request->requester) { 1743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->devices = devices; 1744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FinalizeEnumerateDevices(*it, request); 1745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 17485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->state(request->audio_type()) == 17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_REQUEST_STATE_REQUESTED || 17505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->state(request->video_type()) == 17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_REQUEST_STATE_REQUESTED) { 17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We are doing enumeration for other type of media, wait until it is 17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // all done before posting the request to UI because UI needs 17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the device lists to handle the request. 17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1757a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!SetupDeviceCaptureRequest(request)) { 1758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FinalizeRequestFailed(*it, 1759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request, 176023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) MEDIA_DEVICE_NO_HARDWARE); 1761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 17625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PostRequestToUI(*it, request); 1763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_list.clear(); 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --active_enumeration_ref_count_[stream_type]; 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid MediaStreamManager::Aborted(MediaStreamType stream_type, 17735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int capture_session_id) { 17745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK_CURRENTLY_ON(BrowserThread::IO); 17755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DVLOG(1) << "Aborted({stream_type = " << stream_type << "} " 17765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << "{capture_session_id = " << capture_session_id << "})"; 17775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu StopDevice(stream_type, capture_session_id); 17785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 17795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 17815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamManager::SendMessageToNativeLog(const std::string& message) { 17825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 17835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 17845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(DoAddLogMessage, message)); 17855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 17865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1787effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid MediaStreamManager::OnSuspend() { 1788effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SendMessageToNativeLog("Power state suspended."); 1789effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1790effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1791effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid MediaStreamManager::OnResume() { 1792effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SendMessageToNativeLog("Power state resumed."); 1793effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1794effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 17955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamManager::AddLogMessageOnIOThread(const std::string& message) { 17965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Get render process ids on the IO thread. 1797effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 17985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 17995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Grab all unique process ids that request a MediaStream or have a 18005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // MediaStream running. 18015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<int> requesting_process_ids; 18025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (DeviceRequests::const_iterator it = requests_.begin(); 18035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != requests_.end(); ++it) { 18045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceRequest* request = it->second; 18055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->request_type == MEDIA_GENERATE_STREAM) 18065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requesting_process_ids.insert(request->requesting_process_id); 18075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 18085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // MediaStreamManager is a singleton in BrowserMainLoop, which owns the UI 18105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // thread. MediaStreamManager has the same lifetime as the UI thread, so it is 18115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // safe to use base::Unretained. 18125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 18135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, 18145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 18155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&MediaStreamManager::AddLogMessageOnUIThread, 18165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 18175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requesting_process_ids, 18185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message)); 18195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 18205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamManager::AddLogMessageOnUIThread( 18225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::set<int>& requesting_process_ids, 18235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& message) { 18245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(ENABLE_WEBRTC) 18255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Must be on the UI thread to access RenderProcessHost from process ID. 1826effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 18275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::set<int>::const_iterator it = requesting_process_ids.begin(); 18295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != requesting_process_ids.end(); ++it) { 18305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Log the message to all renderers that are requesting a MediaStream or 18315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // have a MediaStream running. 18325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderProcessHostImpl* render_process_host_impl = 18335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<content::RenderProcessHostImpl*>( 18345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderProcessHost::FromID(*it)); 18355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (render_process_host_impl) 18365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_process_host_impl->WebRtcLogMessage(message); 18375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 18385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 18395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 18405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaStreamManager::HandleAccessRequestResponse( 1842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& label, 1843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const MediaStreamDevices& devices, 1844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::MediaStreamRequestResult result) { 1845effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 18468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DVLOG(1) << "HandleAccessRequestResponse(" 18478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", {label = " << label << "})"; 1848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(label); 1850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request) { 1851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The request has been canceled before the UI returned. 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->request_type == MEDIA_DEVICE_ACCESS) { 1856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FinalizeMediaAccessRequest(label, request, devices); 1857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Handle the case when the request was denied. 1861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result != MEDIA_DEVICE_OK) { 1862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FinalizeRequestFailed(label, request, result); 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(!devices.empty()); 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process all newly-accepted devices for this request. 1868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found_audio = false; 1869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool found_video = false; 1870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (MediaStreamDevices::const_iterator device_it = devices.begin(); 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_it != devices.end(); ++device_it) { 1872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StreamDeviceInfo device_info; 1873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) device_info.device = *device_it; 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || 18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { 18775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_info.device.id = request->UIRequest()->tab_capture_device_id; 18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialize the sample_rate and channel_layout here since for audio 18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // mirroring, we don't go through EnumerateDevices where these are usually 18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // initialized. 18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const media::AudioParameters parameters = 18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_manager_->GetDefaultOutputStreamParameters(); 18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int sample_rate = parameters.sample_rate(); 18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we weren't able to get the native sampling rate or the sample_rate 18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is outside the valid range for input devices set reasonable defaults. 18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sample_rate <= 0 || sample_rate > 96000) 18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sample_rate = 44100; 18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 189158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_info.device.input.sample_rate = sample_rate; 189258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_info.device.input.channel_layout = media::CHANNEL_LAYOUT_STEREO; 18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (device_info.device.type == request->audio_type()) { 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_audio = true; 18985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (device_info.device.type == request->video_type()) { 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_video = true; 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 19028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If this is request for a new MediaStream, a device is only opened once 1903116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // per render frame. This is so that the permission to use a device can be 19048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // revoked by a single call to StopStreamDevice regardless of how many 19058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // MediaStreams it is being used in. 19065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->request_type == MEDIA_GENERATE_STREAM) { 19078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MediaRequestState state; 1908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (FindExistingRequestedDeviceInfo(*request, 1909a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_info.device, 19108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &device_info, 19118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &state)) { 19128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->devices.push_back(device_info); 19138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->SetState(device_info.device.type, state); 19148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DVLOG(1) << "HandleAccessRequestResponse - device already opened " 1915a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << ", {label = " << label << "}" 1916a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << ", device_id = " << device_it->id << "}"; 19178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) continue; 19188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 19198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 19208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) device_info.session_id = 19218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetDeviceManager(device_info.device.type)->Open(device_info); 1922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TranslateDeviceIdToSourceId(request, &device_info.device); 19238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->devices.push_back(device_info); 1924a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 19258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); 19268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DVLOG(1) << "HandleAccessRequestResponse - opening device " 19278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", {label = " << label << "}" 1928a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << ", {device_id = " << device_info.device.id << "}" 19298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << ", {session_id = " << device_info.session_id << "}"; 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check whether we've received all stream types requested. 193346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!found_audio && IsAudioInputMediaType(request->audio_type())) { 19345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetState(request->audio_type(), MEDIA_REQUEST_STATE_ERROR); 19358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DVLOG(1) << "Set no audio found label " << label; 19368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!found_video && IsVideoMediaType(request->video_type())) 19395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->SetState(request->video_type(), MEDIA_REQUEST_STATE_ERROR); 19408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 19418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (RequestDone(*request)) 19428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) HandleRequestDone(label, request); 19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaStreamManager::StopMediaStreamFromBrowser(const std::string& label) { 1946effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceRequest* request = FindRequest(label); 1949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!request) 19502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Notify renderers that the devices in the stream will be stopped. 19530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (request->requester) { 1954f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); 1955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_it != request->devices.end(); ++device_it) { 1956116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request->requester->DeviceStopped(request->requesting_frame_id, 1957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) label, 1958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *device_it); 1959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 19600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 19612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CancelRequest(label); 19632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 19642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) { 1966effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) use_fake_ui_ = true; 1968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fake_ui_ = fake_ui.Pass(); 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::WillDestroyCurrentMessageLoop() { 1972a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()"; 1973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), io_loop_); 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(requests_.empty()); 19751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (device_task_runner_.get()) { 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopMonitoring(); 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_capture_manager_->Unregister(); 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_input_device_manager_->Unregister(); 19805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_task_runner_ = NULL; 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_input_device_manager_ = NULL; 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_capture_manager_ = NULL; 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaStreamManager::NotifyDevicesChanged( 19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaStreamType stream_type, 19892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StreamDeviceInfoArray& devices) { 1990effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 19912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaObserver* media_observer = 19922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetContentClient()->browser()->GetMediaObserver(); 19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Map the devices to MediaStreamDevices. 19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaStreamDevices new_devices; 19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (StreamDeviceInfoArray::const_iterator it = devices.begin(); 19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != devices.end(); ++it) { 19982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_devices.push_back(it->device); 19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 20002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 200146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsAudioInputMediaType(stream_type)) { 2002a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MediaCaptureDevicesImpl::GetInstance()->OnAudioCaptureDevicesChanged( 2003a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new_devices); 20040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (media_observer) 20050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch media_observer->OnAudioCaptureDevicesChanged(); 20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (IsVideoMediaType(stream_type)) { 2007a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MediaCaptureDevicesImpl::GetInstance()->OnVideoCaptureDevicesChanged( 2008a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new_devices); 20090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (media_observer) 20100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch media_observer->OnVideoCaptureDevicesChanged(); 20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 2017effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 201946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const bool requested_audio = IsAudioInputMediaType(request.audio_type()); 20205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool requested_video = IsVideoMediaType(request.video_type()); 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool audio_done = 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !requested_audio || 20245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request.state(request.audio_type()) == MEDIA_REQUEST_STATE_DONE || 20255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request.state(request.audio_type()) == MEDIA_REQUEST_STATE_ERROR; 20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!audio_done) 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool video_done = 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !requested_video || 20315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request.state(request.video_type()) == MEDIA_REQUEST_STATE_DONE || 20325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request.state(request.video_type()) == MEDIA_REQUEST_STATE_ERROR; 20332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!video_done) 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamProvider* MediaStreamManager::GetDeviceManager( 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamType stream_type) { 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsVideoMediaType(stream_type)) { 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return video_capture_manager(); 204346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else if (IsAudioInputMediaType(stream_type)) { 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return audio_input_device_manager(); 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamManager::OnDevicesChanged( 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SystemMonitor::DeviceType device_type) { 2052effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: This method is only called in response to physical audio/video device 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changes (from the operating system). 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamType stream_type; 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_type = MEDIA_DEVICE_AUDIO_CAPTURE; 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_type = MEDIA_DEVICE_VIDEO_CAPTURE; 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Uninteresting device change. 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always do enumeration even though some enumeration is in progress, 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because those enumeration commands could be sent before these devices 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change. 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++active_enumeration_ref_count_[stream_type]; 20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDeviceManager(stream_type)->EnumerateDevices(stream_type); 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2073effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid MediaStreamManager::OnMediaStreamUIWindowId(MediaStreamType video_type, 2074effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch StreamDeviceInfoArray devices, 2075effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch gfx::NativeViewId window_id) { 2076effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2077effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!window_id) 2078effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 2079effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2080effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Pass along for desktop capturing. Ignored for other stream types. 2081effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (video_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { 2082effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (StreamDeviceInfoArray::iterator it = devices.begin(); 2083effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch it != devices.end(); 2084effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++it) { 2085effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { 2086effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_capture_manager_->SetDesktopCaptureWindowId(it->session_id, 2087effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch window_id); 2088effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 2089effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 2090effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 2091effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 2092effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 2093effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 20941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_CHROMEOS) 20951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaStreamManager::EnsureKeyboardMicChecked() { 20961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_CURRENTLY_ON(BrowserThread::IO); 20971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!has_checked_keyboard_mic_) { 20981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci has_checked_keyboard_mic_ = true; 20991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::PostTask( 21001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::UI, FROM_HERE, 21011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&MediaStreamManager::CheckKeyboardMicOnUIThread, 21021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this))); 21031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 21041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 21051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 21061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaStreamManager::CheckKeyboardMicOnUIThread() { 21071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_CURRENTLY_ON(BrowserThread::UI); 21081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 21091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // We will post this on the device thread before the media media access 21101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // request is posted on the UI thread, so setting the keyboard mic info will 21111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // be done before any stream is created. 21121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (chromeos::CrasAudioHandler::Get()->HasKeyboardMic()) { 21131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci device_task_runner_->PostTask( 21141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 21151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&MediaStreamManager::SetKeyboardMicOnDeviceThread, 21161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this))); 21171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 21181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 21191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 21201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MediaStreamManager::SetKeyboardMicOnDeviceThread() { 21211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(device_task_runner_->BelongsToCurrentThread()); 21221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_manager_->SetHasKeyboardMic(); 21231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 21241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 21251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 2127