Bug 1306219-Part2 Add utility function to invoke MediaDrm and MediaCrypto checking API. draft
authorJames Cheng <jacheng@mozilla.com>
Wed, 26 Oct 2016 10:55:16 +0800
changeset 429576 4fadc919d2dbaa3bc1a7c52b35378613be4b1003
parent 429408 b1b18f25c0ea69d9ee57c4198d577dfcd0129ce1
child 429577 4ebebc9346d09f7038a2269ee899a1d02696dc28
push id33604
push userbmo:jacheng@mozilla.com
push dateWed, 26 Oct 2016 04:56:25 +0000
bugs1306219
milestone52.0a1
Bug 1306219-Part2 Add utility function to invoke MediaDrm and MediaCrypto checking API. MozReview-Commit-ID: FFDjmKQh2gP
mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
mobile/android/base/moz.build
widget/android/fennec/FennecJNIWrappers.cpp
widget/android/fennec/FennecJNIWrappers.h
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
@@ -0,0 +1,91 @@
+/* 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/. */
+
+
+package org.mozilla.gecko.media;
+
+import java.util.UUID;
+
+import org.mozilla.gecko.annotation.WrapForJNI;
+import org.mozilla.gecko.AppConstants;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaCrypto;
+import android.media.MediaDrm;
+import android.util.Log;
+import android.os.Build;
+
+public final class MediaDrmProxy {
+    private static final String LOGTAG = "GeckoMediaDrmProxy";
+    private static final boolean DEBUG = false;
+    private static final UUID WIDEVINE_SCHEME_UUID =
+            new UUID(0xedef8ba979d64aceL, 0xa3c827dcd51d21edL);
+
+    private static final String WIDEVINE_KEY_SYSTEM = "com.widevine.alpha";
+    @WrapForJNI
+    private static final String AAC = "audio/mp4a-latm";
+    @WrapForJNI
+    private static final String AVC = "video/avc";
+    @WrapForJNI
+    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";
+
+    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;
+    }
+
+    @WrapForJNI
+    public static boolean isSchemeSupported(String keySystem) {
+        if (!isSystemSupported()) {
+            return false;
+        }
+        if (keySystem.equals(WIDEVINE_KEY_SYSTEM)) {
+            return MediaDrm.isCryptoSchemeSupported(WIDEVINE_SCHEME_UUID)
+                    && MediaCrypto.isCryptoSchemeSupported(WIDEVINE_SCHEME_UUID);
+        }
+        if (DEBUG) Log.d(LOGTAG, "isSchemeSupported key sytem = " + keySystem);
+        return false;
+    }
+
+    @WrapForJNI
+    public static boolean IsCryptoSchemeSupported(String keySystem,
+                                                  String container) {
+        if (!isSystemSupported()) {
+            return false;
+        }
+        if (keySystem.equals(WIDEVINE_KEY_SYSTEM)) {
+            return MediaDrm.isCryptoSchemeSupported(WIDEVINE_SCHEME_UUID, container);
+        }
+        if (DEBUG) Log.d(LOGTAG, "cannot decrypt key sytem = " + keySystem + ", container = " + container);
+        return false;
+    }
+
+    @WrapForJNI
+    public static boolean CanDecode(String mimeType) {
+        for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+            if (info.isEncoder()) {
+                continue;
+            }
+            for (String m : info.getSupportedTypes()) {
+                if (m.equals(mimeType)) {
+                  return true;
+                }
+            }
+        }
+        if (DEBUG) Log.d(LOGTAG, "cannot decode mimetype = " + mimeType);
+        return false;
+    }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -552,16 +552,17 @@ gbjar.sources += ['java/org/mozilla/geck
     'media/AsyncCodec.java',
     'media/AsyncCodecFactory.java',
     'media/AudioFocusAgent.java',
     'media/Codec.java',
     'media/CodecProxy.java',
     'media/FormatParam.java',
     'media/JellyBeanAsyncCodec.java',
     'media/MediaControlService.java',
+    'media/MediaDrmProxy.java',
     'media/MediaManager.java',
     'media/RemoteManager.java',
     'media/Sample.java',
     'media/SamplePool.java',
     'media/VideoPlayer.java',
     'MediaCastingBar.java',
     'MemoryMonitor.java',
     'menu/GeckoMenu.java',
--- a/widget/android/fennec/FennecJNIWrappers.cpp
+++ b/widget/android/fennec/FennecJNIWrappers.cpp
@@ -243,16 +243,55 @@ constexpr char CodecProxy::NativeCallbac
 constexpr char CodecProxy::NativeCallbacks::OnInputExhausted_t::signature[];
 
 constexpr char CodecProxy::NativeCallbacks::OnOutput_t::name[];
 constexpr char CodecProxy::NativeCallbacks::OnOutput_t::signature[];
 
 constexpr char CodecProxy::NativeCallbacks::OnOutputFormatChanged_t::name[];
 constexpr char CodecProxy::NativeCallbacks::OnOutputFormatChanged_t::signature[];
 
+const char MediaDrmProxy::name[] =
+        "org/mozilla/gecko/media/MediaDrmProxy";
+
+constexpr char MediaDrmProxy::CanDecode_t::name[];
+constexpr char MediaDrmProxy::CanDecode_t::signature[];
+
+auto MediaDrmProxy::CanDecode(mozilla::jni::String::Param a0) -> bool
+{
+    return mozilla::jni::Method<CanDecode_t>::Call(MediaDrmProxy::Context(), nullptr, a0);
+}
+
+constexpr char MediaDrmProxy::IsCryptoSchemeSupported_t::name[];
+constexpr char MediaDrmProxy::IsCryptoSchemeSupported_t::signature[];
+
+auto MediaDrmProxy::IsCryptoSchemeSupported(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> bool
+{
+    return mozilla::jni::Method<IsCryptoSchemeSupported_t>::Call(MediaDrmProxy::Context(), nullptr, a0, a1);
+}
+
+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);
+}
+
+const char16_t MediaDrmProxy::AAC[] = u"audio/mp4a-latm";
+
+const char16_t MediaDrmProxy::AVC[] = u"video/avc";
+
+const char16_t MediaDrmProxy::OPUS[] = u"audio/opus";
+
+const char16_t MediaDrmProxy::VORBIS[] = u"audio/vorbis";
+
+const char16_t MediaDrmProxy::VP8[] = u"video/x-vnd.on2.vp8";
+
+const char16_t MediaDrmProxy::VP9[] = u"video/x-vnd.on2.vp9";
+
 const char Sample::name[] =
         "org/mozilla/gecko/media/Sample";
 
 constexpr char Sample::WriteToByteBuffer_t::name[];
 constexpr char Sample::WriteToByteBuffer_t::signature[];
 
 auto Sample::WriteToByteBuffer(mozilla::jni::ByteBuffer::Param a0) const -> void
 {
--- a/widget/android/fennec/FennecJNIWrappers.h
+++ b/widget/android/fennec/FennecJNIWrappers.h
@@ -917,16 +917,101 @@ public:
     };
 
     static const mozilla::jni::CallingThread callingThread =
             mozilla::jni::CallingThread::ANY;
 
     template<class Impl> class Natives;
 };
 
