android_media_MediaDrm.cpp revision 600071ca78bb3fa52b4b3e04112ed6664ffe0e30
18a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/*
28a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Copyright 2013, The Android Open Source Project
38a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *
48a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
58a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * you may not use this file except in compliance with the License.
68a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * You may obtain a copy of the License at
78a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *
88a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *     http://www.apache.org/licenses/LICENSE-2.0
98a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker *
108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * Unless required by applicable law or agreed to in writing, software
118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * See the License for the specific language governing permissions and
148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker * limitations under the License.
158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker */
168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker//#define LOG_NDEBUG 0
188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define LOG_TAG "MediaDrm-JNI"
198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <utils/Log.h>
208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "android_media_MediaDrm.h"
228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "android_runtime/AndroidRuntime.h"
2487eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include "android_runtime/Log.h"
2554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#include "android_os_Parcel.h"
268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "jni.h"
278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "JNIHelp.h"
288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <binder/IServiceManager.h>
3054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#include <binder/Parcel.h>
318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/IDrm.h>
328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/IMediaPlayerService.h>
338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/stagefright/foundation/ADebug.h>
34f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker#include <media/stagefright/MediaErrors.h>
358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkernamespace android {
378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define FIND_CLASS(var, className) \
398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->FindClass(className); \
408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find class " className);
418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find field " fieldName);
458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find method " fieldName);
498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#define GET_STATIC_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
5154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    var = env->GetStaticFieldID(clazz, fieldName, fieldDescriptor); \
5254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find field " fieldName);
5354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
5454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#define GET_STATIC_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
5554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
5654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find static method " fieldName);
5754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
5854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct RequestFields {
608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID data;
618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID defaultUrl;
628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct ArrayListFields {
658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID init;
668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID add;
678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct HashmapFields {
708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID init;
718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID get;
728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID put;
738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID entrySet;
748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct SetFields {
778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID iterator;
788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct IteratorFields {
818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID next;
828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID hasNext;
838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct EntryFields {
868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID getKey;
878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID getValue;
888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerstruct EventTypes {
9117b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kEventProvisionRequired;
9217b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kEventKeyRequired;
9317b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kEventKeyExpired;
9417b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kEventVendorDefined;
9554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker} gEventTypes;
9654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
9717b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinkerstruct KeyTypes {
9817b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kKeyTypeStreaming;
9917b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kKeyTypeOffline;
10017b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    jint kKeyTypeRelease;
10117b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker} gKeyTypes;
10217b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker
103e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerstruct CertificateTypes {
104e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jint kCertificateTypeNone;
105e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jint kCertificateTypeX509;
106e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker} gCertificateTypes;
107e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
108e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerstruct CertificateFields {
109e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jfieldID wrappedPrivateKey;
110e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jfieldID certificateData;
111e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker};
112e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct fields_t {
1148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID context;
11554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jmethodID post_event;
11616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    RequestFields keyRequest;
1178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    RequestFields provisionRequest;
1188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    ArrayListFields arraylist;
1198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    HashmapFields hashmap;
1208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    SetFields set;
1218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    IteratorFields iterator;
1228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    EntryFields entry;
123e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    CertificateFields certificate;
124e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass certificateClassId;
125e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass hashmapClassId;
126e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass arraylistClassId;
127e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass stringClassId;
1288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
1298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic fields_t gFields;
1318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker// ----------------------------------------------------------------------------
13354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker// ref-counted object for callbacks
13454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerclass JNIDrmListener: public DrmListener
13554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
13654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerpublic:
13754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
13854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    ~JNIDrmListener();
13954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj = NULL);
14054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerprivate:
14154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIDrmListener();
14254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jclass      mClass;     // Reference to MediaDrm class
14354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jobject     mObject;    // Weak ref to MediaDrm Java object to call on
14454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker};
14554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
14654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff TinkerJNIDrmListener::JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
14754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
14854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // Hold onto the MediaDrm class for use in calling the static method
14954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // that posts events to the application thread.
15054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jclass clazz = env->GetObjectClass(thiz);
15154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (clazz == NULL) {
15254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        ALOGE("Can't find android/media/MediaDrm");
153eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/Exception",
154eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "Can't find android/media/MediaDrm");
15554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        return;
15654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
15754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mClass = (jclass)env->NewGlobalRef(clazz);
15854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
15954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // We use a weak reference so the MediaDrm object can be garbage collected.
16054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // The reference is only used as a proxy for callbacks.
16154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mObject  = env->NewGlobalRef(weak_thiz);
16254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
16354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
16454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff TinkerJNIDrmListener::~JNIDrmListener()
16554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
16654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // remove global references
16754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
16854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    env->DeleteGlobalRef(mObject);
16954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    env->DeleteGlobalRef(mClass);
17054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
17154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
17254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkervoid JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra,
17354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker                            const Parcel *obj)
17454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
17554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jint jeventType;
17654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
17754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // translate DrmPlugin event types into their java equivalents
17854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    switch(eventType) {
17954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventProvisionRequired:
18054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventProvisionRequired;
18154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
18254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyNeeded:
18354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventKeyRequired;
18454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
18554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyExpired:
18654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventKeyExpired;
18754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
18854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventVendorDefined:
18954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventVendorDefined;
19054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
19154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        default:
19254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
19354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            return;
19454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
19554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
19654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
19754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (obj && obj->dataSize() > 0) {
19854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        jobject jParcel = createJavaParcelObject(env);
19954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        if (jParcel != NULL) {
20054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
20154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            nativeParcel->setData(obj->data(), obj->dataSize());
20254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            env->CallStaticVoidMethod(mClass, gFields.post_event, mObject,
20354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker                    jeventType, extra, jParcel);
204265551a164ac7757d1f2dacc0e2ab0afa0f850c7Patrik            env->DeleteLocalRef(jParcel);
20554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        }
20654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
20754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
20854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (env->ExceptionCheck()) {
20954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        ALOGW("An exception occurred while notifying an event.");
21054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        LOGW_EX(env);
21154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        env->ExceptionClear();
21254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
21354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
21454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
21554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
2168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic bool throwExceptionAsNecessary(
2178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, status_t err, const char *msg = NULL) {
2188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
219f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    const char *drmMessage = NULL;
220f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker
221f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    switch(err) {
222f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_UNKNOWN:
223f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "General DRM error";
224f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
225f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_NO_LICENSE:
226f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "No license";
227f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
228f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_LICENSE_EXPIRED:
229f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "License expired";
230f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
231f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_SESSION_NOT_OPENED:
232f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Session not opened";
233f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
234f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
235f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Not initialized";
236f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
237f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_DECRYPT:
238f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Decrypt error";
239f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
240f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_CANNOT_HANDLE:
241f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Unsupported scheme or data format";
242f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
243f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_TAMPER_DETECTED:
244f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Invalid state";
245f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
246f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    default:
247f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
248f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    }
249f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker
250f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    String8 vendorMessage;
251f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
252f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        vendorMessage.format("DRM vendor-defined error: %d", err);
253f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = vendorMessage.string();
254f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    }
255f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker
2568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err == BAD_VALUE) {
2578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", msg);
2588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return true;
2591d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker    } else if (err == ERROR_DRM_NOT_PROVISIONED) {
2601d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        jniThrowException(env, "android/media/NotProvisionedException", msg);
2611d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        return true;
2623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    } else if (err == ERROR_DRM_RESOURCE_BUSY) {
2633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        jniThrowException(env, "android/media/ResourceBusyException", msg);
2643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        return true;
2651d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker    } else if (err == ERROR_DRM_DEVICE_REVOKED) {
2661d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        jniThrowException(env, "android/media/DeniedByServerException", msg);
2671d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        return true;
2688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    } else if (err != OK) {
269f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        String8 errbuf;
270f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        if (drmMessage != NULL) {
271f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker            if (msg == NULL) {
272f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker                msg = drmMessage;
273f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker            } else {
274f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker                errbuf.format("%s: %s", msg, drmMessage);
275f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker                msg = errbuf.string();
276f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker            }
277f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        }
2781d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        ALOGE("Illegal state exception: %s", msg);
2798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", msg);
2808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return true;
2818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return false;
2838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic sp<IDrm> GetDrm(JNIEnv *env, jobject thiz) {
286656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    JDrm *jdrm = (JDrm *)env->GetLongField(thiz, gFields.context);
2878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return jdrm ? jdrm->getDrm() : NULL;
2888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff TinkerJDrm::JDrm(
2918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, const uint8_t uuid[16]) {
2928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mObject = env->NewWeakGlobalRef(thiz);
2938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mDrm = MakeDrm(uuid);
29454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (mDrm != NULL) {
29554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        mDrm->setListener(this);
29654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
2978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff TinkerJDrm::~JDrm() {
3008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
3018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->DeleteWeakGlobalRef(mObject);
3038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mObject = NULL;
3048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
3078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkersp<IDrm> JDrm::MakeDrm() {
3088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IServiceManager> sm = defaultServiceManager();
3098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IBinder> binder =
3118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        sm->getService(String16("media.player"));
3128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IMediaPlayerService> service =
3148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        interface_cast<IMediaPlayerService>(binder);
3158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (service == NULL) {
3178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = service->makeDrm();
3218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
3238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm;
3278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
3308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkersp<IDrm> JDrm::MakeDrm(const uint8_t uuid[16]) {
3318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = MakeDrm();
3328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
3348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->createPlugin(uuid);
3388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err != OK) {
3408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm;
3448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
34654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerstatus_t JDrm::setListener(const sp<DrmListener>& listener) {
34754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    Mutex::Autolock lock(mLock);
34854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mListener = listener;
34954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    return OK;
35054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
35154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
35254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkervoid JDrm::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) {
35354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    sp<DrmListener> listener;
35454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mLock.lock();
35554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    listener = mListener;
35654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mLock.unlock();
35754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
35854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (listener != NULL) {
35954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
36054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        listener->notify(eventType, extra, obj);
36154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
36254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
36354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
364600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinkervoid JDrm::disconnect() {
365600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker    if (mDrm != NULL) {
366600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker        mDrm->destroyPlugin();
367600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker        mDrm.clear();
368600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker    }
369600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker}
370600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker
37154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
3728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
3737cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinkerbool JDrm::IsCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
3748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = MakeDrm();
3758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
3778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
3788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3807cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    return drm->isCryptoSchemeSupported(uuid, mimeType);
3818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatus_t JDrm::initCheck() const {
3848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return mDrm == NULL ? NO_INIT : OK;
3858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// JNI conversion utilities
3888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray) {
3898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> vector;
3908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    size_t length = env->GetArrayLength(byteArray);
3918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    vector.insertAt((size_t)0, length);
3928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
3938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return vector;
3948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray VectorToJByteArray(JNIEnv *env, Vector<uint8_t> const &vector) {
3978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    size_t length = vector.size();
3988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jbyteArray result = env->NewByteArray(length);
3998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (result != NULL) {
4008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetByteArrayRegion(result, 0, length, (jbyte *)vector.array());
4018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return result;
4038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic String8 JStringToString8(JNIEnv *env, jstring const &jstr) {
4068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 result;
4078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
40854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    const char *s = env->GetStringUTFChars(jstr, NULL);
4098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (s) {
4108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        result = s;
4118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->ReleaseStringUTFChars(jstr, s);
4128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return result;
4148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
41516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
4168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/*
4178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.util.HashMap;
4188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.util.Set;
4198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.Map.Entry;
4208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import jav.util.Iterator;
4218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    HashMap<k, v> hm;
4238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Set<Entry<k, v> > s = hm.entrySet();
4248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Iterator i = s.iterator();
4258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Entry e = s.next();
4268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker*/
4278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic KeyedVector<String8, String8> HashMapToKeyedVector(JNIEnv *env, jobject &hashMap) {
429e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass clazz = gFields.stringClassId;
4308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> keyedVector;
4318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject entrySet = env->CallObjectMethod(hashMap, gFields.hashmap.entrySet);
4338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (entrySet) {
4348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jobject iterator = env->CallObjectMethod(entrySet, gFields.set.iterator);
4358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        if (iterator) {
4368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            jboolean hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
4378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            while (hasNext) {
4388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                jobject entry = env->CallObjectMethod(iterator, gFields.iterator.next);
4398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                if (entry) {
4408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jobject obj = env->CallObjectMethod(entry, gFields.entry.getKey);
4418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    if (!env->IsInstanceOf(obj, clazz)) {
442eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                        jniThrowException(env, "java/lang/IllegalArgumentException",
443eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                                          "HashMap key is not a String");
4448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    }
4458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jstring jkey = static_cast<jstring>(obj);
4468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    obj = env->CallObjectMethod(entry, gFields.entry.getValue);
4488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    if (!env->IsInstanceOf(obj, clazz)) {
449eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                        jniThrowException(env, "java/lang/IllegalArgumentException",
450eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                                          "HashMap value is not a String");
4518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    }
4528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jstring jvalue = static_cast<jstring>(obj);
4538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    String8 key = JStringToString8(env, jkey);
4558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    String8 value = JStringToString8(env, jvalue);
4568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    keyedVector.add(key, value);
4578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    env->DeleteLocalRef(jkey);
4598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    env->DeleteLocalRef(jvalue);
4608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
4618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                }
4628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env->DeleteLocalRef(entry);
4638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            }
4648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            env->DeleteLocalRef(iterator);
4658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        }
4668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(entrySet);
4678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return keyedVector;
4698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject KeyedVectorToHashMap (JNIEnv *env, KeyedVector<String8, String8> const &map) {
472e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass clazz = gFields.hashmapClassId;
4738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject hashMap = env->NewObject(clazz, gFields.hashmap.init);
4748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    for (size_t i = 0; i < map.size(); ++i) {
4758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jkey = env->NewStringUTF(map.keyAt(i).string());
4768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jvalue = env->NewStringUTF(map.valueAt(i).string());
4778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->CallObjectMethod(hashMap, gFields.hashmap.put, jkey, jvalue);
4788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(jkey);
4798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(jvalue);
4808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return hashMap;
4828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
4858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                                                   List<Vector<uint8_t> > list) {
486e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass clazz = gFields.arraylistClassId;
4878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
4888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    List<Vector<uint8_t> >::iterator iter = list.begin();
4898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    while (iter != list.end()) {
4908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray byteArray = VectorToJByteArray(env, *iter);
4918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
4928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(byteArray);
4938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        iter++;
4948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return arrayList;
4978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}  // namespace android
5008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerusing namespace android;
5028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic sp<JDrm> setDrm(
5048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, const sp<JDrm> &drm) {
505656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    sp<JDrm> old = (JDrm *)env->GetLongField(thiz, gFields.context);
5068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm != NULL) {
5078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        drm->incStrong(thiz);
5088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (old != NULL) {
5108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        old->decStrong(thiz);
5118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
512f11dd63e0c5c8cf02d382351004000b243013b5fNarayan Kamath    env->SetLongField(thiz, gFields.context, reinterpret_cast<jlong>(drm.get()));
5138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return old;
5158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic bool CheckSession(JNIEnv *env, const sp<IDrm> &drm, jbyteArray const &jsessionId)
5188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker{
5198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
520eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", "MediaDrm obj is null");
5218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
5228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jsessionId == NULL) {
525eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", "sessionId is null");
5268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
5278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return true;
5298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_release(JNIEnv *env, jobject thiz) {
53254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    sp<JDrm> drm = setDrm(env, thiz, NULL);
53354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (drm != NULL) {
53454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        drm->setListener(NULL);
535600071ca78bb3fa52b4b3e04112ed6664ffe0e30Jeff Tinker        drm->disconnect();
53654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
5378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_init(JNIEnv *env) {
5408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
5418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm");
542656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    GET_FIELD_ID(gFields.context, clazz, "mNativeContext", "J");
54354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    GET_STATIC_METHOD_ID(gFields.post_event, clazz, "postEventFromNative",
54454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker                         "(Ljava/lang/Object;IILjava/lang/Object;)V");
54554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
54654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jfieldID field;
547e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_PROVISION_REQUIRED", "I");
54854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventProvisionRequired = env->GetStaticIntField(clazz, field);
549e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_REQUIRED", "I");
55054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventKeyRequired = env->GetStaticIntField(clazz, field);
551e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_EXPIRED", "I");
55254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventKeyExpired = env->GetStaticIntField(clazz, field);
553e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_VENDOR_DEFINED", "I");
55454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventVendorDefined = env->GetStaticIntField(clazz, field);
5558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
55617b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I");
55717b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field);
55817b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_OFFLINE", "I");
55917b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    gKeyTypes.kKeyTypeOffline = env->GetStaticIntField(clazz, field);
56017b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
56117b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);
56217b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker
563e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I");
564e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field);
565e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I");
566e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    gCertificateTypes.kCertificateTypeX509 = env->GetStaticIntField(clazz, field);
567e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
56816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
569e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
570e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
5718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
573e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
574e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
5758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
576e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$Certificate");
577e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    GET_FIELD_ID(gFields.certificate.wrappedPrivateKey, clazz, "mWrappedKey", "[B");
578e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    GET_FIELD_ID(gFields.certificate.certificateData, clazz, "mCertificateData", "[B");
57965c94e695929ffa1aaa49d7b5938b34aaf078b6cJeff Tinker    gFields.certificateClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
580e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
5818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/ArrayList");
5828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V");
5838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.arraylist.add, clazz, "add", "(Ljava/lang/Object;)Z");
5848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/HashMap");
5868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.init, clazz, "<init>", "()V");
5878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.get, clazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
5888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.put, clazz, "put",
5898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
5908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.entrySet, clazz, "entrySet", "()Ljava/util/Set;");
5918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Set");
5938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.set.iterator, clazz, "iterator", "()Ljava/util/Iterator;");
5948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Iterator");
5968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.iterator.next, clazz, "next", "()Ljava/lang/Object;");
5978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.iterator.hasNext, clazz, "hasNext", "()Z");
5988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Map$Entry");
6008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.entry.getKey, clazz, "getKey", "()Ljava/lang/Object;");
6018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.entry.getValue, clazz, "getValue", "()Ljava/lang/Object;");
602e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
603e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    FIND_CLASS(clazz, "java/util/HashMap");
60465c94e695929ffa1aaa49d7b5938b34aaf078b6cJeff Tinker    gFields.hashmapClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
605e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
606e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    FIND_CLASS(clazz, "java/lang/String");
60765c94e695929ffa1aaa49d7b5938b34aaf078b6cJeff Tinker    gFields.stringClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
608e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
609e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    FIND_CLASS(clazz, "java/util/ArrayList");
61065c94e695929ffa1aaa49d7b5938b34aaf078b6cJeff Tinker    gFields.arraylistClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
6118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_setup(
6148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz,
6158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jobject weak_this, jbyteArray uuidObj) {
6168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuidObj == NULL) {
618eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", "uuid is null");
6198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
6238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuid.size() != 16) {
625eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
626eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "invalid UUID size, expected 16 bytes");
6278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<JDrm> drm = new JDrm(env, thiz, uuid.array());
6318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->initCheck();
6338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err != OK) {
6358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(
6368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env,
6371d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker                "android/media/UnsupportedSchemeException",
6388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "Failed to instantiate drm object.");
6398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
64254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    sp<JNIDrmListener> listener = new JNIDrmListener(env, thiz, weak_this);
64354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    drm->setListener(listener);
6448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    setDrm(env, thiz, drm);
6458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_finalize(
6488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz) {
6498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    android_media_MediaDrm_release(env, thiz);
6508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
6537cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray uuidObj, jstring jmimeType) {
6548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuidObj == NULL) {
6568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
6588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
6618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuid.size() != 16) {
6638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(
6648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env,
6658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "java/lang/IllegalArgumentException",
666eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                "invalid UUID size, expected 16 bytes");
6678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
6688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6707cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    String8 mimeType;
6717cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    if (jmimeType != NULL) {
6727cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker        mimeType = JStringToString8(env, jmimeType);
6737cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    }
6747cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker
6757cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    return JDrm::IsCryptoSchemeSupported(uuid.array(), mimeType);
6768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray android_media_MediaDrm_openSession(
6798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
6808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
683eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
684eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
6858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId;
6898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->openSession(sessionId);
6908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to open session")) {
6928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return VectorToJByteArray(env, sessionId);
6968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_closeSession(
6998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
7008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
7038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
7048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
7078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->closeSession(sessionId);
7098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to close session");
7118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
71316b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jobject android_media_MediaDrm_getKeyRequest(
7148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jinitData,
71516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jstring jmimeType, jint jkeyType, jobject joptParams) {
7168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
7198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
7208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
7238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> initData;
7258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jinitData != NULL) {
7268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        initData = JByteArrayToVector(env, jinitData);
7278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 mimeType;
7308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jmimeType != NULL) {
7318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        mimeType = JStringToString8(env, jmimeType);
7328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
73417b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    DrmPlugin::KeyType keyType;
73517b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    if (jkeyType == gKeyTypes.kKeyTypeStreaming) {
73617b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker        keyType = DrmPlugin::kKeyType_Streaming;
73717b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    } else if (jkeyType == gKeyTypes.kKeyTypeOffline) {
73817b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker        keyType = DrmPlugin::kKeyType_Offline;
73917b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    } else if (jkeyType == gKeyTypes.kKeyTypeRelease) {
74017b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker        keyType = DrmPlugin::kKeyType_Release;
74117b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    } else {
74217b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
74317b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker                          "invalid keyType");
74417b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker        return NULL;
74517b8922785987afa002fb5f081781f056e3ca1c7Jeff Tinker    }
7468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> optParams;
7488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (joptParams != NULL) {
7498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        optParams = HashMapToKeyedVector(env, joptParams);
7508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> request;
7538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 defaultUrl;
7548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
75516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->getKeyRequest(sessionId, initData, mimeType,
75616b8cffb2893c10c35788191847500004da466d1Jeff Tinker                                          keyType, optParams, request, defaultUrl);
7578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
75816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get key request")) {
7598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
7608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    // Fill out return obj
7638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
76416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
7658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
76616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jobject keyObj = NULL;
7678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (clazz) {
76916b8cffb2893c10c35788191847500004da466d1Jeff Tinker        keyObj = env->AllocObject(clazz);
7708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray jrequest = VectorToJByteArray(env, request);
77116b8cffb2893c10c35788191847500004da466d1Jeff Tinker        env->SetObjectField(keyObj, gFields.keyRequest.data, jrequest);
7728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
77416b8cffb2893c10c35788191847500004da466d1Jeff Tinker        env->SetObjectField(keyObj, gFields.keyRequest.defaultUrl, jdefaultUrl);
7758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
77716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return keyObj;
7788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
78016b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_provideKeyResponse(
7818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jresponse) {
7828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
78516b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
7868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
7898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jresponse == NULL) {
791eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
792eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "key response is null");
79316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
7948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
79616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keySetId;
7978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
79816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->provideKeyResponse(sessionId, response, keySetId);
7998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8008117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to handle key response")) {
8018117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker        return NULL;
8028117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    }
80316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, keySetId);
8048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
80616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_removeKeys(
80716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jkeysetId) {
80816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
80916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
81016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeysetId == NULL) {
811eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
812eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "keySetId is null");
81316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
81416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
81516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
81616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));
81716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
81816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->removeKeys(keySetId);
81916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
82016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to remove keys");
82116b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
82216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
82316b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_restoreKeys(
82416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId,
82516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeysetId) {
82616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
8278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
8308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
8318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
83316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeysetId == NULL) {
83416b8cffb2893c10c35788191847500004da466d1Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
83516b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
83616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
83716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
8388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
83916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));
8408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
84116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->restoreKeys(sessionId, keySetId);
8428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
84316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to restore keys");
8448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
84616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jobject android_media_MediaDrm_queryKeyStatus(
8478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
8488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
8518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
8548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> infoMap;
8568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
85716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->queryKeyStatus(sessionId, infoMap);
8588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
85916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to query key status")) {
8608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return KeyedVectorToHashMap(env, infoMap);
8648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
866e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerstatic jobject android_media_MediaDrm_getProvisionRequestNative(
867e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    JNIEnv *env, jobject thiz, jint jcertType, jstring jcertAuthority) {
8688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
871eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
872eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
8738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> request;
8778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 defaultUrl;
8788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
879e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    String8 certType;
880e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    if (jcertType == gCertificateTypes.kCertificateTypeX509) {
881e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        certType = "X.509";
882e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    } else if (jcertType == gCertificateTypes.kCertificateTypeNone) {
883e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        certType = "none";
884e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    } else {
885e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        certType = "invalid";
886e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    }
887e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
888e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    String8 certAuthority = JStringToString8(env, jcertAuthority);
889e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    status_t err = drm->getProvisionRequest(certType, certAuthority, request, defaultUrl);
8908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get provision request")) {
8928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    // Fill out return obj
8968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
8978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
8988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject provisionObj = NULL;
9008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (clazz) {
9028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        provisionObj = env->AllocObject(clazz);
9038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray jrequest = VectorToJByteArray(env, request);
9048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(provisionObj, gFields.provisionRequest.data, jrequest);
9058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
9078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(provisionObj, gFields.provisionRequest.defaultUrl, jdefaultUrl);
9088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return provisionObj;
9118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
913e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerstatic jobject android_media_MediaDrm_provideProvisionResponseNative(
9148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jresponse) {
9158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
918eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
919eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
920e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        return NULL;
9218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jresponse == NULL) {
924eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
925eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "provision response is null");
926e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        return NULL;
9278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
930e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    Vector<uint8_t> certificate, wrappedKey;
931e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
932e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    status_t err = drm->provideProvisionResponse(response, certificate, wrappedKey);
933e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
934e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    // Fill out return obj
935e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jclass clazz = gFields.certificateClassId;
936e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
937e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jobject certificateObj = NULL;
938e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
939e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    if (clazz && certificate.size() && wrappedKey.size()) {
940e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        certificateObj = env->AllocObject(clazz);
941e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        jbyteArray jcertificate = VectorToJByteArray(env, certificate);
942e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        env->SetObjectField(certificateObj, gFields.certificate.certificateData, jcertificate);
9438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
944e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        jbyteArray jwrappedKey = VectorToJByteArray(env, wrappedKey);
945e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        env->SetObjectField(certificateObj, gFields.certificate.wrappedPrivateKey, jwrappedKey);
946e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    }
9478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to handle provision response");
949e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    return certificateObj;
9508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_getSecureStops(
9538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
9548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
957eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
958eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
9598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    List<Vector<uint8_t> > secureStops;
9638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getSecureStops(secureStops);
9658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get secure stops")) {
9678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return ListOfVectorsToArrayListOfByteArray(env, secureStops);
9718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_releaseSecureStops(
9748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jssRelease) {
9758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
978eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
979eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
9808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
9818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> ssRelease(JByteArrayToVector(env, jssRelease));
9848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->releaseSecureStops(ssRelease);
9868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to release secure stops");
9888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jstring android_media_MediaDrm_getPropertyString(
9918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname) {
9928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
995eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
996eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
9978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL) {
1001eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1002eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
10038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
10048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
10078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 value;
10088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getPropertyString(name, value);
10108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get property")) {
10128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
10138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return env->NewStringUTF(value.string());
10168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
10178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray android_media_MediaDrm_getPropertyByteArray(
10198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname) {
10208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
10218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
1023eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
1024eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
10258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
10268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL) {
1029eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1030eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
10318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
10328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
10358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> value;
10368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getPropertyByteArray(name, value);
10388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get property")) {
10408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
10418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return VectorToJByteArray(env, value);
10448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
10458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_setPropertyString(
10478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname, jstring jvalue) {
10488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
10498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
1051eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
1052eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
10538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
10548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1056eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jname == NULL) {
1057eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1058eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
1059eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        return;
1060eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    }
1061eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker
1062eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jvalue == NULL) {
1063eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1064eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property value String is null");
10658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
10668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
10698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 value = JStringToString8(env, jvalue);
10708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->setPropertyString(name, value);
10728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set property");
10748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
10758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_setPropertyByteArray(
10778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname, jbyteArray jvalue) {
10788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
10798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
1081eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
1082eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
10838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
10848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1086eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jname == NULL) {
1087eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1088eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
1089eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        return;
1090eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    }
1091eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker
1092eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jvalue == NULL) {
1093eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1094eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property value byte array is null");
10958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
10968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
10978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
10998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> value = JByteArrayToVector(env, jvalue);
11008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->setPropertyByteArray(name, value);
11028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set property");
11048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
11058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
110616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_setCipherAlgorithmNative(
110716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
110816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jstring jalgorithm) {
110916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
111116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
111316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
111416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
111516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jalgorithm == NULL) {
1117eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1118eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "algorithm String is null");
111916b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
112016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
112116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
112216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
112316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    String8 algorithm = JStringToString8(env, jalgorithm);
112416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
112516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->setCipherAlgorithm(sessionId, algorithm);
112616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
112716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set cipher algorithm");
112816b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
112916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
113016b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_setMacAlgorithmNative(
113116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
113216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jstring jalgorithm) {
113316b8cffb2893c10c35788191847500004da466d1Jeff Tinker
113416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
113516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
113616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
113716b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
113816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
113916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
114016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jalgorithm == NULL) {
1141eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1142eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "algorithm String is null");
114316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
114416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
114516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
114616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
114716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    String8 algorithm = JStringToString8(env, jalgorithm);
114816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
114916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->setMacAlgorithm(sessionId, algorithm);
115016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
115116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set mac algorithm");
115216b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
115316b8cffb2893c10c35788191847500004da466d1Jeff Tinker
115416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
115516b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_encryptNative(
115616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
115716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
115816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
115916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
116016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
116116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
116216b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
116316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
116416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
116516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
1166eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1167eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
116816b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
116916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
117016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
117116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
117216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
117316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> input(JByteArrayToVector(env, jinput));
117416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
117516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> output;
117616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
117716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->encrypt(sessionId, keyId, input, iv, output);
117816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
11798117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to encrypt")) {
11808117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker        return NULL;
11818117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    }
118216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
118316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, output);
118416b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
118516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
118616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_decryptNative(
118716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
118816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
118916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
119016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
119116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
119216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
119316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
119416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
119516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
119616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
1197eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1198eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
119916b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
120016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
120116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
120216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
120316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
120416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> input(JByteArrayToVector(env, jinput));
120516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
120616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> output;
120716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
120816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->decrypt(sessionId, keyId, input, iv, output);
12098117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to decrypt")) {
12108117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker        return NULL;
12118117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    }
121216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
121316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, output);
121416b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
121516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
121616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_signNative(
121716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
121816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jmessage) {
121916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
122016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
122116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
122216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
122316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
122416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
122516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
122616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jmessage == NULL) {
1227eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1228eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
122916b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
123016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
123116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
123216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
123316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
123416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
123516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> signature;
123616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
123716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->sign(sessionId, keyId, message, signature);
123816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
12398117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to sign")) {
12408117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker        return NULL;
12418117d8f7023f8981bc4b2651efed5b28104d83d3Jeff Tinker    }
124216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
124316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, signature);
124416b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
124516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
124616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jboolean android_media_MediaDrm_verifyNative(
124716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
124816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jmessage, jbyteArray jsignature) {
124916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
125016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
125116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
125216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
125316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return false;
125416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
125516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
125616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jmessage == NULL || jsignature == NULL) {
1257eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1258eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
125916b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return false;
126016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
126116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
126216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
126316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
126416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
126516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> signature(JByteArrayToVector(env, jsignature));
126616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    bool match;
126716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
126816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->verify(sessionId, keyId, message, signature, match);
126916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
127016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to verify");
127116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return match;
127216b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
127316b8cffb2893c10c35788191847500004da466d1Jeff Tinker
12748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1275e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerstatic jbyteArray android_media_MediaDrm_signRSANative(
1276e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
1277e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    jstring jalgorithm, jbyteArray jwrappedKey, jbyteArray jmessage) {
1278e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1279e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
1280e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1281e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
1282e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        return NULL;
1283e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    }
1284e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1285e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    if (jalgorithm == NULL || jwrappedKey == NULL || jmessage == NULL) {
1286e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1287e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker                          "required argument is null");
1288e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        return NULL;
1289e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    }
1290e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1291e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
1292e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    String8 algorithm = JStringToString8(env, jalgorithm);
1293e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    Vector<uint8_t> wrappedKey(JByteArrayToVector(env, jwrappedKey));
1294e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
1295e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    Vector<uint8_t> signature;
1296e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1297e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    status_t err = drm->signRSA(sessionId, algorithm, message, wrappedKey, signature);
1298e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1299e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to sign")) {
1300e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker        return NULL;
1301e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    }
1302e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1303e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    return VectorToJByteArray(env, signature);
1304e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker}
1305e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1306e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
13078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic JNINativeMethod gMethods[] = {
13088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "release", "()V", (void *)android_media_MediaDrm_release },
13098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_init", "()V", (void *)android_media_MediaDrm_native_init },
13108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_setup", "(Ljava/lang/Object;[B)V",
13128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_native_setup },
13138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_finalize", "()V",
13158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_native_finalize },
13168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13177cda491321b9bd2e8faf956824312ea6a30e6457Jeff Tinker    { "isCryptoSchemeSupportedNative", "([BLjava/lang/String;)Z",
13188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },
13198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "openSession", "()[B",
13218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_openSession },
13228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "closeSession", "([B)V",
13248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_closeSession },
13258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
132616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
132716b8cffb2893c10c35788191847500004da466d1Jeff Tinker      "Landroid/media/MediaDrm$KeyRequest;",
132816b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_getKeyRequest },
13298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
133016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "provideKeyResponse", "([B[B)[B",
133116b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_provideKeyResponse },
13328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
133316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "removeKeys", "([B)V",
133416b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_removeKeys },
13358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
133616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "restoreKeys", "([B[B)V",
133716b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_restoreKeys },
133816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
133916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "queryKeyStatus", "([B)Ljava/util/HashMap;",
134016b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_queryKeyStatus },
13418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1342e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    { "getProvisionRequestNative", "(ILjava/lang/String;)Landroid/media/MediaDrm$ProvisionRequest;",
1343e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker      (void *)android_media_MediaDrm_getProvisionRequestNative },
13448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1345e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    { "provideProvisionResponseNative", "([B)Landroid/media/MediaDrm$Certificate;",
1346e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker      (void *)android_media_MediaDrm_provideProvisionResponseNative },
13478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getSecureStops", "()Ljava/util/List;",
13498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getSecureStops },
13508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "releaseSecureStops", "([B)V",
13528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_releaseSecureStops },
13538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
13558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getPropertyString },
13568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getPropertyByteArray", "(Ljava/lang/String;)[B",
13588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getPropertyByteArray },
13598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "setPropertyString", "(Ljava/lang/String;Ljava/lang/String;)V",
13618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_setPropertyString },
13628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "setPropertyByteArray", "(Ljava/lang/String;[B)V",
13648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_setPropertyByteArray },
136516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
136616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "setCipherAlgorithmNative",
136716b8cffb2893c10c35788191847500004da466d1Jeff Tinker      "(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
136816b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_setCipherAlgorithmNative },
136916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
137016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "setMacAlgorithmNative",
137116b8cffb2893c10c35788191847500004da466d1Jeff Tinker      "(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
137216b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_setMacAlgorithmNative },
137316b8cffb2893c10c35788191847500004da466d1Jeff Tinker
137416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "encryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
137516b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_encryptNative },
137616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
137716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "decryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
137816b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_decryptNative },
137916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
138016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "signNative", "(Landroid/media/MediaDrm;[B[B[B)[B",
138116b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_signNative },
138216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
138316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "verifyNative", "(Landroid/media/MediaDrm;[B[B[B[B)Z",
138416b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_verifyNative },
1385e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker
1386e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker    { "signRSANative", "(Landroid/media/MediaDrm;[BLjava/lang/String;[B[B)[B",
1387e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker      (void *)android_media_MediaDrm_signRSANative },
13888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
13898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
13908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerint register_android_media_Drm(JNIEnv *env) {
13918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return AndroidRuntime::registerNativeMethods(env,
13928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "android/media/MediaDrm", gMethods, NELEM(gMethods));
13938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
13948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1395