18240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber/* 28240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * Copyright 2012, The Android Open Source Project 38240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * 48240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 58240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * you may not use this file except in compliance with the License. 68240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * You may obtain a copy of the License at 78240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * 88240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 98240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * 108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * Unless required by applicable law or agreed to in writing, software 118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * See the License for the specific language governing permissions and 148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber * limitations under the License. 158240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber */ 168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 178240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber//#define LOG_NDEBUG 0 1807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber#define LOG_TAG "MediaCrypto-JNI" 198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <utils/Log.h> 208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber#include "android_media_MediaCrypto.h" 228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 238240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include "android_runtime/AndroidRuntime.h" 248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include "jni.h" 258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include "JNIHelp.h" 268240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <binder/IServiceManager.h> 28dc614f86a5a61d0b4287796dfa028c637f615d34Jeff Tinker#include <cutils/properties.h> 298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <media/ICrypto.h> 30dc614f86a5a61d0b4287796dfa028c637f615d34Jeff Tinker#include <media/IMediaDrmService.h> 318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <media/stagefright/foundation/ADebug.h> 328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubernamespace android { 348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstruct fields_t { 368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jfieldID context; 378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}; 388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic fields_t gFields; 408240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 418240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic sp<JCrypto> getCrypto(JNIEnv *env, jobject thiz) { 42075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (JCrypto *)env->GetLongField(thiz, gFields.context); 438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas HuberJCrypto::JCrypto( 468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber JNIEnv *env, jobject thiz, 478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const uint8_t uuid[16], const void *initData, size_t initSize) { 488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 498240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber mCrypto = MakeCrypto(uuid, initData, initSize); 518240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas HuberJCrypto::~JCrypto() { 548240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber mCrypto.clear(); 558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env->DeleteWeakGlobalRef(mObject); 598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber mObject = NULL; 608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static 638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubersp<ICrypto> JCrypto::MakeCrypto() { 648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 65d12b7c0600a9568549f8571c43dcfa22cdbb03acJeff Tinker 66d12b7c0600a9568549f8571c43dcfa22cdbb03acJeff Tinker sp<IBinder> binder = sm->getService(String16("media.drm")); 67d12b7c0600a9568549f8571c43dcfa22cdbb03acJeff Tinker sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder); 68d12b7c0600a9568549f8571c43dcfa22cdbb03acJeff Tinker if (service == NULL) { 69d12b7c0600a9568549f8571c43dcfa22cdbb03acJeff Tinker return NULL; 708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 718240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 72d12b7c0600a9568549f8571c43dcfa22cdbb03acJeff Tinker sp<ICrypto> crypto = service->makeCrypto(); 7390defba919e8e969a9963bf401a7b144d869accfJeff Tinker if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) { 748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return NULL; 758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return crypto; 788240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 798240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static 818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubersp<ICrypto> JCrypto::MakeCrypto( 828240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const uint8_t uuid[16], const void *initData, size_t initSize) { 838240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto = MakeCrypto(); 848240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 858240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (crypto == NULL) { 868240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return NULL; 878240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 888240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 898240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber status_t err = crypto->createPlugin(uuid, initData, initSize); 908240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 918240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (err != OK) { 928240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return NULL; 938240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 948240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 958240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return crypto; 968240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 978240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberbool JCrypto::requiresSecureDecoderComponent(const char *mime) const { 998240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (mCrypto == NULL) { 1008240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return false; 1018240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 1028240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1038240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return mCrypto->requiresSecureDecoderComponent(mime); 1048240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1058240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static 1078240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberbool JCrypto::IsCryptoSchemeSupported(const uint8_t uuid[16]) { 1088240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto = MakeCrypto(); 1098240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (crypto == NULL) { 1118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return false; 1128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 1138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return crypto->isCryptoSchemeSupported(uuid); 1158240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1178240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatus_t JCrypto::initCheck() const { 1188240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return mCrypto == NULL ? NO_INIT : OK; 1198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static 1228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubersp<ICrypto> JCrypto::GetCrypto(JNIEnv *env, jobject obj) { 12307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber jclass clazz = env->FindClass("android/media/MediaCrypto"); 1248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber CHECK(clazz != NULL); 1258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1268240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (!env->IsInstanceOf(obj, clazz)) { 1278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return NULL; 1288240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 1298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<JCrypto> jcrypto = getCrypto(env, obj); 1318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto == NULL) { 1338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return NULL; 1348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 1358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return jcrypto->mCrypto; 1378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1396f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker// JNI conversion utilities 1406f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinkerstatic Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray) { 1416f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker Vector<uint8_t> vector; 1426f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker size_t length = env->GetArrayLength(byteArray); 1436f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker vector.insertAt((size_t)0, length); 1446f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray()); 1456f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker return vector; 1466f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker} 1476f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 1488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} // namespace android 1498240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberusing namespace android; 1518240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic sp<JCrypto> setCrypto( 1538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber JNIEnv *env, jobject thiz, const sp<JCrypto> &crypto) { 154075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat sp<JCrypto> old = (JCrypto *)env->GetLongField(thiz, gFields.context); 1558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (crypto != NULL) { 1568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto->incStrong(thiz); 1578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 1588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (old != NULL) { 1598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber old->decStrong(thiz); 1608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 161075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, gFields.context, (jlong)crypto.get()); 1628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return old; 1648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1658240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 16607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_release(JNIEnv *env, jobject thiz) { 1678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber setCrypto(env, thiz, NULL); 1688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 17007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_native_init(JNIEnv *env) { 17107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber jclass clazz = env->FindClass("android/media/MediaCrypto"); 1728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber CHECK(clazz != NULL); 1738240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 174075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat gFields.context = env->GetFieldID(clazz, "mNativeContext", "J"); 1758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber CHECK(gFields.context != NULL); 1768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 1778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 17807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_native_setup( 1798240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber JNIEnv *env, jobject thiz, 1808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jbyteArray uuidObj, jbyteArray initDataObj) { 1818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jsize uuidLength = env->GetArrayLength(uuidObj); 1828240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1838240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (uuidLength != 16) { 1848240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jniThrowException( 1858240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env, 1868240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "java/lang/IllegalArgumentException", 1878240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber NULL); 1888240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return; 1898240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 1908240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1918240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jboolean isCopy; 1928240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jbyte *uuid = env->GetByteArrayElements(uuidObj, &isCopy); 1938240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 19407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber jsize initDataLength = 0; 19507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber jbyte *initData = NULL; 19607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber 19707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (initDataObj != NULL) { 19807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber initDataLength = env->GetArrayLength(initDataObj); 19907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber initData = env->GetByteArrayElements(initDataObj, &isCopy); 20007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 2018240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2028240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<JCrypto> crypto = new JCrypto( 2038240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env, thiz, (const uint8_t *)uuid, initData, initDataLength); 2048240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2058240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber status_t err = crypto->initCheck(); 2068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 20707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber if (initDataObj != NULL) { 20807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber env->ReleaseByteArrayElements(initDataObj, initData, 0); 20907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber initData = NULL; 21007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber } 2118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env->ReleaseByteArrayElements(uuidObj, uuid, 0); 2138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber uuid = NULL; 2148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2158240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (err != OK) { 2168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jniThrowException( 2178240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env, 21860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber "android/media/MediaCryptoException", 2198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "Failed to instantiate crypto object."); 2208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return; 2218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 2228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2238240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber setCrypto(env,thiz, crypto); 2248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 2258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 22607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_native_finalize( 2278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber JNIEnv *env, jobject thiz) { 22807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber android_media_MediaCrypto_release(env, thiz); 2298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 2308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 23160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jboolean android_media_MediaCrypto_isCryptoSchemeSupportedNative( 2325a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe JNIEnv *env, jobject /* thiz */, jbyteArray uuidObj) { 2338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jsize uuidLength = env->GetArrayLength(uuidObj); 2348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (uuidLength != 16) { 2368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jniThrowException( 2378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env, 2388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "java/lang/IllegalArgumentException", 2398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber NULL); 240075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return JNI_FALSE; 2418240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 2428240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jboolean isCopy; 2448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jbyte *uuid = env->GetByteArrayElements(uuidObj, &isCopy); 2458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber bool result = JCrypto::IsCryptoSchemeSupported((const uint8_t *)uuid); 2478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env->ReleaseByteArrayElements(uuidObj, uuid, 0); 2498240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber uuid = NULL; 2508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 251075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return result ? JNI_TRUE : JNI_FALSE; 2528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 2538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 25407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jboolean android_media_MediaCrypto_requiresSecureDecoderComponent( 2558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber JNIEnv *env, jobject thiz, jstring mimeObj) { 2568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (mimeObj == NULL) { 2578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 258075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return JNI_FALSE; 2598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 2608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<JCrypto> crypto = getCrypto(env, thiz); 2628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (crypto == NULL) { 2648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 265075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return JNI_FALSE; 2668240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 2678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const char *mime = env->GetStringUTFChars(mimeObj, NULL); 2698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (mime == NULL) { 271075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return JNI_FALSE; 2728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 2738240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber bool result = crypto->requiresSecureDecoderComponent(mime); 2758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber env->ReleaseStringUTFChars(mimeObj, mime); 2778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber mime = NULL; 2788240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 279075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return result ? JNI_TRUE : JNI_FALSE; 2808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 2818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 2826f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinkerstatic void android_media_MediaCrypto_setMediaDrmSession( 2836f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker JNIEnv *env, jobject thiz, jbyteArray jsessionId) { 2846f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker if (jsessionId == NULL) { 2856f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 2866f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker return; 2876f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker } 2886f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 2896f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker sp<ICrypto> crypto = JCrypto::GetCrypto(env, thiz); 2906f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 2916f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker if (crypto == NULL) { 2926f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 2936f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker return; 2946f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker } 2956f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 2966f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId)); 2976f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 2986f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker status_t err = crypto->setMediaDrmSession(sessionId); 2996f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 300025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker if (err != OK) { 301025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker String8 msg("setMediaDrmSession failed"); 302025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker if (err == ERROR_DRM_SESSION_NOT_OPENED) { 303025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker msg += ": session not opened"; 304025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker } else if (err == ERROR_UNSUPPORTED) { 305025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker msg += ": not supported by this crypto scheme"; 306025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker } else if (err == NO_INIT) { 307025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker msg += ": crypto plugin not initialized"; 308025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker } else { 309025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker msg.appendFormat(": general failure (%d)", err); 310025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker } 311025af8b0de1c4697a54f6b7363e27111a00eb284Jeff Tinker jniThrowException(env, "android/media/MediaCryptoException", msg.string()); 3126f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker } 3136f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker} 3146f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 31576f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = { 31607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber { "release", "()V", (void *)android_media_MediaCrypto_release }, 31707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber { "native_init", "()V", (void *)android_media_MediaCrypto_native_init }, 3188240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 3198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber { "native_setup", "([B[B)V", 32007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber (void *)android_media_MediaCrypto_native_setup }, 3218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 3228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber { "native_finalize", "()V", 32307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber (void *)android_media_MediaCrypto_native_finalize }, 3248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 32560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber { "isCryptoSchemeSupportedNative", "([B)Z", 32660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber (void *)android_media_MediaCrypto_isCryptoSchemeSupportedNative }, 3278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 3288240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber { "requiresSecureDecoderComponent", "(Ljava/lang/String;)Z", 32907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber (void *)android_media_MediaCrypto_requiresSecureDecoderComponent }, 3306f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker 3316f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker { "setMediaDrmSession", "([B)V", 3326f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker (void *)android_media_MediaCrypto_setMediaDrmSession }, 3338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}; 3348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 3358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberint register_android_media_Crypto(JNIEnv *env) { 3368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return AndroidRuntime::registerNativeMethods(env, 33707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "android/media/MediaCrypto", gMethods, NELEM(gMethods)); 3388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber} 3398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 340