blob: 7fce3d050fc4fd7f0938d625718b6b10ad0a09d4 [file] [log] [blame]
aimitakeshid074e302010-07-29 10:12:27 +09001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Takeshi Aimidc549d62010-09-20 23:40:41 +090017//#define LOG_NDEBUG 0
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +090018#define LOG_TAG "android_drm_DrmManagerClient"
aimitakeshid074e302010-07-29 10:12:27 +090019#include <utils/Log.h>
20
21#include <jni.h>
22#include <JNIHelp.h>
Henrik B Andersson057b0862012-02-10 13:17:40 +010023#include <ScopedLocalRef.h>
aimitakeshid074e302010-07-29 10:12:27 +090024#include <android_runtime/AndroidRuntime.h>
25
26#include <drm/DrmInfo.h>
27#include <drm/DrmRights.h>
28#include <drm/DrmInfoEvent.h>
29#include <drm/DrmInfoStatus.h>
30#include <drm/DrmInfoRequest.h>
31#include <drm/DrmSupportInfo.h>
32#include <drm/DrmConstraints.h>
Takeshi Aimidc9186562010-11-16 13:56:11 +090033#include <drm/DrmMetadata.h>
aimitakeshid074e302010-07-29 10:12:27 +090034#include <drm/DrmConvertedStatus.h>
35#include <drm/drm_framework_common.h>
36
37#include <DrmManagerClientImpl.h>
38
39using namespace android;
40
41/**
42 * Utility class used to extract the value from the provided java object.
43 * May need to add some utility function to create java object.
44 */
45class Utility {
46public:
47 static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName);
48
49 static char* getByteArrayValue(
50 JNIEnv* env, jobject object, const char* fieldName, int* dataLength);
51
52 static char* getByteArrayValue(
53 JNIEnv* env, jbyteArray byteArray, int* dataLength);
54
55 static String8 getStringValue(JNIEnv* env, jstring string);
56
57 static int getIntValue(JNIEnv* env, jobject object, const char* fieldName);
58};
59
60String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
aimitakeshid074e302010-07-29 10:12:27 +090061 /* Look for the instance field with the name fieldName */
62 jfieldID fieldID
63 = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");
64
65 if (NULL != fieldID) {
66 jstring valueString = (jstring) env->GetObjectField(object, fieldID);
James Dongf16a2722012-03-02 16:49:35 -080067 return Utility::getStringValue(env, valueString);
aimitakeshid074e302010-07-29 10:12:27 +090068 }
James Dongf16a2722012-03-02 16:49:35 -080069
70 String8 dataString("");
aimitakeshid074e302010-07-29 10:12:27 +090071 return dataString;
72}
73
74String8 Utility::getStringValue(JNIEnv* env, jstring string) {
75 String8 dataString("");
76
77 if (NULL != string && string != env->NewStringUTF("")) {
78 char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));
79
80 const int length = strlen(bytes) + 1;
81 char *data = new char[length];
82 strncpy(data, bytes, length);
83 dataString = String8(data);
84
85 env->ReleaseStringUTFChars(string, bytes);
86 delete [] data; data = NULL;
87 }
88 return dataString;
89}
90
91char* Utility::getByteArrayValue(
92 JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
James Dongf16a2722012-03-02 16:49:35 -080093
aimitakeshid074e302010-07-29 10:12:27 +090094 *dataLength = 0;
95
96 jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
97
98 if (NULL != fieldID) {
99 jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
James Dongf16a2722012-03-02 16:49:35 -0800100 return Utility::getByteArrayValue(env, byteArray, dataLength);
aimitakeshid074e302010-07-29 10:12:27 +0900101 }
James Dongf16a2722012-03-02 16:49:35 -0800102 return NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900103}
104
105char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {
106 char* data = NULL;
107 if (NULL != byteArray) {
108 jint length = env->GetArrayLength(byteArray);
109
110 *dataLength = length;
111 if (0 < *dataLength) {
112 data = new char[length];
113 env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
114 }
115 }
116 return data;
117}
118
119int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {
120 jfieldID fieldID;
121 int intValue = -1;
122
123 /* Get a reference to obj’s class */
124 jclass clazz = env->GetObjectClass(object);
125 /* Look for the instance field with the name fieldName */
126 fieldID = env->GetFieldID(clazz, fieldName , "I");
127
128 if (NULL != fieldID) {
129 intValue = (int) env->GetIntField(object, fieldID);
130 }
131
132 return intValue;
133}
134
135class JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
136public:
137 JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
138
139 virtual ~JNIOnInfoListener();
140 void onInfo(const DrmInfoEvent& event);
141
142private:
143 JNIOnInfoListener();
144 jclass mClass;
145 jobject mObject;
146};
147
148JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
149 jclass clazz = env->GetObjectClass(thiz);
150
151 if (clazz == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000152 ALOGE("Can't find android/drm/DrmManagerClient");
aimitakeshid074e302010-07-29 10:12:27 +0900153 jniThrowException(env, "java/lang/Exception", NULL);
154 return;
155 }
156 mClass = (jclass)env->NewGlobalRef(clazz);
157 mObject = env->NewGlobalRef(weak_thiz);
158}
159
160JNIOnInfoListener::~JNIOnInfoListener() {
161 JNIEnv *env = AndroidRuntime::getJNIEnv();
162 env->DeleteGlobalRef(mObject);
163 env->DeleteGlobalRef(mClass);
164}
165
166void JNIOnInfoListener::onInfo(const DrmInfoEvent& event) {
167 jint uniqueId = event.getUniqueId();
168 jint type = event.getType();
169 JNIEnv *env = AndroidRuntime::getJNIEnv();
170 jstring message = env->NewStringUTF(event.getMessage().string());
Steve Block06ade6a2011-10-20 11:56:00 +0100171 ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
Takeshi Aimi6fd97b72012-07-11 17:13:38 +0900172 const DrmBuffer& drmBuffer = event.getData();
173 if (event.getCount() > 0 || drmBuffer.length > 0) {
174 jclass hashMapClazz = env->FindClass("java/util/HashMap");
175 jmethodID hashMapInitId = env->GetMethodID(hashMapClazz, "<init>", "()V");
176 jmethodID hashMapPutId = env->GetMethodID(hashMapClazz, "put",
177 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
178 jobject hashMapObject = env->NewObject(hashMapClazz, hashMapInitId);
179 env->DeleteLocalRef(hashMapClazz);
aimitakeshid074e302010-07-29 10:12:27 +0900180
Takeshi Aimi6fd97b72012-07-11 17:13:38 +0900181 if (0 < drmBuffer.length) {
182 jfieldID fid = env->GetStaticFieldID(
183 mClass, "EXTENDED_INFO_DATA", "Ljava/lang/String;");
184 jstring key = (jstring) env->GetStaticObjectField(mClass, fid);
185
186 jbyteArray valueByte = env->NewByteArray(drmBuffer.length);
187 env->SetByteArrayRegion(valueByte, 0, drmBuffer.length, (jbyte*) drmBuffer.data);
188 env->CallObjectMethod(hashMapObject, hashMapPutId, key, valueByte);
189 env->DeleteLocalRef(valueByte);
190 env->DeleteLocalRef(key);
191 }
192 DrmInfoEvent::KeyIterator keyIt = event.keyIterator();
193 while (keyIt.hasNext()) {
194 String8 mapKey = keyIt.next();
195 jstring key = env->NewStringUTF(mapKey.string());
196 jstring value = env->NewStringUTF(event.get(mapKey).string());
197 env->CallObjectMethod(hashMapObject, hashMapPutId, key, value);
198 env->DeleteLocalRef(value);
199 env->DeleteLocalRef(key);
200 }
201 env->CallStaticVoidMethod(
202 mClass,
203 env->GetStaticMethodID(mClass, "notify",
204 "(Ljava/lang/Object;IILjava/lang/String;Ljava/util/HashMap;)V"),
205 mObject, uniqueId, type, message, hashMapObject);
206 env->DeleteLocalRef(hashMapObject);
207 } else {
208 env->CallStaticVoidMethod(
209 mClass,
210 env->GetStaticMethodID(mClass, "notify",
211 "(Ljava/lang/Object;IILjava/lang/String;)V"),
212 mObject, uniqueId, type, message);
213 }
214 env->DeleteLocalRef(message);
aimitakeshid074e302010-07-29 10:12:27 +0900215}
216
217static Mutex sLock;
218
219static sp<DrmManagerClientImpl> setDrmManagerClientImpl(
220 JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
221 Mutex::Autolock l(sLock);
222 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
223 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
224
225 sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
226 if (client.get()) {
227 client->incStrong(thiz);
228 }
229 if (old != 0) {
230 old->decStrong(thiz);
231 }
232 env->SetIntField(thiz, fieldId, (int)client.get());
233 return old;
234}
235
236static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
237 Mutex::Autolock l(sLock);
238 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
239 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
240
241 DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
242 return sp<DrmManagerClientImpl>(client);
243}
244
Gloria Wanga17d4542011-07-21 15:10:22 -0700245static jint android_drm_DrmManagerClient_initialize(
Kei Takahashi6225df02012-01-31 13:18:45 +0900246 JNIEnv* env, jobject thiz) {
Steve Block06ade6a2011-10-20 11:56:00 +0100247 ALOGV("initialize - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900248
Gloria Wanga17d4542011-07-21 15:10:22 -0700249 int uniqueId = 0;
250 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900251 drmManager->addClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900252
aimitakeshid074e302010-07-29 10:12:27 +0900253 setDrmManagerClientImpl(env, thiz, drmManager);
Steve Block06ade6a2011-10-20 11:56:00 +0100254 ALOGV("initialize - Exit");
Gloria Wanga17d4542011-07-21 15:10:22 -0700255 return uniqueId;
aimitakeshid074e302010-07-29 10:12:27 +0900256}
257
Kei Takahashi6225df02012-01-31 13:18:45 +0900258static void android_drm_DrmManagerClient_setListeners(
259 JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
260 ALOGV("setListeners - Enter");
261
262 // Set the listener to DrmManager
263 sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
264 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
265
266 ALOGV("setListeners - Exit");
267}
268
269static void android_drm_DrmManagerClient_release(
270 JNIEnv* env, jobject thiz, jint uniqueId) {
271 ALOGV("release - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900272 DrmManagerClientImpl::remove(uniqueId);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900273 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
aimitakeshid074e302010-07-29 10:12:27 +0900274
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900275 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
276 if (oldClient != NULL) {
277 oldClient->setOnInfoListener(uniqueId, NULL);
278 oldClient->removeClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900279 }
Kei Takahashi6225df02012-01-31 13:18:45 +0900280 ALOGV("release - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900281}
282
283static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
284 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
Steve Block06ade6a2011-10-20 11:56:00 +0100285 ALOGV("GetConstraints - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900286
287 const String8 pathString = Utility::getStringValue(env, jpath);
288 DrmConstraints* pConstraints
289 = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
290
291 jclass localRef = env->FindClass("android/content/ContentValues");
Henrik B Andersson057b0862012-02-10 13:17:40 +0100292 jmethodID ContentValues_putByteArray =
293 env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
294 jmethodID ContentValues_putString =
295 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
296 jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
aimitakeshid074e302010-07-29 10:12:27 +0900297 jobject constraints = NULL;
298
299 if (NULL != localRef && NULL != pConstraints) {
aimitakeshid074e302010-07-29 10:12:27 +0900300 // create the java DrmConstraints object
Henrik B Andersson057b0862012-02-10 13:17:40 +0100301 constraints = env->NewObject(localRef, ContentValues_constructor);
aimitakeshid074e302010-07-29 10:12:27 +0900302
303 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
aimitakeshid074e302010-07-29 10:12:27 +0900304 while (keyIt.hasNext()) {
305 String8 key = keyIt.next();
306
307 // insert the entry<constraintKey, constraintValue> to newly created java object
308 if (DrmConstraints::EXTENDED_METADATA == key) {
309 const char* value = pConstraints->getAsByteArray(&key);
310 if (NULL != value) {
Henrik B Andersson057b0862012-02-10 13:17:40 +0100311 ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
312 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
313 env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
314 env->CallVoidMethod(constraints, ContentValues_putByteArray,
315 keyString.get(), dataArray.get());
aimitakeshid074e302010-07-29 10:12:27 +0900316 }
317 } else {
318 String8 value = pConstraints->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100319 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
320 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
321 env->CallVoidMethod(constraints, ContentValues_putString,
322 keyString.get(), valueString.get());
aimitakeshid074e302010-07-29 10:12:27 +0900323 }
324 }
325 }
326
327 delete pConstraints; pConstraints = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100328 ALOGV("GetConstraints - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900329 return constraints;
330}
331
Takeshi Aimidc9186562010-11-16 13:56:11 +0900332static jobject android_drm_DrmManagerClient_getMetadataFromContent(
333 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100334 ALOGV("GetMetadata - Enter");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900335 const String8 pathString = Utility::getStringValue(env, jpath);
336 DrmMetadata* pMetadata =
337 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
338
339 jobject metadata = NULL;
340
Henrik B Andersson057b0862012-02-10 13:17:40 +0100341 jclass localRef = env->FindClass("android/content/ContentValues");
342 jmethodID ContentValues_putString =
343 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
344
Takeshi Aimidc9186562010-11-16 13:56:11 +0900345 if (NULL != localRef && NULL != pMetadata) {
346 // Get the constructor id
347 jmethodID constructorId = NULL;
348 constructorId = env->GetMethodID(localRef, "<init>", "()V");
349 if (NULL != constructorId) {
350 // create the java DrmMetadata object
351 metadata = env->NewObject(localRef, constructorId);
352 if (NULL != metadata) {
353 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
354 while (keyIt.hasNext()) {
355 String8 key = keyIt.next();
356 // insert the entry<constraintKey, constraintValue>
357 // to newly created java object
358 String8 value = pMetadata->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100359 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
360 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
361 env->CallVoidMethod(metadata, ContentValues_putString,
362 keyString.get(), valueString.get());
Takeshi Aimidc9186562010-11-16 13:56:11 +0900363 }
364 }
365 }
366 }
367 delete pMetadata; pMetadata = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100368 ALOGV("GetMetadata - Exit");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900369 return metadata;
370}
371
aimitakeshid074e302010-07-29 10:12:27 +0900372static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
373 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100374 ALOGV("GetAllSupportInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900375 DrmSupportInfo* drmSupportInfoArray = NULL;
376
377 int length = 0;
378 getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
379
380 jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
381
382 jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
383
384 for (int i = 0; i < length; i++) {
385 DrmSupportInfo info = drmSupportInfoArray[i];
386
387 jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
388
389 jmethodID addMimeTypeId
390 = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
391 jmethodID addFileSuffixId
392 = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
393
394 env->CallVoidMethod(
395 drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
396 env->NewStringUTF(info.getDescription().string()));
397
398 DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
399 while (iterator.hasNext()) {
400 String8 value = iterator.next();
401 env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
402 }
403
404 DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
405 while (it.hasNext()) {
406 String8 value = it.next();
407 env->CallVoidMethod(
408 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
409 }
410
411 env->SetObjectArrayElement(array, i, drmSupportInfo);
412 }
413
414 delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100415 ALOGV("GetAllSupportInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900416 return array;
417}
418
419static void android_drm_DrmManagerClient_installDrmEngine(
420 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100421 ALOGV("installDrmEngine - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900422 //getDrmManagerClient(env, thiz)
423 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
Steve Block06ade6a2011-10-20 11:56:00 +0100424 ALOGV("installDrmEngine - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900425}
426
Takeshi Aimidc549d62010-09-20 23:40:41 +0900427static jint android_drm_DrmManagerClient_saveRights(
aimitakeshid074e302010-07-29 10:12:27 +0900428 JNIEnv* env, jobject thiz, jint uniqueId,
429 jobject drmRights, jstring rightsPath, jstring contentPath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100430 ALOGV("saveRights - Enter");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900431 int result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900432 int dataLength = 0;
433 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
434
435 if (NULL != mData) {
436 DrmRights rights(DrmBuffer(mData, dataLength),
437 Utility::getStringValue(env, drmRights, "mMimeType"),
438 Utility::getStringValue(env, drmRights, "mAccountId"),
439 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900440 result = getDrmManagerClientImpl(env, thiz)
aimitakeshid074e302010-07-29 10:12:27 +0900441 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
442 Utility::getStringValue(env, contentPath));
443 }
444
James Dongf16a2722012-03-02 16:49:35 -0800445 delete[] mData; mData = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100446 ALOGV("saveRights - Exit");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900447 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900448}
449
450static jboolean android_drm_DrmManagerClient_canHandle(
451 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100452 ALOGV("canHandle - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900453 jboolean result
454 = getDrmManagerClientImpl(env, thiz)
455 ->canHandle(uniqueId, Utility::getStringValue(env, path),
456 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100457 ALOGV("canHandle - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900458 return result;
459}
460
461static jobject android_drm_DrmManagerClient_processDrmInfo(
462 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
Steve Block06ade6a2011-10-20 11:56:00 +0100463 ALOGV("processDrmInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900464 int dataLength = 0;
465 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType");
466 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
467 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
468
469 const DrmBuffer buffer(mData, dataLength);
470 DrmInfo drmInfo(mInfoType, buffer, mMimeType);
471
472 jclass clazz = env->FindClass("android/drm/DrmInfo");
Henrik B Andersson057b0862012-02-10 13:17:40 +0100473 jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900474 jobject keyIterator
475 = env->CallObjectMethod(drmInfoObject,
476 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
477
Henrik B Andersson057b0862012-02-10 13:17:40 +0100478 jclass Iterator_class = env->FindClass("java/util/Iterator");
479 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
480 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900481
Henrik B Andersson057b0862012-02-10 13:17:40 +0100482 jclass Object_class = env->FindClass("java/lang/Object");
483 jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
aimitakeshid074e302010-07-29 10:12:27 +0900484
Henrik B Andersson057b0862012-02-10 13:17:40 +0100485 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
486 ScopedLocalRef<jstring> key(env,
487 (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
488 ScopedLocalRef<jobject> valueObject(env,
489 env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
490 ScopedLocalRef<jstring> valString(env, NULL);
491 if (NULL != valueObject.get()) {
492 valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
aimitakeshid074e302010-07-29 10:12:27 +0900493 }
494
Henrik B Andersson057b0862012-02-10 13:17:40 +0100495 String8 keyString = Utility::getStringValue(env, key.get());
496 String8 valueString = Utility::getStringValue(env, valString.get());
Steve Block06ade6a2011-10-20 11:56:00 +0100497 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900498
499 drmInfo.put(keyString, valueString);
500 }
501
502 DrmInfoStatus* pDrmInfoStatus
503 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
504
505 jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
506 jobject drmInfoStatus = NULL;
507
508 if (NULL != localRef && NULL != pDrmInfoStatus) {
509 int statusCode = pDrmInfoStatus->statusCode;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900510 int infoType = pDrmInfoStatus->infoType;
aimitakeshid074e302010-07-29 10:12:27 +0900511
512 jbyteArray dataArray = NULL;
513 if (NULL != pDrmInfoStatus->drmBuffer) {
514 int length = pDrmInfoStatus->drmBuffer->length;
515 dataArray = env->NewByteArray(length);
516 env->SetByteArrayRegion(
517 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
518
519 delete [] pDrmInfoStatus->drmBuffer->data;
520 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
521 }
522 jclass clazz = env->FindClass("android/drm/ProcessedData");
523 jmethodID constructorId
524 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
525 jobject processedData = env->NewObject(clazz, constructorId, dataArray,
526 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
527 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
528
529 constructorId
530 = env->GetMethodID(localRef,
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900531 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
aimitakeshid074e302010-07-29 10:12:27 +0900532
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900533 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
534 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900535 }
536
James Dongf16a2722012-03-02 16:49:35 -0800537 delete[] mData; mData = NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900538 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
539
Steve Block06ade6a2011-10-20 11:56:00 +0100540 ALOGV("processDrmInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900541 return drmInfoStatus;
542}
543
544static jobject android_drm_DrmManagerClient_acquireDrmInfo(
545 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
Steve Block06ade6a2011-10-20 11:56:00 +0100546 ALOGV("acquireDrmInfo Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900547 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType");
548 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
549
550 DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
551
552 jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
553 jobject keyIterator
554 = env->CallObjectMethod(drmInfoRequest,
555 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
Henrik B Andersson057b0862012-02-10 13:17:40 +0100556 jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
557 "get", "(Ljava/lang/String;)Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900558
Henrik B Andersson057b0862012-02-10 13:17:40 +0100559 jclass Iterator_class = env->FindClass("java/util/Iterator");
560 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
561 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900562
Henrik B Andersson057b0862012-02-10 13:17:40 +0100563 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
564 ScopedLocalRef<jstring> key(env,
565 (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
566 ScopedLocalRef<jstring> value(env,
567 (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
aimitakeshid074e302010-07-29 10:12:27 +0900568
Henrik B Andersson057b0862012-02-10 13:17:40 +0100569 String8 keyString = Utility::getStringValue(env, key.get());
570 String8 valueString = Utility::getStringValue(env, value.get());
Steve Block06ade6a2011-10-20 11:56:00 +0100571 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900572
573 drmInfoReq.put(keyString, valueString);
574 }
575
576 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
577
578 jobject drmInfoObject = NULL;
579
580 if (NULL != pDrmInfo) {
581 jclass localRef = env->FindClass("android/drm/DrmInfo");
582
583 if (NULL != localRef) {
584 int length = pDrmInfo->getData().length;
585
586 jbyteArray dataArray = env->NewByteArray(length);
587 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
588
589 drmInfoObject
590 = env->NewObject(localRef,
591 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
592 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
593
594 DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
595 jmethodID putMethodId
596 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
597
598 while (it.hasNext()) {
599 String8 key = it.next();
600 String8 value = pDrmInfo->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100601 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
602 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900603 env->CallVoidMethod(drmInfoObject, putMethodId,
Henrik B Andersson057b0862012-02-10 13:17:40 +0100604 keyString.get(), valueString.get());
aimitakeshid074e302010-07-29 10:12:27 +0900605 }
606 }
607 delete [] pDrmInfo->getData().data;
608 }
609
610 delete pDrmInfo; pDrmInfo = NULL;
611
Steve Block06ade6a2011-10-20 11:56:00 +0100612 ALOGV("acquireDrmInfo Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900613 return drmInfoObject;
614}
615
616static jint android_drm_DrmManagerClient_getDrmObjectType(
617 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100618 ALOGV("getDrmObjectType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900619 int drmObjectType
620 = getDrmManagerClientImpl(env, thiz)
621 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
622 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100623 ALOGV("getDrmObjectType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900624 return drmObjectType;
625}
626
627static jstring android_drm_DrmManagerClient_getOriginalMimeType(
James Dong0889fda2012-08-08 17:45:59 -0700628 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jobject fileDescriptor) {
Steve Block06ade6a2011-10-20 11:56:00 +0100629 ALOGV("getOriginalMimeType Enter");
James Dong0889fda2012-08-08 17:45:59 -0700630
631 int fd = (fileDescriptor == NULL)
632 ? -1
633 : jniGetFDFromFileDescriptor(env, fileDescriptor);
634
aimitakeshid074e302010-07-29 10:12:27 +0900635 String8 mimeType
636 = getDrmManagerClientImpl(env, thiz)
James Dong0889fda2012-08-08 17:45:59 -0700637 ->getOriginalMimeType(uniqueId,
638 Utility::getStringValue(env, path), fd);
Steve Block06ade6a2011-10-20 11:56:00 +0100639 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900640 return env->NewStringUTF(mimeType.string());
641}
642
643static jint android_drm_DrmManagerClient_checkRightsStatus(
644 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
James Dong0889fda2012-08-08 17:45:59 -0700645 ALOGV("checkRightsStatus Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900646 int rightsStatus
647 = getDrmManagerClientImpl(env, thiz)
648 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
James Dong0889fda2012-08-08 17:45:59 -0700649 ALOGV("checkRightsStatus Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900650 return rightsStatus;
651}
652
Takeshi Aimidc549d62010-09-20 23:40:41 +0900653static jint android_drm_DrmManagerClient_removeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900654 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100655 ALOGV("removeRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900656 return getDrmManagerClientImpl(env, thiz)
657 ->removeRights(uniqueId, Utility::getStringValue(env, path));
aimitakeshid074e302010-07-29 10:12:27 +0900658}
659
Takeshi Aimidc549d62010-09-20 23:40:41 +0900660static jint android_drm_DrmManagerClient_removeAllRights(
aimitakeshid074e302010-07-29 10:12:27 +0900661 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100662 ALOGV("removeAllRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900663 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900664}
665
666static jint android_drm_DrmManagerClient_openConvertSession(
667 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100668 ALOGV("openConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900669 int convertId
670 = getDrmManagerClientImpl(env, thiz)
671 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100672 ALOGV("openConvertSession Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900673 return convertId;
674}
675
James Dong9864b252012-03-02 18:36:53 -0800676static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) {
677 ALOGV("GetConvertedStatus - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900678 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
679
680 jobject drmConvertedStatus = NULL;
681
682 if (NULL != localRef && NULL != pDrmConvertedStatus) {
683 int statusCode = pDrmConvertedStatus->statusCode;
684
685 jbyteArray dataArray = NULL;
686 if (NULL != pDrmConvertedStatus->convertedData) {
687 int length = pDrmConvertedStatus->convertedData->length;
688 dataArray = env->NewByteArray(length);
689 env->SetByteArrayRegion(
690 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
691
692 delete [] pDrmConvertedStatus->convertedData->data;
693 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
694 }
695 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
696 drmConvertedStatus
697 = env->NewObject(localRef, constructorId,
698 statusCode, dataArray, pDrmConvertedStatus->offset);
699 }
700
701 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
702
James Dong9864b252012-03-02 18:36:53 -0800703 ALOGV("GetConvertedStatus - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900704 return drmConvertedStatus;
705}
706
James Dong9864b252012-03-02 18:36:53 -0800707static jobject android_drm_DrmManagerClient_convertData(
708 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
709 ALOGV("convertData Enter");
710
711 int dataLength = 0;
712 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
713 const DrmBuffer buffer(mData, dataLength);
714
715 DrmConvertedStatus* pDrmConvertedStatus
716 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
717 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
718
719 delete[] mData;
720 mData = NULL;
721
722 ALOGV("convertData - Exit");
723 return status;
724}
725
726static jobject android_drm_DrmManagerClient_closeConvertSession(
727 JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
728
729 ALOGV("closeConvertSession Enter");
730
731 DrmConvertedStatus* pDrmConvertedStatus
732 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
733 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
734
735 ALOGV("closeConvertSession - Exit");
736 return status;
737}
738
aimitakeshid074e302010-07-29 10:12:27 +0900739static JNINativeMethod nativeMethods[] = {
740
Kei Takahashi6225df02012-01-31 13:18:45 +0900741 {"_initialize", "()I",
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900742 (void*)android_drm_DrmManagerClient_initialize},
aimitakeshid074e302010-07-29 10:12:27 +0900743
Kei Takahashi6225df02012-01-31 13:18:45 +0900744 {"_setListeners", "(ILjava/lang/Object;)V",
745 (void*)android_drm_DrmManagerClient_setListeners},
746
747 {"_release", "(I)V",
748 (void*)android_drm_DrmManagerClient_release},
aimitakeshid074e302010-07-29 10:12:27 +0900749
750 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
751 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
752
Takeshi Aimidc9186562010-11-16 13:56:11 +0900753 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
754 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
755
aimitakeshid074e302010-07-29 10:12:27 +0900756 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
757 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
758
759 {"_installDrmEngine", "(ILjava/lang/String;)V",
760 (void*)android_drm_DrmManagerClient_installDrmEngine},
761
762 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
763 (void*)android_drm_DrmManagerClient_canHandle},
764
765 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
766 (void*)android_drm_DrmManagerClient_processDrmInfo},
767
768 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
769 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
770
Takeshi Aimidc549d62010-09-20 23:40:41 +0900771 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900772 (void*)android_drm_DrmManagerClient_saveRights},
773
774 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
775 (void*)android_drm_DrmManagerClient_getDrmObjectType},
776
James Dong0889fda2012-08-08 17:45:59 -0700777 {"_getOriginalMimeType", "(ILjava/lang/String;Ljava/io/FileDescriptor;)Ljava/lang/String;",
aimitakeshid074e302010-07-29 10:12:27 +0900778 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
779
780 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
781 (void*)android_drm_DrmManagerClient_checkRightsStatus},
782
Takeshi Aimidc549d62010-09-20 23:40:41 +0900783 {"_removeRights", "(ILjava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900784 (void*)android_drm_DrmManagerClient_removeRights},
785
Takeshi Aimidc549d62010-09-20 23:40:41 +0900786 {"_removeAllRights", "(I)I",
aimitakeshid074e302010-07-29 10:12:27 +0900787 (void*)android_drm_DrmManagerClient_removeAllRights},
788
789 {"_openConvertSession", "(ILjava/lang/String;)I",
790 (void*)android_drm_DrmManagerClient_openConvertSession},
791
792 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
793 (void*)android_drm_DrmManagerClient_convertData},
794
795 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
796 (void*)android_drm_DrmManagerClient_closeConvertSession},
797};
798
799static int registerNativeMethods(JNIEnv* env) {
800 int result = -1;
801
802 /* look up the class */
803 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
804
805 if (NULL != clazz) {
806 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
807 / sizeof(nativeMethods[0])) == JNI_OK) {
808 result = 0;
809 }
810 }
811 return result;
812}
813
814jint JNI_OnLoad(JavaVM* vm, void* reserved) {
815 JNIEnv* env = NULL;
816 jint result = -1;
817
818 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
819 if (NULL != env && registerNativeMethods(env) == 0) {
820 result = JNI_VERSION_1_4;
821 }
822 }
823 return result;
824}
825