| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_DEVICES_MANAGER_H_ |
| #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_DEVICES_MANAGER_H_ |
| |
| #include <array> |
| #include <vector> |
| |
| #include "base/callback.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/system_monitor/system_monitor.h" |
| #include "content/common/content_export.h" |
| #include "content/common/media/media_devices.h" |
| #include "media/audio/audio_device_description.h" |
| #include "media/capture/video/video_capture_device_descriptor.h" |
| |
| namespace media { |
| class AudioSystem; |
| } |
| |
| namespace content { |
| |
| class MediaStreamManager; |
| class VideoCaptureManager; |
| |
| // Use MediaDeviceType values to index on this type. |
| using MediaDeviceEnumeration = |
| std::array<MediaDeviceInfoArray, NUM_MEDIA_DEVICE_TYPES>; |
| |
| // MediaDeviceChangeSubscriber is an interface to be implemented by classes |
| // that can register with MediaDevicesManager to get notifications about changes |
| // in the set of media devices. |
| class CONTENT_EXPORT MediaDeviceChangeSubscriber { |
| public: |
| // This function is invoked to notify about changes in the set of media |
| // devices of type |type|. |device_infos| contains the updated list of |
| // devices of type |type|. |
| virtual void OnDevicesChanged(MediaDeviceType type, |
| const MediaDeviceInfoArray& device_infos) = 0; |
| }; |
| |
| // MediaDevicesManager is responsible for doing media-device enumerations. |
| // In addition it implements caching for enumeration results and device |
| // monitoring in order to keep caches consistent. |
| // All its methods must be called on the IO thread. |
| class CONTENT_EXPORT MediaDevicesManager |
| : public base::SystemMonitor::DevicesChangedObserver { |
| public: |
| // Use MediaDeviceType values to index on this type. By default all device |
| // types are false. |
| class BoolDeviceTypes final |
| : public std::array<bool, NUM_MEDIA_DEVICE_TYPES> { |
| public: |
| BoolDeviceTypes() { fill(false); } |
| }; |
| |
| using EnumerationCallback = |
| base::Callback<void(const MediaDeviceEnumeration&)>; |
| |
| MediaDevicesManager( |
| media::AudioSystem* audio_system, |
| const scoped_refptr<VideoCaptureManager>& video_capture_manager, |
| MediaStreamManager* media_stream_manager); |
| ~MediaDevicesManager() override; |
| |
| // Performs a possibly cached device enumeration for the requested device |
| // types and reports the results to |callback|. |
| // The enumeration results passed to |callback| are guaranteed to be valid |
| // only for the types specified in |requested_types|. |
| // Note that this function is not reentrant, so if |callback| needs to perform |
| // another call to EnumerateDevices, it must do so by posting a task to the |
| // IO thread. |
| void EnumerateDevices(const BoolDeviceTypes& requested_types, |
| const EnumerationCallback& callback); |
| |
| // Subscribes |subscriber| to receive device-change notifications for devices |
| // of type |type|. If |subscriber| is already subscribed, this function has |
| // no side effects. MediaDevicesManager does not own |subscriber|. It is the |
| // responsibility of the caller to ensure that all registered subscribers |
| // remain valid while the they are subscribed. |
| void SubscribeDeviceChangeNotifications( |
| MediaDeviceType type, |
| MediaDeviceChangeSubscriber* subscriber); |
| |
| // Unubscribes |subscriber| from device-change notifications for the devices |
| // of type |type|. If |subscriber| is not subscribed, this function has no |
| // side effects. |
| void UnsubscribeDeviceChangeNotifications( |
| MediaDeviceType type, |
| MediaDeviceChangeSubscriber* subscriber); |
| |
| // Tries to start device monitoring. If successful, enables caching of |
| // enumeration results for the device types supported by the monitor. |
| void StartMonitoring(); |
| |
| // Stops device monitoring and disables caching for all device types. |
| void StopMonitoring(); |
| |
| // Returns true if device monitoring is active, false otherwise. |
| bool IsMonitoringStarted(); |
| |
| // Implements base::SystemMonitor::DevicesChangedObserver. |
| // This function is only called in response to physical audio/video device |
| // changes. |
| void OnDevicesChanged(base::SystemMonitor::DeviceType device_type) override; |
| |
| // TODO(guidou): Remove this function once content::GetMediaDeviceIDForHMAC |
| // is rewritten to receive devices via a callback. |
| // See http://crbug.com/648155. |
| MediaDeviceInfoArray GetCachedDeviceInfo(MediaDeviceType type); |
| |
| private: |
| friend class MediaDevicesManagerTest; |
| struct EnumerationRequest; |
| |
| // The NO_CACHE policy is such that no previous results are used when |
| // EnumerateDevices is called. The results of a new or in-progress low-level |
| // device enumeration are used. |
| // The SYSTEM_MONITOR policy is such that previous results are re-used, |
| // provided they were produced by a low-level device enumeration issued after |
| // the last call to OnDevicesChanged. |
| enum class CachePolicy { |
| NO_CACHE, |
| SYSTEM_MONITOR, |
| }; |
| |
| // Manually sets a caching policy for a given device type. |
| void SetCachePolicy(MediaDeviceType type, CachePolicy policy); |
| |
| // Helpers to issue low-level device enumerations. |
| void DoEnumerateDevices(MediaDeviceType type); |
| void EnumerateAudioDevices(bool is_input); |
| |
| // Callback for VideoCaptureManager::EnumerateDevices. |
| void VideoInputDevicesEnumerated( |
| const media::VideoCaptureDeviceDescriptors& descriptors); |
| |
| // Callback for AudioSystem::GetDeviceDescriptions. |
| void AudioDevicesEnumerated( |
| MediaDeviceType type, |
| media::AudioDeviceDescriptions device_descriptions); |
| |
| // Helpers to handle enumeration results. |
| void DevicesEnumerated(MediaDeviceType type, |
| const MediaDeviceInfoArray& snapshot); |
| void UpdateSnapshot(MediaDeviceType type, |
| const MediaDeviceInfoArray& new_snapshot); |
| void ProcessRequests(); |
| bool IsEnumerationRequestReady(const EnumerationRequest& request_info); |
| |
| // Helpers to handle device-change notification. |
| void HandleDevicesChanged(MediaDeviceType type); |
| void NotifyMediaStreamManager(MediaDeviceType type, |
| const MediaDeviceInfoArray& new_snapshot); |
| void NotifyDeviceChangeSubscribers(MediaDeviceType type, |
| const MediaDeviceInfoArray& snapshot); |
| |
| #if defined(OS_MACOSX) |
| void StartMonitoringOnUIThread(); |
| #endif |
| |
| bool use_fake_devices_; |
| media::AudioSystem* const audio_system_; // not owned |
| scoped_refptr<VideoCaptureManager> video_capture_manager_; |
| MediaStreamManager* const media_stream_manager_; // not owned |
| |
| using CachePolicies = std::array<CachePolicy, NUM_MEDIA_DEVICE_TYPES>; |
| CachePolicies cache_policies_; |
| |
| class CacheInfo; |
| using CacheInfos = std::vector<CacheInfo>; |
| CacheInfos cache_infos_; |
| |
| BoolDeviceTypes has_seen_result_; |
| std::vector<EnumerationRequest> requests_; |
| MediaDeviceEnumeration current_snapshot_; |
| bool monitoring_started_; |
| |
| std::vector<MediaDeviceChangeSubscriber*> |
| device_change_subscribers_[NUM_MEDIA_DEVICE_TYPES]; |
| |
| base::WeakPtrFactory<MediaDevicesManager> weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MediaDevicesManager); |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_DEVICES_MANAGER_H_ |