Bug 1306219-Part2 Add utility function to invoke MediaDrm and MediaCrypto checking API.
MozReview-Commit-ID: FFDjmKQh2gP
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 {