Bug 1307818-[P1] Provide drmStubId for CDMProxy and instantiate {Local,Remote}MediaDrmBridge. draft
authorKilik Kuo <kikuo@mozilla.com>
Wed, 16 Nov 2016 22:09:34 +0800
changeset 439722 9b1d2838ef48e0f05a957f2dbc4f42fe13c537d4
parent 436738 336759fad4621dfcd0a3293840edbed67018accd
child 439723 3ba77475e01f76d293cfd35d98e57a9842742cb0
push id36071
push userkikuo@mozilla.com
push dateWed, 16 Nov 2016 14:19:26 +0000
bugs1307818
milestone52.0a1
Bug 1307818-[P1] Provide drmStubId for CDMProxy and instantiate {Local,Remote}MediaDrmBridge. MozReview-Commit-ID: EFPn4DOZq4D
dom/media/eme/mediadrm/MediaDrmCDMProxy.cpp
dom/media/eme/mediadrm/MediaDrmCDMProxy.h
dom/media/eme/mediadrm/MediaDrmProxySupport.cpp
dom/media/eme/mediadrm/MediaDrmProxySupport.h
mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
widget/android/fennec/FennecJNIWrappers.cpp
widget/android/fennec/FennecJNIWrappers.h
--- a/dom/media/eme/mediadrm/MediaDrmCDMProxy.cpp
+++ b/dom/media/eme/mediadrm/MediaDrmCDMProxy.cpp
@@ -367,16 +367,23 @@ MediaDrmCDMProxy::GetSessionIdsForKeyId(
 #ifdef DEBUG
 bool
 MediaDrmCDMProxy::IsOnOwnerThread()
 {
   return NS_GetCurrentThread() == mOwnerThread;
 }
 #endif
 
+const nsString&
+MediaDrmCDMProxy::GetMediaDrmStubId() const
+{
+  MOZ_ASSERT(mCDM);
+  return mCDM->GetMediaDrmStubId();
+}
+
 void
 MediaDrmCDMProxy::OnCDMCreated(uint32_t aPromiseId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mKeys.IsNull()) {
     return;
   }
 
@@ -459,9 +466,9 @@ MediaDrmCDMProxy::md_Shutdown()
   if (mShutdownCalled) {
     return;
   }
   mShutdownCalled = true;
   mCDM->Shutdown();
   mCDM = nullptr;
 }
 
-} // namespace mozilla
\ No newline at end of file
+} // namespace mozilla
--- a/dom/media/eme/mediadrm/MediaDrmCDMProxy.h
+++ b/dom/media/eme/mediadrm/MediaDrmCDMProxy.h
@@ -5,17 +5,16 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MediaDrmCDMProxy_h_
 #define MediaDrmCDMProxy_h_
 
 #include <jni.h>
 #include "mozilla/jni/Types.h"
 #include "GeneratedJNINatives.h"
-
 #include "mozilla/CDMProxy.h"
 #include "mozilla/CDMCaps.h"
 #include "mozilla/dom/MediaKeys.h"
 #include "mozilla/MediaDrmProxySupport.h"
 #include "mozilla/UniquePtr.h"
 
 #include "MediaCodec.h"
 #include "nsString.h"
@@ -113,16 +112,18 @@ public:
 
   void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
                              nsTArray<nsCString>& aSessionIds) override;
 
 #ifdef DEBUG
   bool IsOnOwnerThread() override;
 #endif
 
+  const nsString& GetMediaDrmStubId() const;
+
 private:
   virtual ~MediaDrmCDMProxy();
 
   void OnCDMCreated(uint32_t aPromiseId);
 
   struct CreateSessionData {
     MediaKeySessionType mSessionType;
     uint32_t mCreateSessionToken;
@@ -176,9 +177,9 @@ private:
   void md_CreateSession(nsAutoPtr<CreateSessionData> aData);
   void md_UpdateSession(nsAutoPtr<UpdateSessionData> aData);
   void md_CloseSession(nsAutoPtr<SessionOpData> aData);
   void md_Shutdown();
 // =====================================================================
 };
 
 } // namespace mozilla
