Bug 1404230 - Part2 - Add a web api to support HDCP policy check on MediaKeys. draft
authorJames Cheng <jacheng@mozilla.com>
Mon, 02 Oct 2017 17:39:00 +0800
changeset 688579 38067e29e3890fc3bcab8c2dfb2ab07301951426
parent 688578 4ee0f47edbb3642d226e7403bf6c4d7ec9f23e12
child 688580 a45be3c24369f2bb74707dfd9a3005e930bffeeb
push id86792
push userbmo:jacheng@mozilla.com
push dateMon, 30 Oct 2017 09:42:43 +0000
bugs1404230
milestone58.0a1
Bug 1404230 - Part2 - Add a web api to support HDCP policy check on MediaKeys. MozReview-Commit-ID: HW7DtQ6GuOa
dom/media/eme/MediaKeys.cpp
dom/media/eme/MediaKeys.h
dom/media/eme/MediaKeysPolicy.cpp
dom/media/eme/MediaKeysPolicy.h
dom/media/eme/moz.build
dom/webidl/MediaKeys.webidl
dom/webidl/MediaKeysPolicy.webidl
dom/webidl/moz.build
--- a/dom/media/eme/MediaKeys.cpp
+++ b/dom/media/eme/MediaKeys.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/dom/MediaKeys.h"
 #include "GMPCrashHelper.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/MediaKeysBinding.h"
 #include "mozilla/dom/MediaKeyMessageEvent.h"
 #include "mozilla/dom/MediaKeyError.h"
 #include "mozilla/dom/MediaKeySession.h"
 #include "mozilla/dom/MediaKeyStatusMap.h"
+#include "mozilla/dom/MediaKeysPolicy.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/Telemetry.h"
 #ifdef MOZ_WIDGET_ANDROID
 #include "mozilla/MediaDrmCDMProxy.h"
 #endif
 #include "mozilla/EMEUtils.h"
 #include "nsContentUtils.h"
@@ -592,10 +593,44 @@ MediaKeys::GetSessionsInfo(nsString& ses
       sessionsInfo.Append(
         NS_ConvertUTF8toUTF16((nsDependentCString(keyStatus))));
       sessionsInfo.AppendLiteral(")");
     }
     sessionsInfo.AppendLiteral(")");
   }
 }
 
