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 "nsCOMPtr.h"
15 #include "nsID.h"
16 #include "nsISupports.h"
17 #include "nsITimer.h"
18 #include "nsTHashSet.h"
19 
20 class AudioDeviceInfo;
21 
22 namespace mozilla {
23 
24 template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
25 class MozPromise;
26 
27 namespace dom {
28 
29 class Promise;
30 struct MediaStreamConstraints;
31 struct DisplayMediaStreamConstraints;
32 struct MediaTrackSupportedConstraints;
33 struct AudioOutputOptions;
34 
35 #define MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID  \
36   {                                                  \
37     0x2f784d8a, 0x7485, 0x4280, {                    \
38       0x9a, 0x36, 0x74, 0xa4, 0xd6, 0x71, 0xa6, 0xc8 \
39     }                                                \
40   }
41 
42 class MediaDevices final : public DOMEventTargetHelper {
43  public:
44   using SinkInfoPromise = MozPromise<RefPtr<AudioDeviceInfo>, nsresult, true>;
45 
46   explicit MediaDevices(nsPIDOMWindowInner* aWindow);
47 
48   NS_DECL_ISUPPORTS_INHERITED
49   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
50 
51   JSObject* WrapObject(JSContext* cx,
52                        JS::Handle<JSObject*> aGivenProto) override;
53 
54   // No code needed, as MediaTrackSupportedConstraints members default to true.
GetSupportedConstraints(MediaTrackSupportedConstraints & aResult)55   void GetSupportedConstraints(MediaTrackSupportedConstraints& aResult){};
56 
57   already_AddRefed<Promise> GetUserMedia(
58       const MediaStreamConstraints& aConstraints, CallerType aCallerType,
59       ErrorResult& aRv);
60 
61   already_AddRefed<Promise> EnumerateDevices(CallerType aCallerType,
62                                              ErrorResult& aRv);
63 
64   already_AddRefed<Promise> GetDisplayMedia(
65       const DisplayMediaStreamConstraints& aConstraints, CallerType aCallerType,
66       ErrorResult& aRv);
67 
68   already_AddRefed<Promise> SelectAudioOutput(
69       const AudioOutputOptions& aOptions, CallerType aCallerType,
70       ErrorResult& aRv);
71 
72   // Get the sink that corresponds to the given device id.
73   // The returned promise will be resolved with the device
74   // information if the aDeviceId matches a device that would be exposed by
75   // enumerateDevices().
76   // The promise will be rejected with NS_ERROR_NOT_AVAILABLE if aDeviceId
77   // does not match any exposed device.
78   RefPtr<SinkInfoPromise> GetSinkDevice(const nsString& aDeviceId);
79 
80   // Called when MediaManager encountered a change in its device lists.
81   void OnDeviceChange();
82 
83   void SetupDeviceChangeListener();
84 
85   mozilla::dom::EventHandlerNonNull* GetOndevicechange();
86   void SetOndevicechange(mozilla::dom::EventHandlerNonNull* aCallback);
87 
88   void EventListenerAdded(nsAtom* aType) override;
89   using DOMEventTargetHelper::EventListenerAdded;
90 
91  private:
92   class GumResolver;
93   class EnumDevResolver;
94   class GumRejecter;
95 
96   virtual ~MediaDevices();
97 
98   nsTHashSet<nsString> mExplicitlyGrantedAudioOutputIds;
99   nsCOMPtr<nsITimer> mFuzzTimer;
100 
101   // Connect/Disconnect on main thread only
102   MediaEventListener mDeviceChangeListener;
103   bool mIsDeviceChangeListenerSetUp = false;
104   bool mCanExposeMicrophoneInfo = false;
105 
106   void RecordAccessTelemetry(const UseCounter counter) const;
107 };
108 
109 NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
110                               MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
111 
112 }  // namespace dom
113 }  // namespace mozilla
114 
115 #endif  // mozilla_dom_MediaDevices_h
116