-#endif // MediaDrmCDMProxy_h_
\ No newline at end of file
+#endif // MediaDrmCDMProxy_h_
--- a/dom/media/eme/mediadrm/MediaDrmProxySupport.cpp
+++ b/dom/media/eme/mediadrm/MediaDrmProxySupport.cpp
@@ -199,16 +199,19 @@ MediaDrmProxySupport::MediaDrmProxySuppo
   : mKeySystem(aKeySystem), mDestroyed(false)
 {
   mJavaCallbacks = MediaDrmProxy::NativeMediaDrmProxyCallbacks::New();
 
   mBridgeProxy =
     MediaDrmProxy::Create(mKeySystem,
                           mJavaCallbacks,
                           MediaPrefs::PDMAndroidRemoteCodecEnabled());
+
+  MOZ_ASSERT(mBridgeProxy, "mBridgeProxy should not be null");
+  mMediaDrmStubId = mBridgeProxy->GetStubId()->ToString();
 }
 
 MediaDrmProxySupport::~MediaDrmProxySupport()
 {
   MOZ_ASSERT(mDestroyed, "Shutdown() should be called before !!");
   MediaDrmJavaCallbacksSupport::DisposeNative(mJavaCallbacks);
 }
 
@@ -276,9 +279,9 @@ MediaDrmProxySupport::Shutdown()
 
   if (mDestroyed) {
     return;
   }
   mBridgeProxy->Destroy();
   mDestroyed = true;
 }
 
-} // namespace mozilla
\ No newline at end of file
+} // namespace mozilla
--- a/dom/media/eme/mediadrm/MediaDrmProxySupport.h
+++ b/dom/media/eme/mediadrm/MediaDrmProxySupport.h
@@ -49,19 +49,21 @@ public:
                      const nsCString& aSessionId,
                      const nsTArray<uint8_t>& aResponse);
 
   void CloseSession(uint32_t aPromiseId,
                     const nsCString& aSessionId);
 
   void Shutdown();
 
+  const nsString& GetMediaDrmStubId() const { return mMediaDrmStubId; }
+
 private:
   const nsString mKeySystem;
   java::MediaDrmProxy::GlobalRef mBridgeProxy;
   java::MediaDrmProxy::NativeMediaDrmProxyCallbacks::GlobalRef mJavaCallbacks;
   DecryptorProxyCallback* mCallback;
   bool mDestroyed;
-
+  nsString mMediaDrmStubId;
 };
 
 } // namespace mozilla
