1d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi/*
2d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Copyright (C) 2010 The Android Open Source Project
3d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
4d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
5d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * you may not use this file except in compliance with the License.
6d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * You may obtain a copy of the License at
7d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
8d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
9d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
10d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Unless required by applicable law or agreed to in writing, software
11d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
12d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * See the License for the specific language governing permissions and
14d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * limitations under the License.
15d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi */
16d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
17dc549d60f98d809f626c99de614960409a847054Takeshi Aimi//#define LOG_NDEBUG 0
18c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi#define LOG_TAG "android_drm_DrmManagerClient"
19d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <utils/Log.h>
20d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
21d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <jni.h>
22d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <JNIHelp.h>
23057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson#include <ScopedLocalRef.h>
24d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <android_runtime/AndroidRuntime.h>
25d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
26d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfo.h>
27d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmRights.h>
28d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfoEvent.h>
29d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfoStatus.h>
30d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmInfoRequest.h>
31d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmSupportInfo.h>
32d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmConstraints.h>
33dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi#include <drm/DrmMetadata.h>
34d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/DrmConvertedStatus.h>
35d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <drm/drm_framework_common.h>
36d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
37d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi#include <DrmManagerClientImpl.h>
38d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
39d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiusing namespace android;
40d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
41d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi/**
42d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Utility class used to extract the value from the provided java object.
43d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * May need to add some utility function to create java object.
44d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi */
45d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiclass Utility {
46d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshipublic:
47d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName);
48d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
49d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static char* getByteArrayValue(
50d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject object, const char* fieldName, int* dataLength);
51d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
52d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static char* getByteArrayValue(
53d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jbyteArray byteArray, int* dataLength);
54d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
55d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static String8 getStringValue(JNIEnv* env, jstring string);
56d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
57d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static int getIntValue(JNIEnv* env, jobject object, const char* fieldName);
58d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi};
59d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
60d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
61d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /* Look for the instance field with the name fieldName */
62d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jfieldID fieldID
63d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");
64d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
65d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != fieldID) {
66d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jstring valueString = (jstring) env->GetObjectField(object, fieldID);
67f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong        return Utility::getStringValue(env, valueString);
68d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
69f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong
70f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong    String8 dataString("");
71d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return dataString;
72d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
73d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
74d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiString8 Utility::getStringValue(JNIEnv* env, jstring string) {
75d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    String8 dataString("");
76d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
77d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != string && string != env->NewStringUTF("")) {
78d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));
79d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
80d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        const int length = strlen(bytes) + 1;
81d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        char *data = new char[length];
82d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        strncpy(data, bytes, length);
83d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        dataString = String8(data);
84d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
85d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        env->ReleaseStringUTFChars(string, bytes);
86d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        delete [] data; data = NULL;
87d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
88d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return dataString;
89d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
90d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
91d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshichar* Utility::getByteArrayValue(
92d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
93f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong
94d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    *dataLength = 0;
95d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
96d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
97d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
98d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != fieldID) {
99d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
100f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong        return Utility::getByteArrayValue(env, byteArray, dataLength);
101d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
102f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong    return NULL;
103d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
104d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
105d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshichar* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {
106d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    char* data = NULL;
107d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != byteArray) {
108d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jint length = env->GetArrayLength(byteArray);
109d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
110d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        *dataLength = length;
111d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (0 < *dataLength) {
112d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            data = new char[length];
113d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
114d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
115d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
116d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return data;
117d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
118d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
119d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiint Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {
120d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jfieldID fieldID;
121d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int intValue = -1;
122d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
123d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /* Get a reference to obj’s class */
124d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->GetObjectClass(object);
125d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /* Look for the instance field with the name fieldName */
126d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    fieldID = env->GetFieldID(clazz, fieldName , "I");
127d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
128d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != fieldID) {
129d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        intValue = (int) env->GetIntField(object, fieldID);
130d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
131d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
132d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return intValue;
133d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
134d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
135d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiclass JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
136d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshipublic:
137d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
138d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
139d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    virtual ~JNIOnInfoListener();
140d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    void onInfo(const DrmInfoEvent& event);
141d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
142d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiprivate:
143d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    JNIOnInfoListener();
144d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass mClass;
145d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobject mObject;
146d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi};
147d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
148d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiJNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
149d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->GetObjectClass(thiz);
150d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
151d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (clazz == NULL) {
152c6aacce37191e1cc79cfeba13b39899f59c68c3bSteve Block        ALOGE("Can't find android/drm/DrmManagerClient");
153d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jniThrowException(env, "java/lang/Exception", NULL);
154d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return;
155d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
156d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mClass = (jclass)env->NewGlobalRef(clazz);
157d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    mObject  = env->NewGlobalRef(weak_thiz);
158d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
159d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
160d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiJNIOnInfoListener::~JNIOnInfoListener() {
161d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    JNIEnv *env = AndroidRuntime::getJNIEnv();
162d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    env->DeleteGlobalRef(mObject);
163d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    env->DeleteGlobalRef(mClass);
164d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
165d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
166d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshivoid JNIOnInfoListener::onInfo(const DrmInfoEvent& event) {
167d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jint uniqueId = event.getUniqueId();
168d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jint type = event.getType();
169d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    JNIEnv *env = AndroidRuntime::getJNIEnv();
170d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jstring message = env->NewStringUTF(event.getMessage().string());
17106ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
172d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
173d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    env->CallStaticVoidMethod(
174d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            mClass,
175d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
176d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            mObject, uniqueId, type, message);
177d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
178d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
179d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic Mutex sLock;
180d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
181d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic sp<DrmManagerClientImpl> setDrmManagerClientImpl(
182d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
183d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Mutex::Autolock l(sLock);
184d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
185d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
186d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
187d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
188d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (client.get()) {
189d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        client->incStrong(thiz);
190d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
191d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (old != 0) {
192d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        old->decStrong(thiz);
193d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
194d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    env->SetIntField(thiz, fieldId, (int)client.get());
195d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return old;
196d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
197d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
198d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
199d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    Mutex::Autolock l(sLock);
200d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->FindClass("android/drm/DrmManagerClient");
201d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
202d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
203d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
204d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return sp<DrmManagerClientImpl>(client);
205d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
206d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
207a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wangstatic jint android_drm_DrmManagerClient_initialize(
2086225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        JNIEnv* env, jobject thiz) {
20906ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("initialize - Enter");
210d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
211a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    int uniqueId = 0;
212a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
213c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    drmManager->addClient(uniqueId);
214d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
215d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    setDrmManagerClientImpl(env, thiz, drmManager);
21606ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("initialize - Exit");
217a17d454fd0d20d14cf1fbc09f0f296cb6cbb870bGloria Wang    return uniqueId;
218d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
219d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
2206225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashistatic void android_drm_DrmManagerClient_setListeners(
2216225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
2226225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    ALOGV("setListeners - Enter");
2236225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
2246225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    // Set the listener to DrmManager
2256225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
2266225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
2276225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
2286225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    ALOGV("setListeners - Exit");
2296225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi}
2306225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
2316225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashistatic void android_drm_DrmManagerClient_release(
2326225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        JNIEnv* env, jobject thiz, jint uniqueId) {
2336225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    ALOGV("release - Enter");
234d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmManagerClientImpl::remove(uniqueId);
235c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
236d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
237c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
238c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    if (oldClient != NULL) {
239c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        oldClient->setOnInfoListener(uniqueId, NULL);
240c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        oldClient->removeClient(uniqueId);
241d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
2426225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    ALOGV("release - Exit");
243d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
244d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
245d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic jobject android_drm_DrmManagerClient_getConstraintsFromContent(
246d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
24706ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("GetConstraints - Enter");
248d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
249d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 pathString = Utility::getStringValue(env, jpath);
250d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmConstraints* pConstraints
251d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
252d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
253d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass localRef = env->FindClass("android/content/ContentValues");
254057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID ContentValues_putByteArray =
255057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson            env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
256057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID ContentValues_putString =
257057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson            env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
258057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
259d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobject constraints = NULL;
260d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
261d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != localRef && NULL != pConstraints) {
262d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        // create the java DrmConstraints object
263057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        constraints = env->NewObject(localRef, ContentValues_constructor);
264d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
265d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
266d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        while (keyIt.hasNext()) {
267d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 key = keyIt.next();
268d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
269d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            // insert the entry<constraintKey, constraintValue> to newly created java object
270d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            if (DrmConstraints::EXTENDED_METADATA == key) {
271d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                const char* value = pConstraints->getAsByteArray(&key);
272d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                if (NULL != value) {
273057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
274057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
275057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
276057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    env->CallVoidMethod(constraints, ContentValues_putByteArray,
277057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                                        keyString.get(), dataArray.get());
278d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                }
279d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            } else {
280d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                String8 value = pConstraints->get(key);
281057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
282057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
283057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                env->CallVoidMethod(constraints, ContentValues_putString,
284057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                                    keyString.get(), valueString.get());
285d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
286d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
287d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
288d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
289d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    delete pConstraints; pConstraints = NULL;
29006ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("GetConstraints - Exit");
291d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return constraints;
292d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
293d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
294dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimistatic jobject android_drm_DrmManagerClient_getMetadataFromContent(
295dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
29606ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("GetMetadata - Enter");
297dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    const String8 pathString = Utility::getStringValue(env, jpath);
298dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    DrmMetadata* pMetadata =
299dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
300dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
301dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    jobject metadata = NULL;
302dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
303057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jclass localRef = env->FindClass("android/content/ContentValues");
304057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID ContentValues_putString =
305057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson            env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
306057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson
307dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    if (NULL != localRef && NULL != pMetadata) {
308dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        // Get the constructor id
309dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        jmethodID constructorId = NULL;
310dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        constructorId = env->GetMethodID(localRef, "<init>", "()V");
311dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        if (NULL != constructorId) {
312dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            // create the java DrmMetadata object
313dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            metadata = env->NewObject(localRef, constructorId);
314dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            if (NULL != metadata) {
315dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
316dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                while (keyIt.hasNext()) {
317dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                    String8 key = keyIt.next();
318dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                    // insert the entry<constraintKey, constraintValue>
319dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                    // to newly created java object
320dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                    String8 value = pMetadata->get(key);
321057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
322057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
323057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                    env->CallVoidMethod(metadata, ContentValues_putString,
324057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                                        keyString.get(), valueString.get());
325dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi                }
326dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            }
327dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        }
328dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
329dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    delete pMetadata; pMetadata = NULL;
33006ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("GetMetadata - Exit");
331dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    return metadata;
332dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi}
333dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
334d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
335d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId) {
33606ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("GetAllSupportInfo - Enter");
337d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmSupportInfo* drmSupportInfoArray = NULL;
338d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
339d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int length = 0;
340d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
341d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
342d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
343d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
344d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
345d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
346d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    for (int i = 0; i < length; i++) {
347d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmSupportInfo info = drmSupportInfoArray[i];
348d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
349d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
350d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
351d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jmethodID addMimeTypeId
352d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
353d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jmethodID addFileSuffixId
354d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
355d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
356d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        env->CallVoidMethod(
357d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
358d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->NewStringUTF(info.getDescription().string()));
359d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
360d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
361d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        while (iterator.hasNext()) {
362d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8  value = iterator.next();
363d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
364d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
365d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
366d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
367d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        while (it.hasNext()) {
368d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            String8 value = it.next();
369d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->CallVoidMethod(
370d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
371d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
372d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
373d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        env->SetObjectArrayElement(array, i, drmSupportInfo);
374d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
375d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
376d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
37706ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("GetAllSupportInfo - Exit");
378d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return array;
379d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
380d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
381d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic void android_drm_DrmManagerClient_installDrmEngine(
382d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
38306ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("installDrmEngine - Enter");
384d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    //getDrmManagerClient(env, thiz)
385d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    //  ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
38606ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("installDrmEngine - Exit");
387d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
388d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
389dc549d60f98d809f626c99de614960409a847054Takeshi Aimistatic jint android_drm_DrmManagerClient_saveRights(
390d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId,
391d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            jobject drmRights, jstring rightsPath, jstring contentPath) {
39206ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("saveRights - Enter");
393dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    int result = DRM_ERROR_UNKNOWN;
394d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int dataLength = 0;
395d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    char* mData =  Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
396d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
397d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != mData) {
398d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmRights rights(DrmBuffer(mData, dataLength),
399d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                Utility::getStringValue(env, drmRights, "mMimeType"),
400d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                Utility::getStringValue(env, drmRights, "mAccountId"),
401d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                Utility::getStringValue(env, drmRights, "mSubscriptionId"));
402dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        result = getDrmManagerClientImpl(env, thiz)
403d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
404d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                                Utility::getStringValue(env, contentPath));
405d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
406d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
407f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong    delete[] mData; mData = NULL;
40806ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("saveRights - Exit");
409dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    return result;
410d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
411d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
412d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic jboolean android_drm_DrmManagerClient_canHandle(
413d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
41406ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("canHandle - Enter");
415d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jboolean result
416d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        = getDrmManagerClientImpl(env, thiz)
417d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            ->canHandle(uniqueId, Utility::getStringValue(env, path),
418d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    Utility::getStringValue(env, mimeType));
41906ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("canHandle - Exit");
420d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return result;
421d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
422d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
423d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic jobject android_drm_DrmManagerClient_processDrmInfo(
424d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
42506ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("processDrmInfo - Enter");
426d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int dataLength = 0;
427d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 mMimeType =  Utility::getStringValue(env, drmInfoObject, "mMimeType");
428d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    char* mData =  Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
429d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
430d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
431d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const DrmBuffer buffer(mData, dataLength);
432d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmInfo drmInfo(mInfoType, buffer, mMimeType);
433d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
434d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->FindClass("android/drm/DrmInfo");
435057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
436d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobject keyIterator
437d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        = env->CallObjectMethod(drmInfoObject,
438d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
439d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
440057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jclass Iterator_class = env->FindClass("java/util/Iterator");
441057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
442057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
443057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson
444057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jclass Object_class = env->FindClass("java/lang/Object");
445057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
446057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson
447057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
448057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        ScopedLocalRef<jstring> key(env,
449057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
450057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        ScopedLocalRef<jobject> valueObject(env,
451057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
452057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        ScopedLocalRef<jstring> valString(env, NULL);
453057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        if (NULL != valueObject.get()) {
454057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson            valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
455d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
456d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
457057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        String8 keyString = Utility::getStringValue(env, key.get());
458057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        String8 valueString = Utility::getStringValue(env, valString.get());
45906ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block        ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
460d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
461d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        drmInfo.put(keyString, valueString);
462d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
463d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
464d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmInfoStatus* pDrmInfoStatus
465d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
466d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
467d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
468d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobject drmInfoStatus = NULL;
469d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
470d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != localRef && NULL != pDrmInfoStatus) {
471d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        int statusCode = pDrmInfoStatus->statusCode;
472c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        int infoType = pDrmInfoStatus->infoType;
473d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
474d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jbyteArray dataArray = NULL;
475d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (NULL != pDrmInfoStatus->drmBuffer) {
476d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int length = pDrmInfoStatus->drmBuffer->length;
477d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            dataArray = env->NewByteArray(length);
478d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->SetByteArrayRegion(
479d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
480d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
481d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            delete [] pDrmInfoStatus->drmBuffer->data;
482d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
483d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
484d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jclass clazz = env->FindClass("android/drm/ProcessedData");
485d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jmethodID constructorId
486d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
487d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jobject processedData = env->NewObject(clazz, constructorId, dataArray,
488d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
489d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
490d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
491d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        constructorId
492d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            = env->GetMethodID(localRef,
493c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
494d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
495c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
496c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
497d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
498d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
499f16a2724e08d59c09c95d0fc0db09cfbe67f6141James Dong    delete[] mData; mData = NULL;
500d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    delete pDrmInfoStatus; pDrmInfoStatus = NULL;
501d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
50206ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("processDrmInfo - Exit");
503d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    return drmInfoStatus;
504d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
505d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
506d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshistatic jobject android_drm_DrmManagerClient_acquireDrmInfo(
507d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
50806ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block    ALOGV("acquireDrmInfo Enter");
509d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    const String8 mMimeType =  Utility::getStringValue(env, drmInfoRequest, "mMimeType");
510d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
511d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
512d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
513d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
514d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
515d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobject keyIterator
516d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        = env->CallObjectMethod(drmInfoRequest,
517d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
518057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
519057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson            "get", "(Ljava/lang/String;)Ljava/lang/Object;");
520d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
521057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jclass Iterator_class = env->FindClass("java/util/Iterator");
522057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
523057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
524d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
525057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson    while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
526057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        ScopedLocalRef<jstring> key(env,
527057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
528057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        ScopedLocalRef<jstring> value(env,
529057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson                (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
530d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
531057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        String8 keyString = Utility::getStringValue(env, key.get());
532057b086e0e054247840060cbd1e14295a214221bHenrik B Andersson        String8 valueString = Utility::getStringValue(env, value.get());
53306ade6ae1bd015e8b8ad0685847911213c93cc5bSteve Block        ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
534d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
535d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        drmInfoReq.put(keyString, valueString);
536d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
537d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
538d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
539d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
540d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    jobject drmInfoObject = NULL;
541d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
542d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    if (NULL != pDrmInfo) {
543d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        jclass localRef = env->FindClass("android/drm/DrmInfo");
544d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
545d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (NULL != localRef) {
546d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int length = pDrmInfo->getData().length;
547d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
548d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            jbyteArray dataArray = env->NewByteArray(length);
549d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
550d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
551d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            drmInfoObject
552d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                = env->NewObject(localRef,
553d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    env->GetMethodID(