android_media_MediaDrm.cpp revision eada5376d9c34f77bd3ba86a2ea674e3bde5e961
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"
2454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#include "android_os_Parcel.h"
258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "jni.h"
268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include "JNIHelp.h"
278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <binder/IServiceManager.h>
2954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#include <binder/Parcel.h>
308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/IDrm.h>
318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/IMediaPlayerService.h>
328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#include <media/stagefright/foundation/ADebug.h>
33f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker#include <media/stagefright/MediaErrors.h>
348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkernamespace android {
368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define FIND_CLASS(var, className) \
388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->FindClass(className); \
398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find class " className);
408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find field " fieldName);
448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find method " fieldName);
488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#define GET_STATIC_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
5054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    var = env->GetStaticFieldID(clazz, fieldName, fieldDescriptor); \
5154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find field " fieldName);
5254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
5354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker#define GET_STATIC_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
5454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
5554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    LOG_FATAL_IF(! var, "Unable to find static method " fieldName);
5654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
5754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct RequestFields {
598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID data;
608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID defaultUrl;
618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct ArrayListFields {
648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID init;
658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID add;
668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct HashmapFields {
698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID init;
708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID get;
718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID put;
728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID entrySet;
738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct SetFields {
768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID iterator;
778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct IteratorFields {
808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID next;
818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID hasNext;
828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct EntryFields {
858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID getKey;
868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jmethodID getValue;
878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerstruct EventTypes {
9054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    int kEventProvisionRequired;
9154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    int kEventKeyRequired;
9254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    int kEventKeyExpired;
9354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    int kEventVendorDefined;
9454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker} gEventTypes;
9554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstruct fields_t {
978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jfieldID context;
9854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jmethodID post_event;
9916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    RequestFields keyRequest;
1008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    RequestFields provisionRequest;
1018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    ArrayListFields arraylist;
1028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    HashmapFields hashmap;
1038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    SetFields set;
1048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    IteratorFields iterator;
1058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    EntryFields entry;
1068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
1078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic fields_t gFields;
1098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker// ----------------------------------------------------------------------------
11154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker// ref-counted object for callbacks
11254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerclass JNIDrmListener: public DrmListener
11354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
11454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerpublic:
11554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
11654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    ~JNIDrmListener();
11754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj = NULL);
11854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerprivate:
11954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIDrmListener();
12054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jclass      mClass;     // Reference to MediaDrm class
12154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jobject     mObject;    // Weak ref to MediaDrm Java object to call on
12254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker};
12354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
12454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff TinkerJNIDrmListener::JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
12554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
12654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // Hold onto the MediaDrm class for use in calling the static method
12754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // that posts events to the application thread.
12854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jclass clazz = env->GetObjectClass(thiz);
12954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (clazz == NULL) {
13054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        ALOGE("Can't find android/media/MediaDrm");
131eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/Exception",
132eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "Can't find android/media/MediaDrm");
13354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        return;
13454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
13554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mClass = (jclass)env->NewGlobalRef(clazz);
13654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
13754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // We use a weak reference so the MediaDrm object can be garbage collected.
13854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // The reference is only used as a proxy for callbacks.
13954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mObject  = env->NewGlobalRef(weak_thiz);
14054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
14154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
14254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff TinkerJNIDrmListener::~JNIDrmListener()
14354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
14454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // remove global references
14554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
14654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    env->DeleteGlobalRef(mObject);
14754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    env->DeleteGlobalRef(mClass);
14854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
14954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
15054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkervoid JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra,
15154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker                            const Parcel *obj)
15254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker{
15354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jint jeventType;
15454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
15554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    // translate DrmPlugin event types into their java equivalents
15654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    switch(eventType) {
15754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventProvisionRequired:
15854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventProvisionRequired;
15954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
16054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyNeeded:
16154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventKeyRequired;
16254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
16354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventKeyExpired:
16454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventKeyExpired;
16554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
16654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        case DrmPlugin::kDrmPluginEventVendorDefined:
16754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            jeventType = gEventTypes.kEventVendorDefined;
16854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            break;
16954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        default:
17054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
17154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            return;
17254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
17354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
17454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
17554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (obj && obj->dataSize() > 0) {
17654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        jobject jParcel = createJavaParcelObject(env);
17754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        if (jParcel != NULL) {
17854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
17954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            nativeParcel->setData(obj->data(), obj->dataSize());
18054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker            env->CallStaticVoidMethod(mClass, gFields.post_event, mObject,
18154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker                    jeventType, extra, jParcel);
18254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        }
18354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
18454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
18554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (env->ExceptionCheck()) {
18654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        ALOGW("An exception occurred while notifying an event.");
18754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        LOGW_EX(env);
18854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        env->ExceptionClear();
18954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
19054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
19154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
19254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
1938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic bool throwExceptionAsNecessary(
1948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, status_t err, const char *msg = NULL) {
1958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
196f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    const char *drmMessage = NULL;
197f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker
198f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    switch(err) {
199f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_UNKNOWN:
200f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "General DRM error";
201f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
202f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_NO_LICENSE:
203f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "No license";
204f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
205f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_LICENSE_EXPIRED:
206f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "License expired";
207f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
208f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_SESSION_NOT_OPENED:
209f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Session not opened";
210f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
211f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
212f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Not initialized";
213f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
214f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_DECRYPT:
215f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Decrypt error";
216f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
217f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_CANNOT_HANDLE:
218f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Unsupported scheme or data format";
219f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
220f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    case ERROR_DRM_TAMPER_DETECTED:
221f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = "Invalid state";
222f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
223f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    default:
224f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        break;
225f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    }
226f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker
227f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    String8 vendorMessage;
228f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
229f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        vendorMessage.format("DRM vendor-defined error: %d", err);
230f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        drmMessage = vendorMessage.string();
231f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker    }
232f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker
2338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err == BAD_VALUE) {
2348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", msg);
2358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return true;
2361d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker    } else if (err == ERROR_DRM_NOT_PROVISIONED) {
2371d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        jniThrowException(env, "android/media/NotProvisionedException", msg);
2381d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        return true;
2391d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker    } else if (err == ERROR_DRM_DEVICE_REVOKED) {
2401d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        jniThrowException(env, "android/media/DeniedByServerException", msg);
2411d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        return true;
2428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    } else if (err != OK) {
243f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        String8 errbuf;
244f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        if (drmMessage != NULL) {
245f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker            if (msg == NULL) {
246f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker                msg = drmMessage;
247f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker            } else {
248f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker                errbuf.format("%s: %s", msg, drmMessage);
249f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker                msg = errbuf.string();
250f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker            }
251f7568b5ee96b3d80721c76ab3d47f1368a99bf98Jeff Tinker        }
2521d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker        ALOGE("Illegal state exception: %s", msg);
2538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", msg);
2548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return true;
2558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return false;
2578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic sp<IDrm> GetDrm(JNIEnv *env, jobject thiz) {
2608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JDrm *jdrm = (JDrm *)env->GetIntField(thiz, gFields.context);
2618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return jdrm ? jdrm->getDrm() : NULL;
2628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff TinkerJDrm::JDrm(
2658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, const uint8_t uuid[16]) {
2668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mObject = env->NewWeakGlobalRef(thiz);
2678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mDrm = MakeDrm(uuid);
26854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (mDrm != NULL) {
26954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        mDrm->setListener(this);
27054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
2718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff TinkerJDrm::~JDrm() {
2748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mDrm.clear();
2758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env = AndroidRuntime::getJNIEnv();
2778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->DeleteWeakGlobalRef(mObject);
2798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    mObject = NULL;
2808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
2818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
2838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkersp<IDrm> JDrm::MakeDrm() {
2848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IServiceManager> sm = defaultServiceManager();
2858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IBinder> binder =
2878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        sm->getService(String16("media.player"));
2888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IMediaPlayerService> service =
2908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        interface_cast<IMediaPlayerService>(binder);
2918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (service == NULL) {
2938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
2948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
2958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = service->makeDrm();
2978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
2988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
2998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm;
3038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
3068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkersp<IDrm> JDrm::MakeDrm(const uint8_t uuid[16]) {
3078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = MakeDrm();
3088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
3108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->createPlugin(uuid);
3148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err != OK) {
3168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
3178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm;
3208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
32254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkerstatus_t JDrm::setListener(const sp<DrmListener>& listener) {
32354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    Mutex::Autolock lock(mLock);
32454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mListener = listener;
32554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    return OK;
32654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
32754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
32854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinkervoid JDrm::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) {
32954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    sp<DrmListener> listener;
33054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mLock.lock();
33154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    listener = mListener;
33254cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    mLock.unlock();
33354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
33454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (listener != NULL) {
33554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
33654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        listener->notify(eventType, extra, obj);
33754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
33854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker}
33954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
34054cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
3418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// static
3428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerbool JDrm::IsCryptoSchemeSupported(const uint8_t uuid[16]) {
3438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = MakeDrm();
3448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
3468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
3478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return drm->isCryptoSchemeSupported(uuid);
3508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatus_t JDrm::initCheck() const {
3538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return mDrm == NULL ? NO_INIT : OK;
3548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker// JNI conversion utilities
3578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray) {
3588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> vector;
3598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    size_t length = env->GetArrayLength(byteArray);
3608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    vector.insertAt((size_t)0, length);
3618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
3628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return vector;
3638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray VectorToJByteArray(JNIEnv *env, Vector<uint8_t> const &vector) {
3668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    size_t length = vector.size();
3678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jbyteArray result = env->NewByteArray(length);
3688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (result != NULL) {
3698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetByteArrayRegion(result, 0, length, (jbyte *)vector.array());
3708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return result;
3728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
3738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic String8 JStringToString8(JNIEnv *env, jstring const &jstr) {
3758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 result;
3768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
37754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    const char *s = env->GetStringUTFChars(jstr, NULL);
3788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (s) {
3798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        result = s;
3808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->ReleaseStringUTFChars(jstr, s);
3818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
3828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return result;
3838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
38416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
3858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker/*
3868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.util.HashMap;
3878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.util.Set;
3888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import java.Map.Entry;
3898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    import jav.util.Iterator;
3908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    HashMap<k, v> hm;
3928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Set<Entry<k, v> > s = hm.entrySet();
3938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Iterator i = s.iterator();
3948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Entry e = s.next();
3958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker*/
3968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
3978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic KeyedVector<String8, String8> HashMapToKeyedVector(JNIEnv *env, jobject &hashMap) {
3988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
3998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/lang/String");
4008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> keyedVector;
4018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject entrySet = env->CallObjectMethod(hashMap, gFields.hashmap.entrySet);
4038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (entrySet) {
4048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jobject iterator = env->CallObjectMethod(entrySet, gFields.set.iterator);
4058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        if (iterator) {
4068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            jboolean hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
4078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            while (hasNext) {
4088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                jobject entry = env->CallObjectMethod(iterator, gFields.iterator.next);
4098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                if (entry) {
4108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jobject obj = env->CallObjectMethod(entry, gFields.entry.getKey);
4118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    if (!env->IsInstanceOf(obj, clazz)) {
412eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                        jniThrowException(env, "java/lang/IllegalArgumentException",
413eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                                          "HashMap key is not a String");
4148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    }
4158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jstring jkey = static_cast<jstring>(obj);
4168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    obj = env->CallObjectMethod(entry, gFields.entry.getValue);
4188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    if (!env->IsInstanceOf(obj, clazz)) {
419eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                        jniThrowException(env, "java/lang/IllegalArgumentException",
420eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                                          "HashMap value is not a String");
4218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    }
4228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    jstring jvalue = static_cast<jstring>(obj);
4238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    String8 key = JStringToString8(env, jkey);
4258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    String8 value = JStringToString8(env, jvalue);
4268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    keyedVector.add(key, value);
4278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    env->DeleteLocalRef(jkey);
4298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    env->DeleteLocalRef(jvalue);
4308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                    hasNext = env->CallBooleanMethod(iterator, gFields.iterator.hasNext);
4318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                }
4328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env->DeleteLocalRef(entry);
4338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            }
4348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker            env->DeleteLocalRef(iterator);
4358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        }
4368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(entrySet);
4378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return keyedVector;
4398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject KeyedVectorToHashMap (JNIEnv *env, KeyedVector<String8, String8> const &map) {
4428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
4438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/HashMap");
4448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject hashMap = env->NewObject(clazz, gFields.hashmap.init);
4458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    for (size_t i = 0; i < map.size(); ++i) {
4468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jkey = env->NewStringUTF(map.keyAt(i).string());
4478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jvalue = env->NewStringUTF(map.valueAt(i).string());
4488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->CallObjectMethod(hashMap, gFields.hashmap.put, jkey, jvalue);
4498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(jkey);
4508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(jvalue);
4518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return hashMap;
4538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
4568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                                                   List<Vector<uint8_t> > list) {
4578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
4588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/ArrayList");
4598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
4608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    List<Vector<uint8_t> >::iterator iter = list.begin();
4618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    while (iter != list.end()) {
4628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray byteArray = VectorToJByteArray(env, *iter);
4638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
4648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->DeleteLocalRef(byteArray);
4658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        iter++;
4668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return arrayList;
4698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}  // namespace android
4728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerusing namespace android;
4748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic sp<JDrm> setDrm(
4768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, const sp<JDrm> &drm) {
4778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<JDrm> old = (JDrm *)env->GetIntField(thiz, gFields.context);
4788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm != NULL) {
4798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        drm->incStrong(thiz);
4808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (old != NULL) {
4828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        old->decStrong(thiz);
4838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    env->SetIntField(thiz, gFields.context, (int)drm.get());
4858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return old;
4878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
4888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic bool CheckSession(JNIEnv *env, const sp<IDrm> &drm, jbyteArray const &jsessionId)
4908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker{
4918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
492eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException", "MediaDrm obj is null");
4938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
4948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
4958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
4968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jsessionId == NULL) {
497eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", "sessionId is null");
4988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
4998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return true;
5018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_release(JNIEnv *env, jobject thiz) {
50454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    sp<JDrm> drm = setDrm(env, thiz, NULL);
50554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    if (drm != NULL) {
50654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker        drm->setListener(NULL);
50754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    }
5088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_init(JNIEnv *env) {
5118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
5128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm");
5138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_FIELD_ID(gFields.context, clazz, "mNativeContext", "I");
51454cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    GET_STATIC_METHOD_ID(gFields.post_event, clazz, "postEventFromNative",
51554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker                         "(Ljava/lang/Object;IILjava/lang/Object;)V");
51654cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker
51754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    jfieldID field;
518e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_PROVISION_REQUIRED", "I");
51954cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventProvisionRequired = env->GetStaticIntField(clazz, field);
520e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_REQUIRED", "I");
52154cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventKeyRequired = env->GetStaticIntField(clazz, field);
522e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_KEY_EXPIRED", "I");
52354cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventKeyExpired = env->GetStaticIntField(clazz, field);
524e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_STATIC_FIELD_ID(field, clazz, "EVENT_VENDOR_DEFINED", "I");
52554cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    gEventTypes.kEventVendorDefined = env->GetStaticIntField(clazz, field);
5268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
52716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
528e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
529e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
5308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
532e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
533e1c76bebef41d362369627ed0c06ea9a01c6bddbJeff Tinker    GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
5348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/ArrayList");
5368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V");
5378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.arraylist.add, clazz, "add", "(Ljava/lang/Object;)Z");
5388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/HashMap");
5408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.init, clazz, "<init>", "()V");
5418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.get, clazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
5428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.put, clazz, "put",
5438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
5448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.hashmap.entrySet, clazz, "entrySet", "()Ljava/util/Set;");
5458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Set");
5478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.set.iterator, clazz, "iterator", "()Ljava/util/Iterator;");
5488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Iterator");
5508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.iterator.next, clazz, "next", "()Ljava/lang/Object;");
5518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.iterator.hasNext, clazz, "hasNext", "()Z");
5528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "java/util/Map$Entry");
5548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.entry.getKey, clazz, "getKey", "()Ljava/lang/Object;");
5558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    GET_METHOD_ID(gFields.entry.getValue, clazz, "getValue", "()Ljava/lang/Object;");
5568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_setup(
5598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz,
5608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jobject weak_this, jbyteArray uuidObj) {
5618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuidObj == NULL) {
563eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", "uuid is null");
5648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
5658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
5688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuid.size() != 16) {
570eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
571eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "invalid UUID size, expected 16 bytes");
5728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
5738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<JDrm> drm = new JDrm(env, thiz, uuid.array());
5768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->initCheck();
5788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (err != OK) {
5808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(
5818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env,
5821d7c218ba23185c58ae27f59e4ec6b8526b2d04aJeff Tinker                "android/media/UnsupportedSchemeException",
5838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "Failed to instantiate drm object.");
5848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
5858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
5868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
58754cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    sp<JNIDrmListener> listener = new JNIDrmListener(env, thiz, weak_this);
58854cfbd6dc28334119c33b6a77779bfe244c71e69Jeff Tinker    drm->setListener(listener);
5898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    setDrm(env, thiz, drm);
5908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_native_finalize(
5938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz) {
5948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    android_media_MediaDrm_release(env, thiz);
5958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
5968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
5978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
5988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        JNIEnv *env, jobject thiz, jbyteArray uuidObj) {
5998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuidObj == NULL) {
6018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
6028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
6038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
6068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (uuid.size() != 16) {
6088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jniThrowException(
6098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                env,
6108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "java/lang/IllegalArgumentException",
611eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                "invalid UUID size, expected 16 bytes");
6128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return false;
6138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return JDrm::IsCryptoSchemeSupported(uuid.array());
6168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray android_media_MediaDrm_openSession(
6198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
6208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
623eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
624eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
6258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId;
6298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->openSession(sessionId);
6308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to open session")) {
6328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return VectorToJByteArray(env, sessionId);
6368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_closeSession(
6398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
6408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
6438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
6448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
6478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->closeSession(sessionId);
6498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to close session");
6518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
6528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
65316b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jobject android_media_MediaDrm_getKeyRequest(
6548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jinitData,
65516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jstring jmimeType, jint jkeyType, jobject joptParams) {
6568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
6578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
6598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
6638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> initData;
6658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jinitData != NULL) {
6668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        initData = JByteArrayToVector(env, jinitData);
6678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 mimeType;
6708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jmimeType != NULL) {
6718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        mimeType = JStringToString8(env, jmimeType);
6728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
67416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)jkeyType;
6758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> optParams;
6778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (joptParams != NULL) {
6788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        optParams = HashMapToKeyedVector(env, joptParams);
6798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> request;
6828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 defaultUrl;
6838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
68416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->getKeyRequest(sessionId, initData, mimeType,
68516b8cffb2893c10c35788191847500004da466d1Jeff Tinker                                          keyType, optParams, request, defaultUrl);
6868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
68716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get key request")) {
6888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
6898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
6908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    // Fill out return obj
6928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
69316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
6948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
69516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jobject keyObj = NULL;
6968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
6978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (clazz) {
69816b8cffb2893c10c35788191847500004da466d1Jeff Tinker        keyObj = env->AllocObject(clazz);
6998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray jrequest = VectorToJByteArray(env, request);
70016b8cffb2893c10c35788191847500004da466d1Jeff Tinker        env->SetObjectField(keyObj, gFields.keyRequest.data, jrequest);
7018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
70316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        env->SetObjectField(keyObj, gFields.keyRequest.defaultUrl, jdefaultUrl);
7048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
70616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return keyObj;
7078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
70916b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_provideKeyResponse(
7108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId, jbyteArray jresponse) {
7118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
71416b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
7158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
7188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jresponse == NULL) {
720eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
721eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "key response is null");
72216b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
7238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
72516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keySetId;
7268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
72716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->provideKeyResponse(sessionId, response, keySetId);
7288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
72916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to handle key response");
73016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, keySetId);
7318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
73316b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_removeKeys(
73416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jkeysetId) {
73516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
73616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
73716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeysetId == NULL) {
738eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
739eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "keySetId is null");
74016b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
74116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
74216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
74316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));
74416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
74516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->removeKeys(keySetId);
74616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
74716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to remove keys");
74816b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
74916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
75016b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_restoreKeys(
75116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId,
75216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeysetId) {
75316b8cffb2893c10c35788191847500004da466d1Jeff Tinker
7548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
7578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
7588a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7598a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
76016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeysetId == NULL) {
76116b8cffb2893c10c35788191847500004da466d1Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
76216b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
76316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
76416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
7658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
76616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeysetId));
7678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
76816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->restoreKeys(sessionId, keySetId);
7698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
77016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to restore keys");
7718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
77316b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jobject android_media_MediaDrm_queryKeyStatus(
7748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jsessionId) {
7758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
7788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
7798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
7818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    KeyedVector<String8, String8> infoMap;
7838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
78416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->queryKeyStatus(sessionId, infoMap);
7858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
78616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to query key status")) {
7878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
7888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
7898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return KeyedVectorToHashMap(env, infoMap);
7918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
7928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_getProvisionRequest(
7948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
7958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
7968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
7978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
798eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
799eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
8008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> request;
8048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 defaultUrl;
8058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getProvisionRequest(request, defaultUrl);
8078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get provision request")) {
8098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    // Fill out return obj
8138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jclass clazz;
8148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
8158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    jobject provisionObj = NULL;
8178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (clazz) {
8198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        provisionObj = env->AllocObject(clazz);
8208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jbyteArray jrequest = VectorToJByteArray(env, request);
8218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(provisionObj, gFields.provisionRequest.data, jrequest);
8228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        jstring jdefaultUrl = env->NewStringUTF(defaultUrl.string());
8248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        env->SetObjectField(provisionObj, gFields.provisionRequest.defaultUrl, jdefaultUrl);
8258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return provisionObj;
8288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8308a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_provideProvisionResponse(
8318a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jresponse) {
8328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
835eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
836eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
8378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
8388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jresponse == NULL) {
841eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
842eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "provision response is null");
8438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
8448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
8478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->provideProvisionResponse(response);
8498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to handle provision response");
8518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jobject android_media_MediaDrm_getSecureStops(
8548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz) {
8558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8578a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
858eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
859eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
8608a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8618a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8628a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8638a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    List<Vector<uint8_t> > secureStops;
8648a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8658a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getSecureStops(secureStops);
8668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get secure stops")) {
8688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return ListOfVectorsToArrayListOfByteArray(env, secureStops);
8728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_releaseSecureStops(
8758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jbyteArray jssRelease) {
8768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
879eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
880eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
8818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
8828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
8838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> ssRelease(JByteArrayToVector(env, jssRelease));
8858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->releaseSecureStops(ssRelease);
8878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to release secure stops");
8898a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
8908a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8918a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jstring android_media_MediaDrm_getPropertyString(
8928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname) {
8938a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
8948a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
8958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
896eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
897eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
8988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
8998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL) {
902eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
903eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
9048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
9088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 value;
9098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getPropertyString(name, value);
9118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get property")) {
9138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return env->NewStringUTF(value.string());
9178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic jbyteArray android_media_MediaDrm_getPropertyByteArray(
9208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname) {
9218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
924eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
925eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
9268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9288a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9298a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (jname == NULL) {
930eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
931eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
9328a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9338a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9348a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9358a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
9368a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> value;
9378a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9388a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->getPropertyByteArray(name, value);
9398a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9408a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (throwExceptionAsNecessary(env, err, "Failed to get property")) {
9418a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return NULL;
9428a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9438a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9448a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return VectorToJByteArray(env, value);
9458a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9468a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9478a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_setPropertyString(
9488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname, jstring jvalue) {
9498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
952eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
953eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
9548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
9558a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9568a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
957eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jname == NULL) {
958eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
959eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
960eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        return;
961eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    }
962eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker
963eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jvalue == NULL) {
964eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
965eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property value String is null");
9668a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
9678a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9688a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
9708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 value = JStringToString8(env, jvalue);
9718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->setPropertyString(name, value);
9738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set property");
9758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
9768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic void android_media_MediaDrm_setPropertyByteArray(
9788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    JNIEnv *env, jobject thiz, jstring jname, jbyteArray jvalue) {
9798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    sp<IDrm> drm = GetDrm(env, thiz);
9808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    if (drm == NULL) {
982eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalStateException",
983eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "MediaDrm obj is null");
9848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
9858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
987eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jname == NULL) {
988eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
989eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property name String is null");
990eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        return;
991eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    }
992eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker
993eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker    if (jvalue == NULL) {
994eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
995eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "property value byte array is null");
9968a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker        return;
9978a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    }
9988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
9998a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    String8 name = JStringToString8(env, jname);
10008a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    Vector<uint8_t> value = JByteArrayToVector(env, jvalue);
10018a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10028a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    status_t err = drm->setPropertyByteArray(name, value);
10038a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
10048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set property");
10058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
10068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
100716b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_setCipherAlgorithmNative(
100816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
100916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jstring jalgorithm) {
101016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
101116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
101216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
101316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
101416b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
101516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
101616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
101716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jalgorithm == NULL) {
1018eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1019eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "algorithm String is null");
102016b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
102116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
102216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
102316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
102416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    String8 algorithm = JStringToString8(env, jalgorithm);
102516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
102616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->setCipherAlgorithm(sessionId, algorithm);
102716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
102816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set cipher algorithm");
102916b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
103016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
103116b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic void android_media_MediaDrm_setMacAlgorithmNative(
103216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
103316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jstring jalgorithm) {
103416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
103516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
103616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
103716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
103816b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
103916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
104016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
104116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jalgorithm == NULL) {
1042eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1043eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "algorithm String is null");
104416b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return;
104516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
104616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
104716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
104816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    String8 algorithm = JStringToString8(env, jalgorithm);
104916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
105016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->setMacAlgorithm(sessionId, algorithm);
105116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
105216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to set mac algorithm");
105316b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
105416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
105516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
105616b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_encryptNative(
105716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
105816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
105916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
106016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
106116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
106216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
106316b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
106416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
106516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
106616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
1067eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1068eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
106916b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
107016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
107116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
107216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
107316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
107416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> input(JByteArrayToVector(env, jinput));
107516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
107616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> output;
107716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
107816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->encrypt(sessionId, keyId, input, iv, output);
107916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
108016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to encrypt");
108116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
108216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, output);
108316b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
108416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
108516b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_decryptNative(
108616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
108716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) {
108816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
108916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
109016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
109116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
109216b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
109316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
109416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
109516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
1096eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1097eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
109816b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
109916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
110016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
110116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
110216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
110316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> input(JByteArrayToVector(env, jinput));
110416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> iv(JByteArrayToVector(env, jiv));
110516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> output;
110616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
110716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->decrypt(sessionId, keyId, input, iv, output);
110816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to decrypt");
110916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, output);
111116b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
111216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111316b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jbyteArray android_media_MediaDrm_signNative(
111416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
111516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jmessage) {
111616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
111816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
111916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
112016b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
112116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
112216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
112316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jmessage == NULL) {
1124eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1125eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
112616b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return NULL;
112716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
112816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
112916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
113016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
113116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
113216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> signature;
113316b8cffb2893c10c35788191847500004da466d1Jeff Tinker
113416b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->sign(sessionId, keyId, message, signature);
113516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
113616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to sign");
113716b8cffb2893c10c35788191847500004da466d1Jeff Tinker
113816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return VectorToJByteArray(env, signature);
113916b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
114016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
114116b8cffb2893c10c35788191847500004da466d1Jeff Tinkerstatic jboolean android_media_MediaDrm_verifyNative(
114216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId,
114316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    jbyteArray jkeyId, jbyteArray jmessage, jbyteArray jsignature) {
114416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
114516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    sp<IDrm> drm = GetDrm(env, jdrm);
114616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
114716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (!CheckSession(env, drm, jsessionId)) {
114816b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return false;
114916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
115016b8cffb2893c10c35788191847500004da466d1Jeff Tinker
115116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    if (jkeyId == NULL || jmessage == NULL || jsignature == NULL) {
1152eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker        jniThrowException(env, "java/lang/IllegalArgumentException",
1153eada5376d9c34f77bd3ba86a2ea674e3bde5e961Jeff Tinker                          "required argument is null");
115416b8cffb2893c10c35788191847500004da466d1Jeff Tinker        return false;
115516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    }
115616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
115716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
115816b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> keyId(JByteArrayToVector(env, jkeyId));
115916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> message(JByteArrayToVector(env, jmessage));
116016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    Vector<uint8_t> signature(JByteArrayToVector(env, jsignature));
116116b8cffb2893c10c35788191847500004da466d1Jeff Tinker    bool match;
116216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
116316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    status_t err = drm->verify(sessionId, keyId, message, signature, match);
116416b8cffb2893c10c35788191847500004da466d1Jeff Tinker
116516b8cffb2893c10c35788191847500004da466d1Jeff Tinker    throwExceptionAsNecessary(env, err, "Failed to verify");
116616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    return match;
116716b8cffb2893c10c35788191847500004da466d1Jeff Tinker}
116816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
11698a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11708a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerstatic JNINativeMethod gMethods[] = {
11718a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "release", "()V", (void *)android_media_MediaDrm_release },
11728a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_init", "()V", (void *)android_media_MediaDrm_native_init },
11738a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11748a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_setup", "(Ljava/lang/Object;[B)V",
11758a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_native_setup },
11768a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11778a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "native_finalize", "()V",
11788a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_native_finalize },
11798a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11808a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "isCryptoSchemeSupportedNative", "([B)Z",
11818a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },
11828a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11838a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "openSession", "()[B",
11848a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_openSession },
11858a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
11868a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "closeSession", "([B)V",
11878a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_closeSession },
11888a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
118916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
119016b8cffb2893c10c35788191847500004da466d1Jeff Tinker      "Landroid/media/MediaDrm$KeyRequest;",
119116b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_getKeyRequest },
11928a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
119316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "provideKeyResponse", "([B[B)[B",
119416b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_provideKeyResponse },
11958a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
119616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "removeKeys", "([B)V",
119716b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_removeKeys },
11988a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
119916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "restoreKeys", "([B[B)V",
120016b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_restoreKeys },
120116b8cffb2893c10c35788191847500004da466d1Jeff Tinker
120216b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "queryKeyStatus", "([B)Ljava/util/HashMap;",
120316b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_queryKeyStatus },
12048a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12058a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getProvisionRequest", "()Landroid/media/MediaDrm$ProvisionRequest;",
12068a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getProvisionRequest },
12078a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12088a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "provideProvisionResponse", "([B)V",
12098a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_provideProvisionResponse },
12108a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12118a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getSecureStops", "()Ljava/util/List;",
12128a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getSecureStops },
12138a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12148a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "releaseSecureStops", "([B)V",
12158a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_releaseSecureStops },
12168a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12178a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
12188a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getPropertyString },
12198a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12208a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "getPropertyByteArray", "(Ljava/lang/String;)[B",
12218a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_getPropertyByteArray },
12228a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12238a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "setPropertyString", "(Ljava/lang/String;Ljava/lang/String;)V",
12248a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_setPropertyString },
12258a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12268a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    { "setPropertyByteArray", "(Ljava/lang/String;[B)V",
12278a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker      (void *)android_media_MediaDrm_setPropertyByteArray },
122816b8cffb2893c10c35788191847500004da466d1Jeff Tinker
122916b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "setCipherAlgorithmNative",
123016b8cffb2893c10c35788191847500004da466d1Jeff Tinker      "(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
123116b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_setCipherAlgorithmNative },
123216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
123316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "setMacAlgorithmNative",
123416b8cffb2893c10c35788191847500004da466d1Jeff Tinker      "(Landroid/media/MediaDrm;[BLjava/lang/String;)V",
123516b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_setMacAlgorithmNative },
123616b8cffb2893c10c35788191847500004da466d1Jeff Tinker
123716b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "encryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
123816b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_encryptNative },
123916b8cffb2893c10c35788191847500004da466d1Jeff Tinker
124016b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "decryptNative", "(Landroid/media/MediaDrm;[B[B[B[B)[B",
124116b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_decryptNative },
124216b8cffb2893c10c35788191847500004da466d1Jeff Tinker
124316b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "signNative", "(Landroid/media/MediaDrm;[B[B[B)[B",
124416b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_signNative },
124516b8cffb2893c10c35788191847500004da466d1Jeff Tinker
124616b8cffb2893c10c35788191847500004da466d1Jeff Tinker    { "verifyNative", "(Landroid/media/MediaDrm;[B[B[B[B)Z",
124716b8cffb2893c10c35788191847500004da466d1Jeff Tinker      (void *)android_media_MediaDrm_verifyNative },
12488a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker};
12498a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
12508a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinkerint register_android_media_Drm(JNIEnv *env) {
12518a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker    return AndroidRuntime::registerNativeMethods(env,
12528a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker                "android/media/MediaDrm", gMethods, NELEM(gMethods));
12538a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker}
12548a0c80fdcc46faa8cb8c9f4dda06f4b63ec2f906Jeff Tinker
1255