android_media_MediaCrypto.cpp revision 8240d9239d9aabed75c49f9d4d69fd8a5fe4c899
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
188240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#define LOG_TAG "Crypto-JNI"
198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include <utils/Log.h>
208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber#include "android_media_Crypto.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) {
1278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jclass clazz = env->FindClass("android/media/Crypto");
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
1618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic void android_media_Crypto_release(JNIEnv *env, jobject thiz) {
1628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    setCrypto(env, thiz, NULL);
1638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
1648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1658240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic void android_media_Crypto_native_init(JNIEnv *env) {
1668240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jclass clazz = env->FindClass("android/media/Crypto");
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
1738240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic void android_media_Crypto_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
1898240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jsize initDataLength = env->GetArrayLength(initDataObj);
1908240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jbyte *initData = env->GetByteArrayElements(initDataObj, &isCopy);
1918240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1928240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<JCrypto> crypto = new JCrypto(
1938240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber            env, thiz, (const uint8_t *)uuid, initData, initDataLength);
1948240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1958240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    status_t err = crypto->initCheck();
1968240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
1978240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseByteArrayElements(initDataObj, initData, 0);
1988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    initData = NULL;
1998240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2008240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
2018240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    uuid = NULL;
2028240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2038240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (err != OK) {
2048240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(
2058240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                env,
2068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "java/io/IOException",
2078240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "Failed to instantiate crypto object.");
2088240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return;
2098240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    setCrypto(env,thiz, crypto);
2128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic void android_media_Crypto_native_finalize(
2158240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz) {
2168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    android_media_Crypto_release(env, thiz);
2178240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2188240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic jboolean android_media_Crypto_isCryptoSchemeSupported(
2208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz, jbyteArray uuidObj) {
2218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jsize uuidLength = env->GetArrayLength(uuidObj);
2228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2238240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (uuidLength != 16) {
2248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(
2258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                env,
2268240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "java/lang/IllegalArgumentException",
2278240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                NULL);
2288240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jboolean isCopy;
2328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    jbyte *uuid = env->GetByteArrayElements(uuidObj, &isCopy);
2338240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2348240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    bool result = JCrypto::IsCryptoSchemeSupported((const uint8_t *)uuid);
2358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2368240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseByteArrayElements(uuidObj, uuid, 0);
2378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    uuid = NULL;
2388240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return result;
2408240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2418240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2428240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic jboolean android_media_Crypto_requiresSecureDecoderComponent(
2438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        JNIEnv *env, jobject thiz, jstring mimeObj) {
2448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (mimeObj == NULL) {
2458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
2468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2498240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<JCrypto> crypto = getCrypto(env, thiz);
2508240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2518240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (crypto == NULL) {
2528240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
2538240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2548240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    const char *mime = env->GetStringUTFChars(mimeObj, NULL);
2578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (mime == NULL) {
2598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        return false;
2608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
2618240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    bool result = crypto->requiresSecureDecoderComponent(mime);
2638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    env->ReleaseStringUTFChars(mimeObj, mime);
2658240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    mime = NULL;
2668240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return result;
2688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberstatic JNINativeMethod gMethods[] = {
2718240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "release", "()V", (void *)android_media_Crypto_release },
2728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "native_init", "()V", (void *)android_media_Crypto_native_init },
2738240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "native_setup", "([B[B)V",
2758240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber      (void *)android_media_Crypto_native_setup },
2768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2778240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "native_finalize", "()V",
2788240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber      (void *)android_media_Crypto_native_finalize },
2798240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2808240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "isCryptoSchemeSupported", "([B)Z",
2818240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber      (void *)android_media_Crypto_isCryptoSchemeSupported },
2828240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2838240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    { "requiresSecureDecoderComponent", "(Ljava/lang/String;)Z",
2848240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber      (void *)android_media_Crypto_requiresSecureDecoderComponent },
2858240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber};
2868240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
2878240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huberint register_android_media_Crypto(JNIEnv *env) {
2888240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    return AndroidRuntime::registerNativeMethods(env,
2898240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber                "android/media/Crypto", gMethods, NELEM(gMethods));
2908240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber}
2918240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
292