+class MediaDrmProxy : public mozilla::jni::ObjectBase<MediaDrmProxy>
+{
+public:
+    static const char name[];
+
+    explicit MediaDrmProxy(const Context& ctx) : ObjectBase<MediaDrmProxy>(ctx) {}
+
+    struct CanDecode_t {
+        typedef MediaDrmProxy Owner;
+        typedef bool ReturnType;
+        typedef bool SetterType;
+        typedef mozilla::jni::Args<
+                mozilla::jni::String::Param> Args;
+        static constexpr char name[] = "CanDecode";
+        static constexpr char signature[] =
+                "(Ljava/lang/String;)Z";
+        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 CanDecode(mozilla::jni::String::Param) -> bool;
+
+    struct IsCryptoSchemeSupported_t {
+        typedef MediaDrmProxy Owner;
+        typedef bool ReturnType;
+        typedef bool SetterType;
+        typedef mozilla::jni::Args<
+                mozilla::jni::String::Param,
+                mozilla::jni::String::Param> Args;
+        static constexpr char name[] = "IsCryptoSchemeSupported";
+        static constexpr char signature[] =
+                "(Ljava/lang/String;Ljava/lang/String;)Z";
+        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 IsCryptoSchemeSupported(mozilla::jni::String::Param, mozilla::jni::String::Param) -> bool;
+
+    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[] =
+                "(Ljava/lang/String;)Z";
+        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 IsSchemeSupported(mozilla::jni::String::Param) -> bool;
+
+    static const char16_t AAC[];
+
+    static const char16_t AVC[];
+
+    static const char16_t OPUS[];
+
+    static const char16_t VORBIS[];
+
+    static const char16_t VP8[];
+
+    static const char16_t VP9[];
+
+    static const mozilla::jni::CallingThread callingThread =
+            mozilla::jni::CallingThread::ANY;
+
+};
+
 class Sample : public mozilla::jni::ObjectBase<Sample>
 {
 public:
     static const char name[];
 
     explicit Sample(const Context& ctx) : ObjectBase<Sample>(ctx) {}
 
     struct WriteToByteBuffer_t {