MediaDevices.h (4882B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_dom_MediaDevices_h 6 #define mozilla_dom_MediaDevices_h 7 8 #include "MediaEventSource.h" 9 #include "js/RootingAPI.h" 10 #include "mozilla/AlreadyAddRefed.h" 11 #include "mozilla/DOMEventTargetHelper.h" 12 #include "mozilla/UseCounter.h" 13 #include "mozilla/dom/BindingDeclarations.h" 14 #include "mozilla/dom/MediaDeviceInfoBinding.h" 15 #include "nsCOMPtr.h" 16 #include "nsID.h" 17 #include "nsISupports.h" 18 #include "nsTHashSet.h" 19 20 class AudioDeviceInfo; 21 22 namespace mozilla { 23 24 class LocalMediaDevice; 25 class MediaDevice; 26 class MediaMgrError; 27 class DOMMediaStream; 28 template <typename ResolveValueT, typename RejectValueT, bool IsExclusive> 29 class MozPromise; 30 31 namespace media { 32 template <typename T> 33 class Refcountable; 34 } // namespace media 35 36 namespace dom { 37 38 class Promise; 39 struct MediaStreamConstraints; 40 struct DisplayMediaStreamConstraints; 41 struct MediaTrackSupportedConstraints; 42 struct AudioOutputOptions; 43 44 class MediaDevices final : public DOMEventTargetHelper { 45 public: 46 using StreamPromise = 47 MozPromise<RefPtr<DOMMediaStream>, RefPtr<MediaMgrError>, true>; 48 using SinkInfoPromise = MozPromise<RefPtr<AudioDeviceInfo>, nsresult, true>; 49 50 explicit MediaDevices(nsPIDOMWindowInner* aWindow); 51 52 NS_DECL_ISUPPORTS_INHERITED 53 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaDevices, DOMEventTargetHelper) 54 55 JSObject* WrapObject(JSContext* cx, 56 JS::Handle<JSObject*> aGivenProto) override; 57 58 void GetSupportedConstraints(MediaTrackSupportedConstraints& aResult); 59 60 already_AddRefed<Promise> GetUserMedia( 61 const MediaStreamConstraints& aConstraints, CallerType aCallerType, 62 ErrorResult& aRv); 63 64 RefPtr<StreamPromise> GetUserMedia(nsPIDOMWindowInner* aWindow, 65 const MediaStreamConstraints& aConstraints, 66 CallerType aCallerType); 67 68 already_AddRefed<Promise> EnumerateDevices(ErrorResult& aRv); 69 70 already_AddRefed<Promise> GetDisplayMedia( 71 const DisplayMediaStreamConstraints& aConstraints, CallerType aCallerType, 72 ErrorResult& aRv); 73 74 already_AddRefed<Promise> SelectAudioOutput( 75 const AudioOutputOptions& aOptions, CallerType aCallerType, 76 ErrorResult& aRv); 77 78 // Get the sink that corresponds to the given device id. 79 // The returned promise will be resolved with the device 80 // information if the aDeviceId matches a device that would be exposed by 81 // enumerateDevices(). 82 // The promise will be rejected with NS_ERROR_NOT_AVAILABLE if aDeviceId 83 // does not match any exposed device. 84 RefPtr<SinkInfoPromise> GetSinkDevice(const nsString& aDeviceId); 85 86 // Called when MediaManager encountered a change in its device lists. 87 void OnDeviceChange(); 88 89 void SetupDeviceChangeListener(); 90 91 mozilla::dom::EventHandlerNonNull* GetOndevicechange(); 92 void SetOndevicechange(mozilla::dom::EventHandlerNonNull* aCallback); 93 94 void EventListenerAdded(nsAtom* aType) override; 95 using DOMEventTargetHelper::EventListenerAdded; 96 97 void BackgroundStateChanged() { MaybeResumeDeviceExposure(); } 98 void WindowResumed() { MaybeResumeDeviceExposure(); } 99 void BrowserWindowBecameActive() { MaybeResumeDeviceExposure(); } 100 101 private: 102 using MediaDeviceSet = nsTArray<RefPtr<MediaDevice>>; 103 using MediaDeviceSetRefCnt = media::Refcountable<MediaDeviceSet>; 104 using LocalMediaDeviceSet = nsTArray<RefPtr<LocalMediaDevice>>; 105 106 virtual ~MediaDevices(); 107 void MaybeResumeDeviceExposure(); 108 void ResumeEnumerateDevices( 109 nsTArray<RefPtr<Promise>>&& aPromises, 110 RefPtr<const MediaDeviceSetRefCnt> aExposedDevices) const; 111 RefPtr<MediaDeviceSetRefCnt> FilterExposedDevices( 112 const MediaDeviceSet& aDevices) const; 113 bool CanExposeInfo(MediaDeviceKind aKind) const; 114 bool ShouldQueueDeviceChange(const MediaDeviceSet& aExposedDevices) const; 115 void ResolveEnumerateDevicesPromise( 116 Promise* aPromise, const LocalMediaDeviceSet& aDevices) const; 117 118 nsTHashSet<nsString> mExplicitlyGrantedAudioOutputRawIds; 119 nsTArray<RefPtr<Promise>> mPendingEnumerateDevicesPromises; 120 // Set only once, if and when required. 121 mutable nsString mDefaultOutputLabel; 122 123 // Connect/Disconnect on main thread only 124 MediaEventListener mDeviceChangeListener; 125 // Ordered set of the system physical devices when devicechange event 126 // decisions were last performed. 127 RefPtr<const MediaDeviceSetRefCnt> mLastPhysicalDevices; 128 bool mIsDeviceChangeListenerSetUp = false; 129 bool mHaveUnprocessedDeviceListChange = false; 130 bool mCanExposeMicrophoneInfo = false; 131 bool mCanExposeCameraInfo = false; 132 133 void RecordAccessTelemetry(const UseCounter counter) const; 134 }; 135 136 } // namespace dom 137 } // namespace mozilla 138 139 #endif // mozilla_dom_MediaDevices_h