Bug 1885602 - Part 2: Add a MozillaAccountMenuButton composable for the menu redesign...
[gecko.git] / dom / media / eme / MediaKeys.h
blob5a44b3c227369a1b36d35d2b3cd3e67349ac4131
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_mediakeys_h__
8 #define mozilla_dom_mediakeys_h__
10 #include "DecoderDoctorLogger.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/DetailedPromise.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/WeakPtr.h"
15 #include "mozilla/dom/MediaKeyStatusMapBinding.h" // For MediaKeyStatus
16 #include "mozilla/dom/MediaKeySystemAccessBinding.h"
17 #include "mozilla/dom/MediaKeysBinding.h"
18 #include "mozilla/dom/Promise.h"
19 #include "nsCOMPtr.h"
20 #include "nsCycleCollectionParticipant.h"
21 #include "nsIObserver.h"
22 #include "nsRefPtrHashtable.h"
23 #include "nsTHashMap.h"
24 #include "nsWrapperCache.h"
26 namespace mozilla {
28 class CDMProxy;
30 namespace dom {
31 class MediaKeys;
32 } // namespace dom
33 DDLoggedTypeName(dom::MediaKeys);
35 namespace dom {
37 class ArrayBufferViewOrArrayBuffer;
38 class MediaKeySession;
39 struct MediaKeysPolicy;
40 class HTMLMediaElement;
42 typedef nsRefPtrHashtable<nsStringHashKey, MediaKeySession> KeySessionHashMap;
43 typedef nsRefPtrHashtable<nsUint32HashKey, dom::DetailedPromise> PromiseHashMap;
44 typedef nsRefPtrHashtable<nsUint32HashKey, MediaKeySession>
45 PendingKeySessionsHashMap;
46 typedef nsTHashMap<nsUint32HashKey, uint32_t> PendingPromiseIdTokenHashMap;
47 typedef uint32_t PromiseId;
49 // This class is used on the main thread only.
50 // Note: its addref/release is not (and can't be) thread safe!
51 class MediaKeys final : public nsIObserver,
52 public nsWrapperCache,
53 public SupportsWeakPtr,
54 public DecoderDoctorLifeLogger<MediaKeys> {
55 ~MediaKeys();
57 public:
58 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
59 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(MediaKeys)
61 NS_DECL_NSIOBSERVER
63 MediaKeys(nsPIDOMWindowInner* aParentWindow, const nsAString& aKeySystem,
64 const MediaKeySystemConfiguration& aConfig);
66 already_AddRefed<DetailedPromise> Init(ErrorResult& aRv);
68 nsPIDOMWindowInner* GetParentObject() const;
70 JSObject* WrapObject(JSContext* aCx,
71 JS::Handle<JSObject*> aGivenProto) override;
73 nsresult Bind(HTMLMediaElement* aElement);
74 void Unbind();
76 // Checks if there's any activity happening that could capture the media
77 // the keys are associated with and then expose that media outside of the
78 // origin it is in.
80 // This method does not return the results of the check, but the MediaKeys
81 // will notify mProxy of the results using `NotifyOutputProtectionStatus`.
82 void CheckIsElementCapturePossible();
84 // Javascript: readonly attribute DOMString keySystem;
85 void GetKeySystem(nsString& retval) const;
87 // JavaScript: MediaKeys.createSession()
88 already_AddRefed<MediaKeySession> CreateSession(
89 MediaKeySessionType aSessionType, ErrorResult& aRv);
91 // JavaScript: MediaKeys.SetServerCertificate()
92 already_AddRefed<DetailedPromise> SetServerCertificate(
93 const ArrayBufferViewOrArrayBuffer& aServerCertificate, ErrorResult& aRv);
95 already_AddRefed<MediaKeySession> GetSession(const nsAString& aSessionId);
97 // Removes and returns MediaKeySession from the set of sessions awaiting
98 // their sessionId to be assigned.
99 already_AddRefed<MediaKeySession> GetPendingSession(uint32_t aToken);
101 // Called once a Init() operation succeeds.
102 void OnCDMCreated(PromiseId aId, const uint32_t aPluginId);
104 // Called once the CDM generates a sessionId while servicing a
105 // MediaKeySession.generateRequest() or MediaKeySession.load() call,
106 // once the sessionId of a MediaKeySession is known.
107 void OnSessionIdReady(MediaKeySession* aSession);
109 // Called once a LoadSession succeeds.
110 void OnSessionLoaded(PromiseId aId, bool aSuccess);
112 // Called once a session has closed.
113 void OnSessionClosed(MediaKeySession* aSession);
115 CDMProxy* GetCDMProxy() { return mProxy; }
117 // Makes a new promise, or nullptr on failure.
118 already_AddRefed<DetailedPromise> MakePromise(ErrorResult& aRv,
119 const nsACString& aName);
120 // Stores promise in mPromises, returning an ID that can be used to retrieve
121 // it later. The ID is passed to the CDM, so that it can signal specific
122 // promises to be resolved.
123 PromiseId StorePromise(DetailedPromise* aPromise);
125 // Stores a map from promise id to pending session token. Using this
126 // mapping, when a promise is rejected via its ID, we can check if the
127 // promise corresponds to a pending session and retrieve that session
128 // via the mapped-to token, and remove the pending session from the
129 // list of sessions awaiting a session id.
130 void ConnectPendingPromiseIdWithToken(PromiseId aId, uint32_t aToken);
132 // Reject promise with the given exception.
133 void RejectPromise(PromiseId aId, ErrorResult&& aException,
134 const nsCString& aReason);
135 // Resolves promise with "undefined".
136 void ResolvePromise(PromiseId aId);
138 void Shutdown();
140 // Called by CDMProxy when CDM crashes or shuts down. It is different from
141 // Shutdown which is called from the script/dom side.
142 void Terminated();
144 // Returns true if this MediaKeys has been bound to a media element.
145 bool IsBoundToMediaElement() const;
147 // Indicates to a MediaKeys instance that the inner window parent of that
148 // instance is being destroyed, this should prompt the keys to shutdown.
149 void OnInnerWindowDestroy();
151 void GetSessionsInfo(nsString& sessionsInfo);
153 // JavaScript: MediaKeys.GetStatusForPolicy()
154 already_AddRefed<Promise> GetStatusForPolicy(const MediaKeysPolicy& aPolicy,
155 ErrorResult& aR);
156 // Called by CDMProxy when CDM successfully GetStatusForPolicy.
157 void ResolvePromiseWithKeyStatus(PromiseId aId,
158 dom::MediaKeyStatus aMediaKeyStatus);
160 template <typename T>
161 void ResolvePromiseWithResult(PromiseId aId, const T& aResult) {
162 RefPtr<DetailedPromise> promise(RetrievePromise(aId));
163 if (!promise) {
164 return;
166 promise->MaybeResolve(aResult);
169 // The topic used for requests related to mediakeys -- observe this to be
170 // notified of such requests.
171 constexpr static const char* kMediaKeysRequestTopic = "mediakeys-request";
173 private:
174 // Instantiate CDMProxy instance.
175 // It could be MediaDrmCDMProxy (Widevine on Fennec) or ChromiumCDMProxy (the
176 // rest).
177 already_AddRefed<CDMProxy> CreateCDMProxy();
179 // Removes promise from mPromises, and returns it.
180 already_AddRefed<DetailedPromise> RetrievePromise(PromiseId aId);
182 // Helpers to connect and disconnect to the parent inner window. An inner
183 // window should track (via weak ptr) MediaKeys created within it so we can
184 // ensure MediaKeys are shutdown if that window is destroyed.
185 void ConnectInnerWindow();
186 void DisconnectInnerWindow();
188 // Owning ref to proxy. The proxy has a weak reference back to the MediaKeys,
189 // and the MediaKeys destructor clears the proxy's reference to the MediaKeys.
190 RefPtr<CDMProxy> mProxy;
192 // The HTMLMediaElement the MediaKeys are associated with. Note that a
193 // MediaKeys instance may not be associated with any HTMLMediaElement so
194 // this can be null (we also cannot rely on a media element to drive shutdown
195 // for this reason).
196 RefPtr<HTMLMediaElement> mElement;
198 // The inner window associated with an instance of MediaKeys. We will
199 // shutdown the media keys when this Window is destroyed. We do this from the
200 // window rather than a document to address the case where media keys can be
201 // created in an about:blank document that then performs an async load -- this
202 // recreates the document, but the inner window is preserved in such a case.
203 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1675360 for more info.
204 nsCOMPtr<nsPIDOMWindowInner> mParent;
205 const nsString mKeySystem;
206 KeySessionHashMap mKeySessions;
207 PromiseHashMap mPromises;
208 PendingKeySessionsHashMap mPendingSessions;
209 PromiseId mCreatePromiseId;
211 // The principal of the relevant settings object.
212 RefPtr<nsIPrincipal> mPrincipal;
213 // The principal of the top level page. This can differ from mPrincipal if
214 // we're in an iframe.
215 RefPtr<nsIPrincipal> mTopLevelPrincipal;
217 const MediaKeySystemConfiguration mConfig;
219 PendingPromiseIdTokenHashMap mPromiseIdToken;
221 // The topic a MediaKeys instance will observe to receive updates from
222 // EncryptedMediaChild.
223 constexpr static const char* kMediaKeysResponseTopic = "mediakeys-response";
224 // Tracks if we've added an observer for responses from the associated
225 // EncryptedMediaChild. When true an observer is already in place, otherwise
226 // the observer has not yet been added.
227 bool mObserverAdded = false;
228 // Stores the json request we will send to EncryptedMediaChild when querying
229 // output protection. Lazily populated upon first use.
230 nsString mCaptureCheckRequestJson;
233 } // namespace dom
234 } // namespace mozilla
236 #endif // mozilla_dom_mediakeys_h__