Bug 1587522 - Add MediaKeySystemAccessPermissionRequest. r?alwu draft
authorBryce Seager van Dyk <bvandyk@mozilla.com>
Wed, 27 Nov 2019 13:33:34 -0800
changeset 2519011 1a8e037409c30f6598fb6b58c8a2669463146a92
parent 2519010 a57d963ecaf1f338aaa5b4092b230b3ea9cb5c93
child 2519012 c9284ab81e4d16c4d04bcd3d48abd68f3442efcc
push id460998
push userbvandyk@mozilla.com
push dateThu, 05 Dec 2019 18:36:12 +0000
treeherdertry@2c96c55894f8 [default view] [failures only]
reviewersalwu
bugs1587522
milestone72.0a1
Bug 1587522 - Add MediaKeySystemAccessPermissionRequest. r?alwu This class will be used to surface permission requests to GeckoView.
dom/media/eme/MediaKeySystemAccessPermissionRequest.cpp
dom/media/eme/MediaKeySystemAccessPermissionRequest.h
dom/media/eme/moz.build
new file mode 100644
--- /dev/null
+++ b/dom/media/eme/MediaKeySystemAccessPermissionRequest.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MediaKeySystemAccessPermissionRequest.h"
+
+#include "nsGlobalWindowInner.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaKeySystemAccessPermissionRequest,
+                                   ContentPermissionRequestBase)
+
+NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(
+    MediaKeySystemAccessPermissionRequest, ContentPermissionRequestBase)
+
+/* static */
+already_AddRefed<MediaKeySystemAccessPermissionRequest>
+MediaKeySystemAccessPermissionRequest::Create(
+    nsPIDOMWindowInner* aWindow,
+    MozPromiseHolder<GenericPromise>&& aPromiseHolder) {
+  // Could conceivably be created off main thread then used on main thread
+  // later. If we really need to do that at some point we could relax this
+  // assert.
+  AssertIsOnMainThread();
+  if (!aWindow) {
+    return nullptr;
+  }
+
+  nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(aWindow);
+  if (!innerWindow->GetPrincipal()) {
+    return nullptr;
+  }
+
+  RefPtr<MediaKeySystemAccessPermissionRequest> request =
+      new MediaKeySystemAccessPermissionRequest(innerWindow,
+                                                std::move(aPromiseHolder));
+  return request.forget();
+}
+
+MediaKeySystemAccessPermissionRequest::MediaKeySystemAccessPermissionRequest(
+    nsGlobalWindowInner* aWindow,
+    MozPromiseHolder<GenericPromise>&& aPromiseHolder)
+    : ContentPermissionRequestBase(
+          aWindow->GetPrincipal(), aWindow,
+          NS_LITERAL_CSTRING("media.eme.require-app-approval"),
+          NS_LITERAL_CSTRING("media-key-system-access")),
+      mPromiseHolder(std::move(aPromiseHolder)) {}
+
+MediaKeySystemAccessPermissionRequest::
+    ~MediaKeySystemAccessPermissionRequest() {
+  AssertIsOnMainThread();
+  // If a request has not been serviced by the time it is destroyed, treat it
+  // as if the request was denied.
+  Cancel();
+}
+
+NS_IMETHODIMP
+MediaKeySystemAccessPermissionRequest::Allow(JS::HandleValue aChoices) {
+  AssertIsOnMainThread();
+  mPromiseHolder.ResolveIfExists(true, __func__);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MediaKeySystemAccessPermissionRequest::Cancel() {
+  AssertIsOnMainThread();
+  mPromiseHolder.RejectIfExists(NS_OK, __func__);
+  return NS_OK;
+}
+
+}  // namespace dom
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/eme/MediaKeySystemAccessPermissionRequest.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_MEDIA_MEDIAKEYSYSTEMACCESSPERMISSIONREQUEST_H_
+#define DOM_MEDIA_MEDIAKEYSYSTEMACCESSPERMISSIONREQUEST_H_
+
+#include "nsContentPermissionHelper.h"
+
+#include "mozilla/MozPromise.h"
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * This class encapsulates a permission request to allow media key system
+ * access. The intention is not for this class to be used in all cases of EME,
+ * but only when we need to seek explicit approval from an application using
+ * Gecko, such as an application embedding via GeckoView.
+ *
+ * media.eme.require-app-approval should be used to gate this functionality in
+ * gecko code, and is also used as the testing pref for
+ * ContentPermissionRequestBase. I.e. CheckPromptPrefs() will respond to having
+ * `media.eme.require-app-approval.prompt.testing` and
+ * `media.eme.require-app-approval.prompt.testing.allow` being set to true or
+ * false and will return an appropriate value to allow for test code to short
+ * circuit showing a prompt. Note that the code using this class needs to call
+ * CheckPromptPrefs and implement test specific logic, it is *not* handled by
+ * this class or ContentPermissionRequestBase.
+ *
+ * Expects to be used on main thread as ContentPermissionRequestBase uses
+ * PContentPermissionRequest which is managed by PContent which is main thread
+ * to main thread communication.
+ */
+class MediaKeySystemAccessPermissionRequest
+    : public ContentPermissionRequestBase {
+ public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(
+      MediaKeySystemAccessPermissionRequest, ContentPermissionRequestBase)
+
+  // Create a MediaKeySystemAccessPermissionRequest.
+  // @param aWindow The window associated with this request.
+  // @param aPromiseHolder A promise holder that will be moved into the
+  // request. The holder will resolve the promise associated with it if the
+  // request is allowed and will reject the promise if canceled.
+  // @return An already_AddRefed pointer to the permission request. This
+  // pointer can be nullptr if aWindow is null or lacks a principle.
+  static already_AddRefed<MediaKeySystemAccessPermissionRequest> Create(
+      nsPIDOMWindowInner* aWindow,
+      MozPromiseHolder<GenericPromise>&& aPromiseHolder);
+
+  // nsIContentPermissionRequest methods
+  NS_IMETHOD Cancel(void) override;
+  NS_IMETHOD Allow(JS::HandleValue choices) override;
+
+ private:
+  MediaKeySystemAccessPermissionRequest(
+      nsGlobalWindowInner* aWindow,
+      MozPromiseHolder<GenericPromise>&& aPromiseHolder);
+  ~MediaKeySystemAccessPermissionRequest();
+
+  MozPromiseHolder<GenericPromise> mPromiseHolder;
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // DOM_MEDIA_MEDIAKEYSYSTEMACCESSPERMISSIONREQUEST_H_
--- a/dom/media/eme/moz.build
+++ b/dom/media/eme/moz.build
@@ -8,16 +8,17 @@ EXPORTS.mozilla.dom += [
     'MediaEncryptedEvent.h',
     'MediaKeyError.h',
     'MediaKeyMessageEvent.h',
     'MediaKeys.h',
     'MediaKeySession.h',
     'MediaKeyStatusMap.h',
     'MediaKeySystemAccess.h',
     'MediaKeySystemAccessManager.h',
+    'MediaKeySystemAccessPermissionRequest.h',
 ]
 
 EXPORTS.mozilla += [
     'CDMCaps.h',
     'CDMProxy.h',
     'DecryptorProxyCallback.h',
     'DetailedPromise.h',
     'EMEUtils.h',
@@ -30,16 +31,17 @@ UNIFIED_SOURCES += [
     'MediaEncryptedEvent.cpp',
     'MediaKeyError.cpp',
     'MediaKeyMessageEvent.cpp',
     'MediaKeys.cpp',
     'MediaKeySession.cpp',
     'MediaKeyStatusMap.cpp',
     'MediaKeySystemAccess.cpp',
     'MediaKeySystemAccessManager.cpp',
+    'MediaKeySystemAccessPermissionRequest.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
   DIRS += ['mediadrm']
   LOCAL_INCLUDES += ['/dom/media/platforms/android']
 
 include('/ipc/chromium/chromium-config.mozbuild')