-#endif // MediaDrmProxySupport_H
\ No newline at end of file
+#endif // MediaDrmProxySupport_H
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
@@ -34,20 +34,22 @@ public final class MediaDrmProxy {
     private static final String VORBIS = "audio/vorbis";
     @WrapForJNI
     private static final String VP8 = "video/x-vnd.on2.vp8";
     @WrapForJNI
     private static final String VP9 = "video/x-vnd.on2.vp9";
     @WrapForJNI
     private static final String OPUS = "audio/opus";
 
+    public static ArrayList<MediaDrmProxy> sProxyList = new ArrayList<MediaDrmProxy>();
+
     // A flag to avoid using the native object that has been destroyed.
     private boolean mDestroyed;
     private GeckoMediaDrm mImpl;
-    public static ArrayList<MediaDrmProxy> mProxyList = new ArrayList<MediaDrmProxy>();
+    private String mDrmStubId;
 
     private static boolean isSystemSupported() {
         // Support versions >= LOLLIPOP
         if (AppConstants.Versions.preLollipop) {
             if (DEBUG) Log.d(LOGTAG, "System Not supported !!, current SDK version is " + Build.VERSION.SDK_INT);
             return false;
         }
         return true;
@@ -245,29 +247,36 @@ public final class MediaDrmProxy {
     public boolean isDestroyed() {
         return mDestroyed;
     }
 
     @WrapForJNI(calledFrom = "gecko")
     public static MediaDrmProxy create(String keySystem,
                                        Callbacks nativeCallbacks,
                                        boolean isRemote) {
-        // TODO: Will implement {Local,Remote}MediaDrmBridge instantiation by
-        // '''isRemote''' flag in Bug 1307818.
-        MediaDrmProxy proxy = new MediaDrmProxy(keySystem, nativeCallbacks);
+        MediaDrmProxy proxy = new MediaDrmProxy(keySystem, nativeCallbacks, isRemote);
         return proxy;
     }
 
-    MediaDrmProxy(String keySystem, Callbacks nativeCallbacks) {
+    MediaDrmProxy(String keySystem, Callbacks nativeCallbacks, boolean isRemote) {
         if (DEBUG) Log.d(LOGTAG, "Constructing MediaDrmProxy");
-        // TODO: Bug 1306185 will implement the LocalMediaDrmBridge as an impl
-        // of GeckoMediaDrm for in-process decoding mode.
-        //mImpl = new LocalMediaDrmBridge(keySystem);
-        mImpl.setCallbacks(new MediaDrmProxyCallbacks(this, nativeCallbacks));
-        mProxyList.add(this);
+        try {
+            mDrmStubId = UUID.randomUUID().toString();
+            if (isRemote) {
+                IMediaDrmBridge remoteBridge =
+                    RemoteManager.getInstance().createRemoteMediaDrmBridge(keySystem, mDrmStubId);
+                mImpl = new RemoteMediaDrmBridge(remoteBridge);
+            } else {
+                mImpl = new LocalMediaDrmBridge(keySystem);
+            }
+            mImpl.setCallbacks(new MediaDrmProxyCallbacks(this, nativeCallbacks));
+            sProxyList.add(this);
+        } catch (Exception e) {
+            Log.e(LOGTAG, "Constructing MediaDrmProxy ... error", e);
+        }
     }
 
     @WrapForJNI
     private void createSession(int createSessionToken,
                                int promiseId,
                                String initDataType,
                                byte[] initData) {
         if (DEBUG) Log.d(LOGTAG, "createSession, promiseId = " + promiseId);
@@ -284,24 +293,46 @@ public final class MediaDrmProxy {
     }
 
     @WrapForJNI
     private void closeSession(int promiseId, String sessionId) {
         if (DEBUG) Log.d(LOGTAG, "closeSession, primiseId(" + promiseId  + "sessionId(" + sessionId + ")");
         mImpl.closeSession(promiseId, sessionId);
     }
 
+    @WrapForJNI(calledFrom = "gecko")
+    private String getStubId() {
+        return mDrmStubId;
+    }
+
+    // Get corresponding MediaCrypto object by a generated UUID for MediaCodec.
+    // Will be called on MediaFormatReader's TaskQueue.
+    @WrapForJNI
+    public static MediaCrypto getMediaCrypto(String stubId) {
+        for (MediaDrmProxy proxy : sProxyList) {
+            if (proxy.getStubId().equals(stubId)) {
+                return proxy.getMediaCryptoFromBridge();
+            }
+        }
+        if (DEBUG) Log.d(LOGTAG, " NULL crytpo ");
+        return null;
+    }
+
     @WrapForJNI // Called when natvie object is destroyed.
     private void destroy() {
         if (DEBUG) Log.d(LOGTAG, "destroy!! Native object is destroyed.");
         if (mDestroyed) {
             return;
         }
         mDestroyed = true;
         release();
     }
 
     private void release() {
         if (DEBUG) Log.d(LOGTAG, "release");
-        mProxyList.remove(this);
+        sProxyList.remove(this);
         mImpl.release();
     }
+
+    private MediaCrypto getMediaCryptoFromBridge() {
+        return mImpl != null ? mImpl.getMediaCrypto() : null;
+    }
 }
--- a/widget/android/fennec/FennecJNIWrappers.cpp
+++ b/widget/android/fennec/FennecJNIWrappers.cpp
@@ -294,16 +294,32 @@ auto MediaDrmProxy::CreateSession(int32_
 constexpr char MediaDrmProxy::Destroy_t::name[];
 constexpr char MediaDrmProxy::Destroy_t::signature[];
 
 auto MediaDrmProxy::Destroy() const -> void
 {
     return mozilla::jni::Method<Destroy_t>::Call(MediaDrmProxy::mCtx, nullptr);
 }
 
+constexpr char MediaDrmProxy::GetMediaCrypto_t::name[];
+constexpr char MediaDrmProxy::GetMediaCrypto_t::signature[];
+
+auto MediaDrmProxy::GetMediaCrypto(mozilla::jni::String::Param a0) -> mozilla::jni::Object::LocalRef
+{
+    return mozilla::jni::Method<GetMediaCrypto_t>::Call(MediaDrmProxy::Context(), nullptr, a0);
+}
+
+constexpr char MediaDrmProxy::GetStubId_t::name[];
+constexpr char MediaDrmProxy::GetStubId_t::signature[];
+
+auto MediaDrmProxy::GetStubId() const -> mozilla::jni::String::LocalRef
+{
+    return mozilla::jni::Method<GetStubId_t>::Call(MediaDrmProxy::mCtx, nullptr);
+}
+
 constexpr char MediaDrmProxy::IsSchemeSupported_t::name[];
 constexpr char MediaDrmProxy::IsSchemeSupported_t::signature[];
 
 auto MediaDrmProxy::IsSchemeSupported(mozilla::jni::String::Param a0) -> bool
 {
     return mozilla::jni::Method<IsSchemeSupported_t>::Call(MediaDrmProxy::Context(), nullptr, a0);
 }
 
--- a/widget/android/fennec/FennecJNIWrappers.h
+++ b/widget/android/fennec/FennecJNIWrappers.h
@@ -1052,16 +1052,55 @@ public:
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =
                 mozilla::jni::DispatchTarget::CURRENT;
     };
 
     auto Destroy() const -> void;
 
+    struct GetMediaCrypto_t {
+        typedef MediaDrmProxy Owner;
+        typedef mozilla::jni::Object::LocalRef ReturnType;
+        typedef mozilla::jni::Object::Param SetterType;
+        typedef mozilla::jni::Args<
+                mozilla::jni::String::Param> Args;
+        static constexpr char name[] = "getMediaCrypto";
+        static constexpr char signature[] =
+                "(Ljava/lang/String;)Landroid/media/MediaCrypto;";
+        static const bool isStatic = true;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::ANY;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    static auto GetMediaCrypto(mozilla::jni::String::Param) -> mozilla::jni::Object::LocalRef;
+
+    struct GetStubId_t {
+        typedef MediaDrmProxy Owner;
+        typedef mozilla::jni::String::LocalRef ReturnType;
+        typedef mozilla::jni::String::Param SetterType;
+        typedef mozilla::jni::Args<> Args;
+        static constexpr char name[] = "getStubId";
+        static constexpr char signature[] =
+                "()Ljava/lang/String;";
+        static const bool isStatic = false;
+        static const mozilla::jni::ExceptionMode exceptionMode =
+                mozilla::jni::ExceptionMode::ABORT;
+        static const mozilla::jni::CallingThread callingThread =
+                mozilla::jni::CallingThread::GECKO;
+        static const mozilla::jni::DispatchTarget dispatchTarget =
+                mozilla::jni::DispatchTarget::CURRENT;
+    };
+
+    auto GetStubId() const -> mozilla::jni::String::LocalRef;
+
     struct IsSchemeSupported_t {
         typedef MediaDrmProxy Owner;
         typedef bool ReturnType;
         typedef bool SetterType;
         typedef mozilla::jni::Args<
                 mozilla::jni::String::Param> Args;
         static constexpr char name[] = "isSchemeSupported";
         static constexpr char signature[] =