android_media_MediaCrypto.cpp revision 07ea426e3ae8915ca6bf67135f523f42cd920af0
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>
288240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <media/ICrypto.h>
298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <media/IMediaPlayerService.h>
308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <media/stagefright/foundation/ADebug.h>
318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubernamespace android {
338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstruct fields_t {
358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jfieldID context;
368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber};
378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic fields_t gFields;
398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
408240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic sp<JCrypto> getCrypto(JNIEnv *env, jobject thiz) {
418240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return (JCrypto *)env->GetIntField(thiz, gFields.context);
428240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas HuberJCrypto::JCrypto(
458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz,
468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        const uint8_t uuid[16], const void *initData, size_t initSize) {
478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    mObject = env->NewWeakGlobalRef(thiz);
488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
498240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    mCrypto = MakeCrypto(uuid, initData, initSize);
508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
518240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas HuberJCrypto::~JCrypto() {
538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    mCrypto.clear();
548240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->DeleteWeakGlobalRef(mObject);
588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    mObject = NULL;
598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static
628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubersp<ICrypto> JCrypto::MakeCrypto() {
638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<IServiceManager> sm = defaultServiceManager();
648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
658240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<IBinder> binder =
668240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        sm->getService(String16("media.player"));
678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<IMediaPlayerService> service =
698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        interface_cast<IMediaPlayerService>(binder);
708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
718240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (service == NULL) {
728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return NULL;
738240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<ICrypto> crypto = service->makeCrypto();
768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (crypto == NULL || crypto->initCheck() != OK) {
788240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return NULL;
798240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return crypto;
828240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
838240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
848240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static
858240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubersp<ICrypto> JCrypto::MakeCrypto(
868240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        const uint8_t uuid[16], const void *initData, size_t initSize) {
878240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<ICrypto> crypto = MakeCrypto();
888240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
898240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (crypto == NULL) {
908240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return NULL;
918240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
928240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
938240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    status_t err = crypto->createPlugin(uuid, initData, initSize);
948240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
958240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (err != OK) {
968240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return NULL;
978240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
998240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return crypto;
1008240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1018240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1028240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberbool JCrypto::requiresSecureDecoderComponent(const char *mime) const {
1038240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (mCrypto == NULL) {
1048240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
1058240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1078240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return mCrypto->requiresSecureDecoderComponent(mime);
1088240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1098240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static
1118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberbool JCrypto::IsCryptoSchemeSupported(const uint8_t uuid[16]) {
1128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<ICrypto> crypto = MakeCrypto();
1138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (crypto == NULL) {
1158240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
1168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1178240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1188240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return crypto->isCryptoSchemeSupported(uuid);
1198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatus_t JCrypto::initCheck() const {
1228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return mCrypto == NULL ? NO_INIT : OK;
1238240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber// static
1268240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Hubersp<ICrypto> JCrypto::GetCrypto(JNIEnv *env, jobject obj) {
12707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    jclass clazz = env->FindClass("android/media/MediaCrypto");
1288240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    CHECK(clazz != NULL);
1298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (!env->IsInstanceOf(obj, clazz)) {
1318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return NULL;
1328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<JCrypto> jcrypto = getCrypto(env, obj);
1358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (jcrypto == NULL) {
1378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return NULL;
1388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1408240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return jcrypto->mCrypto;
1418240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1428240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}  // namespace android
1448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberusing namespace android;
1468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic sp<JCrypto> setCrypto(
1488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz, const sp<JCrypto> &crypto) {
1498240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<JCrypto> old = (JCrypto *)env->GetIntField(thiz, gFields.context);
1508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (crypto != NULL) {
1518240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        crypto->incStrong(thiz);
1528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (old != NULL) {
1548240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        old->decStrong(thiz);
1558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->SetIntField(thiz, gFields.context, (int)crypto.get());
1578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return old;
1598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
16107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_release(JNIEnv *env, jobject thiz) {
1628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    setCrypto(env, thiz, NULL);
1638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
16507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_native_init(JNIEnv *env) {
16607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    jclass clazz = env->FindClass("android/media/MediaCrypto");
1678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    CHECK(clazz != NULL);
1688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
1708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    CHECK(gFields.context != NULL);
1718240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
17307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_native_setup(
1748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz,
1758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jbyteArray uuidObj, jbyteArray initDataObj) {
1768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jsize uuidLength = env->GetArrayLength(uuidObj);
1778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1788240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (uuidLength != 16) {
1798240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(
1808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                env,
1818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "java/lang/IllegalArgumentException",
1828240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                NULL);
1838240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return;
1848240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
1858240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1868240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jboolean isCopy;
1878240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jbyte *uuid = env->GetByteArrayElements(uuidObj, &isCopy);
1888240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
18907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    jsize initDataLength = 0;
19007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    jbyte *initData = NULL;
19107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
19207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (initDataObj != NULL) {
19307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        initDataLength = env->GetArrayLength(initDataObj);
19407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        initData = env->GetByteArrayElements(initDataObj, &isCopy);
19507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
1968240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1978240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<JCrypto> crypto = new JCrypto(
1988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber            env, thiz, (const uint8_t *)uuid, initData, initDataLength);
1998240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2008240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    status_t err = crypto->initCheck();
2018240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
20207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    if (initDataObj != NULL) {
20307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        env->ReleaseByteArrayElements(initDataObj, initData, 0);
20407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        initData = NULL;
20507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
2068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2078240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
2088240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    uuid = NULL;
2098240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (err != OK) {
2118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(
2128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                env,
2138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "java/io/IOException",
2148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "Failed to instantiate crypto object.");
2158240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return;
2168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2178240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2188240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    setCrypto(env,thiz, crypto);
2198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
22107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic void android_media_MediaCrypto_native_finalize(
2228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz) {
22307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    android_media_MediaCrypto_release(env, thiz);
2248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
22607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jboolean android_media_MediaCrypto_isCryptoSchemeSupported(
2278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz, jbyteArray uuidObj) {
2288240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jsize uuidLength = env->GetArrayLength(uuidObj);
2298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (uuidLength != 16) {
2318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(
2328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                env,
2338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "java/lang/IllegalArgumentException",
2348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                NULL);
2358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jboolean isCopy;
2398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jbyte *uuid = env->GetByteArrayElements(uuidObj, &isCopy);
2408240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2418240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    bool result = JCrypto::IsCryptoSchemeSupported((const uint8_t *)uuid);
2428240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
2448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    uuid = NULL;
2458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return result;
2478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
24907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberstatic jboolean android_media_MediaCrypto_requiresSecureDecoderComponent(
2508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz, jstring mimeObj) {
2518240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (mimeObj == NULL) {
2528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
2538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2548240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<JCrypto> crypto = getCrypto(env, thiz);
2578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (crypto == NULL) {
2598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
2608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    const char *mime = env->GetStringUTFChars(mimeObj, NULL);
2648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2658240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (mime == NULL) {
2668240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    bool result = crypto->requiresSecureDecoderComponent(mime);
2708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2718240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseStringUTFChars(mimeObj, mime);
2728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    mime = NULL;
2738240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return result;
2758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic JNINativeMethod gMethods[] = {
27807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "release", "()V", (void *)android_media_MediaCrypto_release },
27907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    { "native_init", "()V", (void *)android_media_MediaCrypto_native_init },
2808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "native_setup", "([B[B)V",
28207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaCrypto_native_setup },
2838240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2848240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "native_finalize", "()V",
28507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaCrypto_native_finalize },
2868240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2878240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "isCryptoSchemeSupported", "([B)Z",
28807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaCrypto_isCryptoSchemeSupported },
2898240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2908240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "requiresSecureDecoderComponent", "(Ljava/lang/String;)Z",
29107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      (void *)android_media_MediaCrypto_requiresSecureDecoderComponent },
2928240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber};
2938240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2948240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberint register_android_media_Crypto(JNIEnv *env) {
2958240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return AndroidRuntime::registerNativeMethods(env,
29607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber                "android/media/MediaCrypto", gMethods, NELEM(gMethods));
2978240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
299