+already_AddRefed<Promise>
+MediaKeys::GetStatusForPolicy(MediaKeysPolicy& aPolicy,
+                              ErrorResult& aRv)
+{
+  RefPtr<DetailedPromise> promise(MakePromise(aRv,
+    NS_LITERAL_CSTRING("MediaKeys::GetStatusForPolicy()")));
+  if (aRv.Failed()) {
+    return nullptr;
+  }
+
+  // Currently, only widevine CDM supports for this API.
+  if (!IsWidevineKeySystem(mKeySystem)) {
+    EME_LOG("MediaKeys[%p]::GetStatusForPolicy() HDCP policy check on unsupported keysystem ", this);
+    NS_WARNING("Tried to query without a CDM");
+    promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
+                         NS_LITERAL_CSTRING("HDCP policy check on unsupported keysystem"));
+    return promise.forget();
+  }
+
+  if (!mProxy) {
+   NS_WARNING("Tried to use a MediaKeys without a CDM");
+   promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
+                        NS_LITERAL_CSTRING("Null CDM in MediaKeys.GetStatusForPolicy()"));
+   return promise.forget();
+  }
+
+  nsString minHdcpVersion;
+  aPolicy.GetMinHdcpVersion(minHdcpVersion);
+  EME_LOG("GetStatusForPolicy minHdcpVersion = %s.", NS_ConvertUTF16toUTF8(minHdcpVersion).get());
+  // TODO: Ask CDM to get the real policy.
+  promise->MaybeResolve(MediaKeyStatus::Usable);
+  return promise.forget();
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/eme/MediaKeys.h
+++ b/dom/media/eme/MediaKeys.h
@@ -24,16 +24,17 @@
 namespace mozilla {
 
 class CDMProxy;
 
 namespace dom {
 
 class ArrayBufferViewOrArrayBuffer;
 class MediaKeySession;
+class MediaKeysPolicy;
 class HTMLMediaElement;
 
 typedef nsRefPtrHashtable<nsStringHashKey, MediaKeySession> KeySessionHashMap;
 typedef nsRefPtrHashtable<nsUint32HashKey, dom::DetailedPromise> PromiseHashMap;
 typedef nsRefPtrHashtable<nsUint32HashKey, MediaKeySession> PendingKeySessionsHashMap;
 typedef nsDataHashtable<nsUint32HashKey, uint32_t> PendingPromiseIdTokenHashMap;
 typedef uint32_t PromiseId;
 
@@ -125,16 +126,20 @@ public:
   // Shutdown which is called from the script/dom side.
   void Terminated();
 
   // Returns true if this MediaKeys has been bound to a media element.
   bool IsBoundToMediaElement() const;
 
   void GetSessionsInfo(nsString& sessionsInfo);
 
+  // JavaScript: MediaKeys.GetStatusForPolicy()
+  already_AddRefed<Promise> GetStatusForPolicy(MediaKeysPolicy& aPolicy,
+                                               ErrorResult& aR);
+
 private:
 
   // Instantiate CDMProxy instance.
   // It could be MediaDrmCDMProxy (Widevine on Fennec) or ChromiumCDMProxy (the rest).
   already_AddRefed<CDMProxy> CreateCDMProxy(nsIEventTarget* aMainThread);
 
   // Removes promise from mPromises, and returns it.
   already_AddRefed<DetailedPromise> RetrievePromise(PromiseId aId);
new file mode 100644
--- /dev/null
+++ b/dom/media/eme/MediaKeysPolicy.cpp
@@ -0,0 +1,60 @@
+/* -*- 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 "mozilla/dom/MediaKeysPolicy.h"
+#include "mozilla/dom/MediaKeysPolicyBinding.h"
+#include "nsPIDOMWindow.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaKeysPolicy)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeysPolicy)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeysPolicy)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeysPolicy)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+MediaKeysPolicy::MediaKeysPolicy(nsPIDOMWindowInner* aParentWindow,
+                                 const nsAString& aMinHdcpVersion)
+  : mParent(aParentWindow),
+    mMinHdcpVersion(aMinHdcpVersion)
+
+{
+}
+
+JSObject*
+MediaKeysPolicy::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return MediaKeysPolicyBinding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner*
+MediaKeysPolicy::GetParentObject() const
+{
+  return mParent;
+}
+
+/*static*/
+already_AddRefed<MediaKeysPolicy>
+MediaKeysPolicy::Constructor(const GlobalObject& aGlobal,
+                             const MediaKeysPolicyInit& aInit,
+                             ErrorResult& aRv)
+{
+  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!window) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return nullptr;
+  }
+
+  RefPtr<MediaKeysPolicy> mediaKeyPolicy = new MediaKeysPolicy(window,
+                                                               aInit.mMinHdcpVersion);
+  return mediaKeyPolicy.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/eme/MediaKeysPolicy.h
@@ -0,0 +1,60 @@
+/* -*- 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 mozilla_dom_MediaKeysPolicy_h
+#define mozilla_dom_MediaKeysPolicy_h
+
+#include "js/TypeDecls.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+namespace dom {
+
+struct MediaKeysPolicyInit;
+
+class MediaKeysPolicy final : public nsISupports,
+                              public nsWrapperCache
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeysPolicy)
+
+public:
+  MediaKeysPolicy(nsPIDOMWindowInner* aParentWindow,
+                  const nsAString& aMinHdcpVersion);
+
+protected:
+  ~MediaKeysPolicy() = default;
+
+public:
+  nsPIDOMWindowInner* GetParentObject() const;
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+  static already_AddRefed<MediaKeysPolicy> Constructor(const GlobalObject& aGlobal,
+                                                       const MediaKeysPolicyInit& aInit,
+                                                       ErrorResult& aRv);
+
+  void GetMinHdcpVersion(nsString& aRetVal) const
+  {
+    aRetVal.Assign(mMinHdcpVersion);
+  }
+
+private:
+  nsCOMPtr<nsPIDOMWindowInner> mParent;
+  nsString mMinHdcpVersion;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MediaKeysPolicy_h
--- a/dom/media/eme/moz.build
+++ b/dom/media/eme/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom += [
     'MediaEncryptedEvent.h',
     'MediaKeyError.h',
     'MediaKeyMessageEvent.h',
     'MediaKeys.h',
     'MediaKeySession.h',
+    'MediaKeysPolicy.h',
     'MediaKeyStatusMap.h',
     'MediaKeySystemAccess.h',
     'MediaKeySystemAccessManager.h',
 ]
 
 EXPORTS.mozilla += [
     'CDMCaps.h',
     'CDMProxy.h',
@@ -27,16 +28,17 @@ UNIFIED_SOURCES += [
     'CDMCaps.cpp',
     'DetailedPromise.cpp',
     'EMEUtils.cpp',
     'MediaEncryptedEvent.cpp',
     'MediaKeyError.cpp',
     'MediaKeyMessageEvent.cpp',
     'MediaKeys.cpp',
     'MediaKeySession.cpp',
+    'MediaKeysPolicy.cpp',
     'MediaKeyStatusMap.cpp',
     'MediaKeySystemAccess.cpp',
     'MediaKeySystemAccessManager.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
   DIRS += ['mediadrm']
 
--- a/dom/webidl/MediaKeys.webidl
+++ b/dom/webidl/MediaKeys.webidl
@@ -21,9 +21,12 @@ enum MediaKeySessionType {
 interface MediaKeys {
   readonly attribute DOMString keySystem;
 
   [NewObject, Throws]
   MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
 
   [NewObject]
   Promise<void> setServerCertificate(BufferSource serverCertificate);
+
+  [Pref="media.eme.hdcp-policy-check.enabled", NewObject]
+  Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy);
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MediaKeysPolicy.webidl
@@ -0,0 +1,19 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
+ * W3C liability, trademark and document use rules apply.
+ */
+ 
+// https://github.com/WICG/media-capabilities/blob/master/eme-extension-policy-check.md
+ 
+dictionary MediaKeysPolicyInit {
+  DOMString minHdcpVersion = "";
+};
+
+[Constructor(optional MediaKeysPolicyInit init), Exposed=Window]
+interface MediaKeysPolicy {
+  readonly attribute DOMString minHdcpVersion;
+};
\ No newline at end of file
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -675,16 +675,17 @@ WEBIDL_FILES = [
     'MediaDevices.webidl',
     'MediaElementAudioSourceNode.webidl',
     'MediaEncryptedEvent.webidl',
     'MediaError.webidl',
     'MediaKeyError.webidl',
     'MediaKeyMessageEvent.webidl',
     'MediaKeys.webidl',
     'MediaKeySession.webidl',
+    'MediaKeysPolicy.webidl',
     'MediaKeysRequestStatus.webidl',
     'MediaKeyStatusMap.webidl',
     'MediaKeySystemAccess.webidl',
     'MediaList.webidl',
     'MediaQueryList.webidl',
     'MediaRecorder.webidl',
     'MediaSource.webidl',
     'MediaStream.webidl',