[MacViews] Show comboboxes with a native NSMenu
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_manager.h
blob9dad60503f06cb17f71604c406dcf1463a48cf02
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // MediaStreamManager is used to open/enumerate media capture devices (video
6 // supported now). Call flow:
7 // 1. GenerateStream is called when a render process wants to use a capture
8 // device.
9 // 2. MediaStreamManager will ask MediaStreamUIController for permission to
10 // use devices and for which device to use.
11 // 3. MediaStreamManager will request the corresponding media device manager(s)
12 // to enumerate available devices. The result will be given to
13 // MediaStreamUIController.
14 // 4. MediaStreamUIController will, by posting the request to UI, let the
15 // users to select which devices to use and send callback to
16 // MediaStreamManager with the result.
17 // 5. MediaStreamManager will call the proper media device manager to open the
18 // device and let the MediaStreamRequester know it has been done.
20 // If either user or test harness selects --use-fake-device-for-media-stream,
21 // a fake video device or devices are used instead of real ones.
23 // When enumeration and open are done in separate operations,
24 // MediaStreamUIController is not involved as in steps.
26 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_
27 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_
29 #include <list>
30 #include <set>
31 #include <string>
32 #include <utility>
34 #include "base/basictypes.h"
35 #include "base/memory/ref_counted.h"
36 #include "base/memory/scoped_ptr.h"
37 #include "base/message_loop/message_loop.h"
38 #include "base/power_monitor/power_observer.h"
39 #include "base/system_monitor/system_monitor.h"
40 #include "base/threading/thread.h"
41 #include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
42 #include "content/browser/renderer_host/media/media_stream_provider.h"
43 #include "content/common/content_export.h"
44 #include "content/common/media/media_stream_options.h"
45 #include "content/public/browser/media_request_state.h"
46 #include "content/public/browser/resource_context.h"
48 namespace media {
49 class AudioManager;
52 namespace content {
54 class AudioInputDeviceManager;
55 class AudioOutputDeviceEnumerator;
56 class BrowserContext;
57 class FakeMediaStreamUIProxy;
58 class MediaStreamDeviceSettings;
59 class MediaStreamRequester;
60 class MediaStreamUIProxy;
61 class VideoCaptureManager;
63 // MediaStreamManager is used to generate and close new media devices, not to
64 // start the media flow. The classes requesting new media streams are answered
65 // using MediaStreamRequester.
66 class CONTENT_EXPORT MediaStreamManager
67 : public MediaStreamProviderListener,
68 public base::MessageLoop::DestructionObserver,
69 public base::PowerObserver,
70 public base::SystemMonitor::DevicesChangedObserver {
71 public:
72 // Callback to deliver the result of a media request.
73 typedef base::Callback<void(const MediaStreamDevices& devices,
74 scoped_ptr<MediaStreamUIProxy> ui)>
75 MediaRequestResponseCallback;
77 // Adds |message| to native logs for outstanding device requests, for use by
78 // render processes hosts whose corresponding render processes are requesting
79 // logging from webrtcLoggingPrivate API. Safe to call from any thread.
80 static void SendMessageToNativeLog(const std::string& message);
82 explicit MediaStreamManager(media::AudioManager* audio_manager);
84 ~MediaStreamManager() override;
86 // Used to access VideoCaptureManager.
87 VideoCaptureManager* video_capture_manager();
89 // Used to access AudioInputDeviceManager.
90 AudioInputDeviceManager* audio_input_device_manager();
92 // Used to access AudioOutputDeviceEnumerator.
93 AudioOutputDeviceEnumerator* audio_output_device_enumerator();
95 // Creates a new media access request which is identified by a unique string
96 // that's returned to the caller. This will trigger the infobar and ask users
97 // for access to the device. |render_process_id| and |render_frame_id| are
98 // used to determine where the infobar will appear to the user. |callback| is
99 // used to send the selected device to the clients. An empty list of device
100 // will be returned if the users deny the access.
101 std::string MakeMediaAccessRequest(
102 int render_process_id,
103 int render_frame_id,
104 int page_request_id,
105 const StreamOptions& options,
106 const GURL& security_origin,
107 const MediaRequestResponseCallback& callback);
109 // GenerateStream opens new media devices according to |components|. It
110 // creates a new request which is identified by a unique string that's
111 // returned to the caller. |render_process_id| and |render_frame_id| are used
112 // to determine where the infobar will appear to the user.
113 void GenerateStream(MediaStreamRequester* requester,
114 int render_process_id,
115 int render_frame_id,
116 const ResourceContext::SaltCallback& sc,
117 int page_request_id,
118 const StreamOptions& components,
119 const GURL& security_origin,
120 bool user_gesture);
122 void CancelRequest(int render_process_id,
123 int render_frame_id,
124 int page_request_id);
126 // Cancel an open request identified by |label|.
127 virtual void CancelRequest(const std::string& label);
129 // Cancel all requests for the given |render_process_id|.
130 void CancelAllRequests(int render_process_id);
132 // Closes the stream device for a certain render frame. The stream must have
133 // been opened by a call to GenerateStream.
134 void StopStreamDevice(int render_process_id,
135 int render_frame_id,
136 const std::string& device_id);
138 // Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE
139 // or MEDIA_DEVICE_VIDEO_CAPTURE.
140 // The request is identified using the string returned to the caller.
141 // When the |requester| is NULL, MediaStreamManager will enumerate both audio
142 // and video devices and also start monitoring device changes, such as
143 // plug/unplug. The new device lists will be delivered via media observer to
144 // MediaCaptureDevicesDispatcher.
145 virtual std::string EnumerateDevices(MediaStreamRequester* requester,
146 int render_process_id,
147 int render_frame_id,
148 const ResourceContext::SaltCallback& sc,
149 int page_request_id,
150 MediaStreamType type,
151 const GURL& security_origin);
153 // Open a device identified by |device_id|. |type| must be either
154 // MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
155 // The request is identified using string returned to the caller.
156 void OpenDevice(MediaStreamRequester* requester,
157 int render_process_id,
158 int render_frame_id,
159 const ResourceContext::SaltCallback& sc,
160 int page_request_id,
161 const std::string& device_id,
162 MediaStreamType type,
163 const GURL& security_origin);
165 // Finds and returns the device id corresponding to the given
166 // |source_id|. Returns true if there was a raw device id that matched the
167 // given |source_id|, false if nothing matched it.
168 bool TranslateSourceIdToDeviceId(MediaStreamType stream_type,
169 const ResourceContext::SaltCallback& rc,
170 const GURL& security_origin,
171 const std::string& source_id,
172 std::string* device_id) const;
174 // Called by UI to make sure the device monitor is started so that UI receive
175 // notifications about device changes.
176 void EnsureDeviceMonitorStarted();
178 // Implements MediaStreamProviderListener.
179 void Opened(MediaStreamType stream_type, int capture_session_id) override;
180 void Closed(MediaStreamType stream_type, int capture_session_id) override;
181 void DevicesEnumerated(MediaStreamType stream_type,
182 const StreamDeviceInfoArray& devices) override;
183 void Aborted(MediaStreamType stream_type, int capture_session_id) override;
185 // Implements base::SystemMonitor::DevicesChangedObserver.
186 void OnDevicesChanged(base::SystemMonitor::DeviceType device_type) override;
188 // Returns all devices currently opened by a request with label |label|.
189 // If no request with |label| exist, an empty array is returned.
190 StreamDeviceInfoArray GetDevicesOpenedByRequest(
191 const std::string& label) const;
193 // This object gets deleted on the UI thread after the IO thread has been
194 // destroyed. So we need to know when IO thread is being destroyed so that
195 // we can delete VideoCaptureManager and AudioInputDeviceManager. Normally
196 // this is handled by
197 // base::MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop.
198 // But for some tests which use TestBrowserThreadBundle, we need to call
199 // WillDestroyCurrentMessageLoop explicitly because the notification happens
200 // too late. (see http://crbug.com/247525#c14).
201 void WillDestroyCurrentMessageLoop() override;
203 // Sends log messages to the render process hosts whose corresponding render
204 // processes are making device requests, to be used by the
205 // webrtcLoggingPrivate API if requested.
206 void AddLogMessageOnIOThread(const std::string& message);
208 // base::PowerObserver overrides.
209 void OnSuspend() override;
210 void OnResume() override;
212 // Called by the tests to specify a fake UI that should be used for next
213 // generated stream (or when using --use-fake-ui-for-media-stream).
214 void UseFakeUIForTests(scoped_ptr<FakeMediaStreamUIProxy> fake_ui);
216 private:
217 // Contains all data needed to keep track of requests.
218 class DeviceRequest;
220 // Cache enumerated device list.
221 struct EnumerationCache {
222 EnumerationCache();
223 ~EnumerationCache();
225 bool valid;
226 StreamDeviceInfoArray devices;
229 // |DeviceRequests| is a list to ensure requests are processed in the order
230 // they arrive. The first member of the pair is the label of the
231 // |DeviceRequest|.
232 using LabeledDeviceRequest = std::pair<std::string, DeviceRequest*>;
233 using DeviceRequests = std::list<LabeledDeviceRequest>;
235 // Initializes the device managers on IO thread. Auto-starts the device
236 // thread and registers this as a listener with the device managers.
237 void InitializeDeviceManagersOnIOThread();
239 // Helper for sending up-to-date device lists to media observer when a
240 // capture device is plugged in or unplugged.
241 void NotifyDevicesChanged(MediaStreamType stream_type,
242 const StreamDeviceInfoArray& devices);
244 void HandleAccessRequestResponse(const std::string& label,
245 const MediaStreamDevices& devices,
246 content::MediaStreamRequestResult result);
247 void StopMediaStreamFromBrowser(const std::string& label);
249 void DoEnumerateDevices(const std::string& label);
251 void AudioOutputDevicesEnumerated(
252 const AudioOutputDeviceEnumeration& device_enumeration);
254 // Helpers.
255 // Checks if all devices that was requested in the request identififed by
256 // |label| has been opened and set the request state accordingly.
257 void HandleRequestDone(const std::string& label,
258 DeviceRequest* request);
259 // Stop the use of the device associated with |session_id| of type |type| in
260 // all |requests_|. The device is removed from the request. If a request
261 /// doesn't use any devices as a consequence, the request is deleted.
262 void StopDevice(MediaStreamType type, int session_id);
263 // Calls the correct capture manager and close the device with |session_id|.
264 // All requests that uses the device are updated.
265 void CloseDevice(MediaStreamType type, int session_id);
266 // Returns true if a request for devices has been completed and the devices
267 // has either been opened or an error has occurred.
268 bool RequestDone(const DeviceRequest& request) const;
269 MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type);
270 void StartEnumeration(DeviceRequest* request);
271 std::string AddRequest(DeviceRequest* request);
272 DeviceRequest* FindRequest(const std::string& label) const;
273 void DeleteRequest(const std::string& label);
274 void ClearEnumerationCache(EnumerationCache* cache);
275 // Returns true if the |cache| is invalid, false if it's invalid or if
276 // the |stream_type| is MEDIA_NO_SERVICE.
277 // On Android, this function will always return true for
278 // MEDIA_DEVICE_AUDIO_CAPTURE since we don't have a SystemMonitor to tell
279 // us about audio device changes.
280 bool EnumerationRequired(EnumerationCache* cache, MediaStreamType type);
281 // Prepare the request with label |label| by starting device enumeration if
282 // needed.
283 void SetupRequest(const std::string& label);
284 // Prepare |request| of type MEDIA_DEVICE_AUDIO_CAPTURE and/or
285 // MEDIA_DEVICE_VIDEO_CAPTURE for being posted to the UI by parsing
286 // StreamOptions::Constraints for requested device IDs.
287 bool SetupDeviceCaptureRequest(DeviceRequest* request);
288 // Prepare |request| of type MEDIA_TAB_AUDIO_CAPTURE and/or
289 // MEDIA_TAB_VIDEO_CAPTURE for being posted to the UI by parsing
290 // StreamOptions::Constraints for requested tab capture IDs.
291 bool SetupTabCaptureRequest(DeviceRequest* request);
292 // Prepare |request| of type MEDIA_DESKTOP_AUDIO_CAPTURE and/or
293 // MEDIA_DESKTOP_VIDEO_CAPTURE for being posted to the UI by parsing
294 // StreamOptions::Constraints for the requested desktop ID.
295 bool SetupScreenCaptureRequest(DeviceRequest* request);
296 // Called when a request has been setup and devices have been enumerated if
297 // needed.
298 void PostRequestToUI(const std::string& label, DeviceRequest* request);
299 // Returns true if a device with |device_id| has already been requested with
300 // a render procecss_id and render_frame_id and type equal to the the values
301 // in |request|. If it has been requested, |device_info| contain information
302 // about the device.
303 bool FindExistingRequestedDeviceInfo(
304 const DeviceRequest& new_request,
305 const MediaStreamDevice& new_device_info,
306 StreamDeviceInfo* existing_device_info,
307 MediaRequestState* existing_request_state) const;
309 void FinalizeGenerateStream(const std::string& label, DeviceRequest* request);
310 void FinalizeRequestFailed(const std::string& label,
311 DeviceRequest* request,
312 content::MediaStreamRequestResult result);
313 void FinalizeOpenDevice(const std::string& label, DeviceRequest* request);
314 void FinalizeMediaAccessRequest(const std::string& label,
315 DeviceRequest* request,
316 const MediaStreamDevices& devices);
317 void FinalizeEnumerateDevices(const std::string& label,
318 DeviceRequest* request);
319 void HandleCheckMediaAccessResponse(const std::string& label,
320 bool have_access);
322 // This method is called when an audio or video device is plugged in or
323 // removed. It make sure all MediaStreams that use a removed device is
324 // stopped and that the render process is notified. |old_devices| is the list
325 // of previously available devices. |new_devices| is the new
326 // list of currently available devices.
327 void StopRemovedDevices(const StreamDeviceInfoArray& old_devices,
328 const StreamDeviceInfoArray& new_devices);
329 // Helper method used by StopRemovedDevices to stop the use of a certain
330 // device.
331 void StopRemovedDevice(const MediaStreamDevice& device);
333 // Helpers to start and stop monitoring devices.
334 void StartMonitoring();
335 void StopMonitoring();
336 #if defined(OS_MACOSX)
337 void StartMonitoringOnUIThread();
338 #endif
340 // Finds the requested device id from constraints. The requested device type
341 // must be MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
342 bool GetRequestedDeviceCaptureId(const DeviceRequest* request,
343 MediaStreamType type,
344 std::string* device_id) const;
346 void TranslateDeviceIdToSourceId(DeviceRequest* request,
347 MediaStreamDevice* device);
349 // Handles the callback from MediaStreamUIProxy to receive the UI window id,
350 // used for excluding the notification window in desktop capturing.
351 void OnMediaStreamUIWindowId(MediaStreamType video_type,
352 StreamDeviceInfoArray devices,
353 gfx::NativeViewId window_id);
355 #if defined(OS_CHROMEOS)
356 // Ensures that we have checked for presence of a keyboard mic. This is only
357 // done once. This function should be called before posting a request on the
358 // UI thread.
359 void EnsureKeyboardMicChecked();
361 // Checks if the system has a keyboard mic, and if so, inform the audio
362 // manager via SetKeyboardMicOnDeviceThread().
363 void CheckKeyboardMicOnUIThread();
365 // Tells the audio mananger that the system supports a keyboard mic.
366 void SetKeyboardMicOnDeviceThread();
367 #endif
369 // Task runner shared by VideoCaptureManager and AudioInputDeviceManager and
370 // used for enumerating audio output devices.
371 // Note: Enumeration tasks may take seconds to complete so must never be run
372 // on any of the BrowserThreads (UI, IO, etc). See http://crbug.com/256945.
373 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
375 media::AudioManager* const audio_manager_; // not owned
376 scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
377 scoped_refptr<VideoCaptureManager> video_capture_manager_;
378 scoped_ptr<AudioOutputDeviceEnumerator> audio_output_device_enumerator_;
379 #if defined(OS_WIN)
380 base::Thread video_capture_thread_;
381 #endif
383 // Indicator of device monitoring state.
384 bool monitoring_started_;
386 #if defined(OS_CHROMEOS)
387 // Flag that's set when we have checked if the system has a keyboard mic. We
388 // only need to check it once, and not when constructing since that will
389 // affect startup time.
390 // Must be accessed on the IO thread;
391 bool has_checked_keyboard_mic_;
392 #endif
394 // Stores most recently enumerated device lists. The cache is cleared when
395 // monitoring is stopped or there is no request for that type of device.
396 EnumerationCache audio_enumeration_cache_;
397 EnumerationCache video_enumeration_cache_;
399 // Keeps track of live enumeration commands sent to VideoCaptureManager or
400 // AudioInputDeviceManager, in order to only enumerate when necessary.
401 int active_enumeration_ref_count_[NUM_MEDIA_TYPES];
403 // All non-closed request. Must be accessed on IO thread.
404 DeviceRequests requests_;
406 bool use_fake_ui_;
407 scoped_ptr<FakeMediaStreamUIProxy> fake_ui_;
409 DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
412 } // namespace content
414 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_