blob: e34046fe9e31e078dd7fb24241c058e583500b74 [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>
23#include <android_runtime/AndroidRuntime.h>
24
25#include <drm/DrmInfo.h>
26#include <drm/DrmRights.h>
27#include <drm/DrmInfoEvent.h>
28#include <drm/DrmInfoStatus.h>
29#include <drm/DrmInfoRequest.h>
30#include <drm/DrmSupportInfo.h>
31#include <drm/DrmConstraints.h>
Takeshi Aimidc9186562010-11-16 13:56:11 +090032#include <drm/DrmMetadata.h>
aimitakeshid074e302010-07-29 10:12:27 +090033#include <drm/DrmConvertedStatus.h>
34#include <drm/drm_framework_common.h>
35
36#include <DrmManagerClientImpl.h>
37
38using namespace android;
39
40/**
41 * Utility class used to extract the value from the provided java object.
42 * May need to add some utility function to create java object.
43 */
44class Utility {
45public:
46 static String8 getStringValue(JNIEnv* env, jobject object, const char* fieldName);
47
48 static char* getByteArrayValue(
49 JNIEnv* env, jobject object, const char* fieldName, int* dataLength);
50
51 static char* getByteArrayValue(
52 JNIEnv* env, jbyteArray byteArray, int* dataLength);
53
54 static String8 getStringValue(JNIEnv* env, jstring string);
55
56 static int getIntValue(JNIEnv* env, jobject object, const char* fieldName);
57};
58
59String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
60 String8 dataString("");
61
62 /* Look for the instance field with the name fieldName */
63 jfieldID fieldID
64 = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");
65
66 if (NULL != fieldID) {
67 jstring valueString = (jstring) env->GetObjectField(object, fieldID);
68
69 if (NULL != valueString && valueString != env->NewStringUTF("")) {
70 char* bytes = const_cast< char* > (env->GetStringUTFChars(valueString, NULL));
71
72 const int length = strlen(bytes) + 1;
73 char *data = new char[length];
74 strncpy(data, bytes, length);
75 dataString = String8(data);
76
77 env->ReleaseStringUTFChars(valueString, bytes);
78 delete [] data; data = NULL;
79 } else {
Steve Block71f2cf12011-10-20 11:56:00 +010080 ALOGV("Failed to retrieve the data from the field %s", fieldName);
aimitakeshid074e302010-07-29 10:12:27 +090081 }
82 }
83 return dataString;
84}
85
86String8 Utility::getStringValue(JNIEnv* env, jstring string) {
87 String8 dataString("");
88
89 if (NULL != string && string != env->NewStringUTF("")) {
90 char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));
91
92 const int length = strlen(bytes) + 1;
93 char *data = new char[length];
94 strncpy(data, bytes, length);
95 dataString = String8(data);
96
97 env->ReleaseStringUTFChars(string, bytes);
98 delete [] data; data = NULL;
99 }
100 return dataString;
101}
102
103char* Utility::getByteArrayValue(
104 JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
105 char* data = NULL;
106 *dataLength = 0;
107
108 jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
109
110 if (NULL != fieldID) {
111 jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
112 if (NULL != byteArray) {
113 jint length = env->GetArrayLength(byteArray);
114
115 *dataLength = length;
116 if (0 < *dataLength) {
117 data = new char[length];
118 env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
119 }
120 }
121 }
122 return data;
123}
124
125char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {
126 char* data = NULL;
127 if (NULL != byteArray) {
128 jint length = env->GetArrayLength(byteArray);
129
130 *dataLength = length;
131 if (0 < *dataLength) {
132 data = new char[length];
133 env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
134 }
135 }
136 return data;
137}
138
139int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {
140 jfieldID fieldID;
141 int intValue = -1;
142
143 /* Get a reference to obj’s class */
144 jclass clazz = env->GetObjectClass(object);
145 /* Look for the instance field with the name fieldName */
146 fieldID = env->GetFieldID(clazz, fieldName , "I");
147
148 if (NULL != fieldID) {
149 intValue = (int) env->GetIntField(object, fieldID);
150 }
151
152 return intValue;
153}
154
155class JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
156public:
157 JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
158
159 virtual ~JNIOnInfoListener();
160 void onInfo(const DrmInfoEvent& event);
161
162private:
163 JNIOnInfoListener();
164 jclass mClass;
165 jobject mObject;
166};
167
168JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
169 jclass clazz = env->GetObjectClass(thiz);
170
171 if (clazz == NULL) {
172 LOGE("Can't find android/drm/DrmManagerClient");
173 jniThrowException(env, "java/lang/Exception", NULL);
174 return;
175 }
176 mClass = (jclass)env->NewGlobalRef(clazz);
177 mObject = env->NewGlobalRef(weak_thiz);
178}
179
180JNIOnInfoListener::~JNIOnInfoListener() {
181 JNIEnv *env = AndroidRuntime::getJNIEnv();
182 env->DeleteGlobalRef(mObject);
183 env->DeleteGlobalRef(mClass);
184}
185
186void JNIOnInfoListener::onInfo(const DrmInfoEvent& event) {
187 jint uniqueId = event.getUniqueId();
188 jint type = event.getType();
189 JNIEnv *env = AndroidRuntime::getJNIEnv();
190 jstring message = env->NewStringUTF(event.getMessage().string());
Steve Block71f2cf12011-10-20 11:56:00 +0100191 ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
aimitakeshid074e302010-07-29 10:12:27 +0900192
193 env->CallStaticVoidMethod(
194 mClass,
195 env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
196 mObject, uniqueId, type, message);
197}
198
199static Mutex sLock;
200
201static sp<DrmManagerClientImpl> setDrmManagerClientImpl(
202 JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
203 Mutex::Autolock l(sLock);
204 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
205 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
206
207 sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
208 if (client.get()) {
209 client->incStrong(thiz);
210 }
211 if (old != 0) {
212 old->decStrong(thiz);
213 }
214 env->SetIntField(thiz, fieldId, (int)client.get());
215 return old;
216}
217
218static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
219 Mutex::Autolock l(sLock);
220 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
221 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
222
223 DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
224 return sp<DrmManagerClientImpl>(client);
225}
226
Gloria Wanga17d4542011-07-21 15:10:22 -0700227static jint android_drm_DrmManagerClient_initialize(
228 JNIEnv* env, jobject thiz, jobject weak_thiz) {
Steve Block71f2cf12011-10-20 11:56:00 +0100229 ALOGV("initialize - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900230
Gloria Wanga17d4542011-07-21 15:10:22 -0700231 int uniqueId = 0;
232 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900233 drmManager->addClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900234
235 // Set the listener to DrmManager
236 sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
237 drmManager->setOnInfoListener(uniqueId, listener);
238
239 setDrmManagerClientImpl(env, thiz, drmManager);
Steve Block71f2cf12011-10-20 11:56:00 +0100240 ALOGV("initialize - Exit");
Gloria Wanga17d4542011-07-21 15:10:22 -0700241
242 return uniqueId;
aimitakeshid074e302010-07-29 10:12:27 +0900243}
244
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900245static void android_drm_DrmManagerClient_finalize(JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100246 ALOGV("finalize - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900247 DrmManagerClientImpl::remove(uniqueId);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900248 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
aimitakeshid074e302010-07-29 10:12:27 +0900249
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900250 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
251 if (oldClient != NULL) {
252 oldClient->setOnInfoListener(uniqueId, NULL);
253 oldClient->removeClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900254 }
Steve Block71f2cf12011-10-20 11:56:00 +0100255 ALOGV("finalize - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900256}
257
258static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
259 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
Steve Block71f2cf12011-10-20 11:56:00 +0100260 ALOGV("GetConstraints - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900261
262 const String8 pathString = Utility::getStringValue(env, jpath);
263 DrmConstraints* pConstraints
264 = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
265
266 jclass localRef = env->FindClass("android/content/ContentValues");
267 jobject constraints = NULL;
268
269 if (NULL != localRef && NULL != pConstraints) {
270 // Get the constructor id
271 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
272 // create the java DrmConstraints object
273 constraints = env->NewObject(localRef, constructorId);
274
275 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
276
277 while (keyIt.hasNext()) {
278 String8 key = keyIt.next();
279
280 // insert the entry<constraintKey, constraintValue> to newly created java object
281 if (DrmConstraints::EXTENDED_METADATA == key) {
282 const char* value = pConstraints->getAsByteArray(&key);
283 if (NULL != value) {
284 jbyteArray dataArray = env->NewByteArray(strlen(value));
285 env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
286 env->CallVoidMethod(
287 constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
288 env->NewStringUTF(key.string()), dataArray);
289 }
290 } else {
291 String8 value = pConstraints->get(key);
292 env->CallVoidMethod(
293 constraints,
294 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
295 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
296 }
297 }
298 }
299
300 delete pConstraints; pConstraints = NULL;
Steve Block71f2cf12011-10-20 11:56:00 +0100301 ALOGV("GetConstraints - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900302 return constraints;
303}
304
Takeshi Aimidc9186562010-11-16 13:56:11 +0900305static jobject android_drm_DrmManagerClient_getMetadataFromContent(
306 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
Steve Block71f2cf12011-10-20 11:56:00 +0100307 ALOGV("GetMetadata - Enter");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900308 const String8 pathString = Utility::getStringValue(env, jpath);
309 DrmMetadata* pMetadata =
310 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
311
312 jobject metadata = NULL;
313
314 jclass localRef = NULL;
315 localRef = env->FindClass("android/content/ContentValues");
316 if (NULL != localRef && NULL != pMetadata) {
317 // Get the constructor id
318 jmethodID constructorId = NULL;
319 constructorId = env->GetMethodID(localRef, "<init>", "()V");
320 if (NULL != constructorId) {
321 // create the java DrmMetadata object
322 metadata = env->NewObject(localRef, constructorId);
323 if (NULL != metadata) {
324 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
325 while (keyIt.hasNext()) {
326 String8 key = keyIt.next();
327 // insert the entry<constraintKey, constraintValue>
328 // to newly created java object
329 String8 value = pMetadata->get(key);
330 env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
331 "(Ljava/lang/String;Ljava/lang/String;)V"),
332 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
333 }
334 }
335 }
336 }
337 delete pMetadata; pMetadata = NULL;
Steve Block71f2cf12011-10-20 11:56:00 +0100338 ALOGV("GetMetadata - Exit");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900339 return metadata;
340}
341
aimitakeshid074e302010-07-29 10:12:27 +0900342static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
343 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100344 ALOGV("GetAllSupportInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900345 DrmSupportInfo* drmSupportInfoArray = NULL;
346
347 int length = 0;
348 getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
349
350 jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
351
352 jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
353
354 for (int i = 0; i < length; i++) {
355 DrmSupportInfo info = drmSupportInfoArray[i];
356
357 jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
358
359 jmethodID addMimeTypeId
360 = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
361 jmethodID addFileSuffixId
362 = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
363
364 env->CallVoidMethod(
365 drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
366 env->NewStringUTF(info.getDescription().string()));
367
368 DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
369 while (iterator.hasNext()) {
370 String8 value = iterator.next();
371 env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
372 }
373
374 DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
375 while (it.hasNext()) {
376 String8 value = it.next();
377 env->CallVoidMethod(
378 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
379 }
380
381 env->SetObjectArrayElement(array, i, drmSupportInfo);
382 }
383
384 delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
Steve Block71f2cf12011-10-20 11:56:00 +0100385 ALOGV("GetAllSupportInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900386 return array;
387}
388
389static void android_drm_DrmManagerClient_installDrmEngine(
390 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
Steve Block71f2cf12011-10-20 11:56:00 +0100391 ALOGV("installDrmEngine - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900392 //getDrmManagerClient(env, thiz)
393 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
Steve Block71f2cf12011-10-20 11:56:00 +0100394 ALOGV("installDrmEngine - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900395}
396
Takeshi Aimidc549d62010-09-20 23:40:41 +0900397static jint android_drm_DrmManagerClient_saveRights(
aimitakeshid074e302010-07-29 10:12:27 +0900398 JNIEnv* env, jobject thiz, jint uniqueId,
399 jobject drmRights, jstring rightsPath, jstring contentPath) {
Steve Block71f2cf12011-10-20 11:56:00 +0100400 ALOGV("saveRights - Enter");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900401 int result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900402 int dataLength = 0;
403 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
404
405 if (NULL != mData) {
406 DrmRights rights(DrmBuffer(mData, dataLength),
407 Utility::getStringValue(env, drmRights, "mMimeType"),
408 Utility::getStringValue(env, drmRights, "mAccountId"),
409 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900410 result = getDrmManagerClientImpl(env, thiz)
aimitakeshid074e302010-07-29 10:12:27 +0900411 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
412 Utility::getStringValue(env, contentPath));
413 }
414
415 delete mData; mData = NULL;
Steve Block71f2cf12011-10-20 11:56:00 +0100416 ALOGV("saveRights - Exit");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900417 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900418}
419
420static jboolean android_drm_DrmManagerClient_canHandle(
421 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block71f2cf12011-10-20 11:56:00 +0100422 ALOGV("canHandle - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900423 jboolean result
424 = getDrmManagerClientImpl(env, thiz)
425 ->canHandle(uniqueId, Utility::getStringValue(env, path),
426 Utility::getStringValue(env, mimeType));
Steve Block71f2cf12011-10-20 11:56:00 +0100427 ALOGV("canHandle - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900428 return result;
429}
430
431static jobject android_drm_DrmManagerClient_processDrmInfo(
432 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
Steve Block71f2cf12011-10-20 11:56:00 +0100433 ALOGV("processDrmInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900434 int dataLength = 0;
435 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType");
436 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
437 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
438
439 const DrmBuffer buffer(mData, dataLength);
440 DrmInfo drmInfo(mInfoType, buffer, mMimeType);
441
442 jclass clazz = env->FindClass("android/drm/DrmInfo");
443 jobject keyIterator
444 = env->CallObjectMethod(drmInfoObject,
445 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
446
447 jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
448
449 while (env->CallBooleanMethod(keyIterator, hasNextId)) {
450 jstring key = (jstring) env->CallObjectMethod(keyIterator,
451 env->GetMethodID(env->FindClass("java/util/Iterator"),
452 "next", "()Ljava/lang/Object;"));
453
454 jobject valueObject = env->CallObjectMethod(drmInfoObject,
455 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
456
457 jstring valString = NULL;
458 if (NULL != valueObject) {
459 valString = (jstring) env->CallObjectMethod(valueObject,
460 env->GetMethodID(env->FindClass("java/lang/Object"),
461 "toString", "()Ljava/lang/String;"));
462 }
463
464 String8 keyString = Utility::getStringValue(env, key);
465 String8 valueString = Utility::getStringValue(env, valString);
Steve Block71f2cf12011-10-20 11:56:00 +0100466 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900467
468 drmInfo.put(keyString, valueString);
469 }
470
471 DrmInfoStatus* pDrmInfoStatus
472 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
473
474 jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
475 jobject drmInfoStatus = NULL;
476
477 if (NULL != localRef && NULL != pDrmInfoStatus) {
478 int statusCode = pDrmInfoStatus->statusCode;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900479 int infoType = pDrmInfoStatus->infoType;
aimitakeshid074e302010-07-29 10:12:27 +0900480
481 jbyteArray dataArray = NULL;
482 if (NULL != pDrmInfoStatus->drmBuffer) {
483 int length = pDrmInfoStatus->drmBuffer->length;
484 dataArray = env->NewByteArray(length);
485 env->SetByteArrayRegion(
486 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
487
488 delete [] pDrmInfoStatus->drmBuffer->data;
489 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
490 }
491 jclass clazz = env->FindClass("android/drm/ProcessedData");
492 jmethodID constructorId
493 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
494 jobject processedData = env->NewObject(clazz, constructorId, dataArray,
495 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
496 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
497
498 constructorId
499 = env->GetMethodID(localRef,
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900500 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
aimitakeshid074e302010-07-29 10:12:27 +0900501
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900502 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
503 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900504 }
505
506 delete mData; mData = NULL;
507 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
508
Steve Block71f2cf12011-10-20 11:56:00 +0100509 ALOGV("processDrmInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900510 return drmInfoStatus;
511}
512
513static jobject android_drm_DrmManagerClient_acquireDrmInfo(
514 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
Steve Block71f2cf12011-10-20 11:56:00 +0100515 ALOGV("acquireDrmInfo Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900516 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType");
517 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
518
519 DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
520
521 jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
522 jobject keyIterator
523 = env->CallObjectMethod(drmInfoRequest,
524 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
525
526 jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
527
528 while (env->CallBooleanMethod(keyIterator, hasNextId)) {
529 jstring key
530 = (jstring) env->CallObjectMethod(keyIterator,
531 env->GetMethodID(env->FindClass("java/util/Iterator"),
532 "next", "()Ljava/lang/Object;"));
533
534 jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
535 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
536
537 String8 keyString = Utility::getStringValue(env, key);
538 String8 valueString = Utility::getStringValue(env, value);
Steve Block71f2cf12011-10-20 11:56:00 +0100539 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900540
541 drmInfoReq.put(keyString, valueString);
542 }
543
544 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
545
546 jobject drmInfoObject = NULL;
547
548 if (NULL != pDrmInfo) {
549 jclass localRef = env->FindClass("android/drm/DrmInfo");
550
551 if (NULL != localRef) {
552 int length = pDrmInfo->getData().length;
553
554 jbyteArray dataArray = env->NewByteArray(length);
555 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
556
557 drmInfoObject
558 = env->NewObject(localRef,
559 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
560 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
561
562 DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
563 jmethodID putMethodId
564 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
565
566 while (it.hasNext()) {
567 String8 key = it.next();
568 String8 value = pDrmInfo->get(key);
569
570 env->CallVoidMethod(drmInfoObject, putMethodId,
571 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
572 }
573 }
574 delete [] pDrmInfo->getData().data;
575 }
576
577 delete pDrmInfo; pDrmInfo = NULL;
578
Steve Block71f2cf12011-10-20 11:56:00 +0100579 ALOGV("acquireDrmInfo Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900580 return drmInfoObject;
581}
582
583static jint android_drm_DrmManagerClient_getDrmObjectType(
584 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block71f2cf12011-10-20 11:56:00 +0100585 ALOGV("getDrmObjectType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900586 int drmObjectType
587 = getDrmManagerClientImpl(env, thiz)
588 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
589 Utility::getStringValue(env, mimeType));
Steve Block71f2cf12011-10-20 11:56:00 +0100590 ALOGV("getDrmObjectType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900591 return drmObjectType;
592}
593
594static jstring android_drm_DrmManagerClient_getOriginalMimeType(
595 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block71f2cf12011-10-20 11:56:00 +0100596 ALOGV("getOriginalMimeType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900597 String8 mimeType
598 = getDrmManagerClientImpl(env, thiz)
599 ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
Steve Block71f2cf12011-10-20 11:56:00 +0100600 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900601 return env->NewStringUTF(mimeType.string());
602}
603
604static jint android_drm_DrmManagerClient_checkRightsStatus(
605 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
Steve Block71f2cf12011-10-20 11:56:00 +0100606 ALOGV("getOriginalMimeType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900607 int rightsStatus
608 = getDrmManagerClientImpl(env, thiz)
609 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
Steve Block71f2cf12011-10-20 11:56:00 +0100610 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900611 return rightsStatus;
612}
613
Takeshi Aimidc549d62010-09-20 23:40:41 +0900614static jint android_drm_DrmManagerClient_removeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900615 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block71f2cf12011-10-20 11:56:00 +0100616 ALOGV("removeRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900617 return getDrmManagerClientImpl(env, thiz)
618 ->removeRights(uniqueId, Utility::getStringValue(env, path));
aimitakeshid074e302010-07-29 10:12:27 +0900619}
620
Takeshi Aimidc549d62010-09-20 23:40:41 +0900621static jint android_drm_DrmManagerClient_removeAllRights(
aimitakeshid074e302010-07-29 10:12:27 +0900622 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block71f2cf12011-10-20 11:56:00 +0100623 ALOGV("removeAllRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900624 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900625}
626
627static jint android_drm_DrmManagerClient_openConvertSession(
628 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
Steve Block71f2cf12011-10-20 11:56:00 +0100629 ALOGV("openConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900630 int convertId
631 = getDrmManagerClientImpl(env, thiz)
632 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
Steve Block71f2cf12011-10-20 11:56:00 +0100633 ALOGV("openConvertSession Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900634 return convertId;
635}
636
637static jobject android_drm_DrmManagerClient_convertData(
638 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
Steve Block71f2cf12011-10-20 11:56:00 +0100639 ALOGV("convertData Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900640
641 int dataLength = 0;
642 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
643 const DrmBuffer buffer(mData, dataLength);
644
645 DrmConvertedStatus* pDrmConvertedStatus
646 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
647
648 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
649
650 jobject drmConvertedStatus = NULL;
651
652 if (NULL != localRef && NULL != pDrmConvertedStatus) {
653 int statusCode = pDrmConvertedStatus->statusCode;
654
655 jbyteArray dataArray = NULL;
656 if (NULL != pDrmConvertedStatus->convertedData) {
657 int length = pDrmConvertedStatus->convertedData->length;
658 dataArray = env->NewByteArray(length);
659 env->SetByteArrayRegion(dataArray, 0, length,
660 (jbyte*) pDrmConvertedStatus->convertedData->data);
661
662 delete [] pDrmConvertedStatus->convertedData->data;
663 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
664 }
665 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
666 drmConvertedStatus
667 = env->NewObject(localRef, constructorId,
668 statusCode, dataArray, pDrmConvertedStatus->offset);
669 }
670
671 delete mData; mData = NULL;
672 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
673
Steve Block71f2cf12011-10-20 11:56:00 +0100674 ALOGV("convertData - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900675 return drmConvertedStatus;
676}
677
678static jobject android_drm_DrmManagerClient_closeConvertSession(
679 JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
680
Steve Block71f2cf12011-10-20 11:56:00 +0100681 ALOGV("closeConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900682
683 DrmConvertedStatus* pDrmConvertedStatus
684 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
685
686 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
687
688 jobject drmConvertedStatus = NULL;
689
690 if (NULL != localRef && NULL != pDrmConvertedStatus) {
691 int statusCode = pDrmConvertedStatus->statusCode;
692
693 jbyteArray dataArray = NULL;
694 if (NULL != pDrmConvertedStatus->convertedData) {
695 int length = pDrmConvertedStatus->convertedData->length;
696 dataArray = env->NewByteArray(length);
697 env->SetByteArrayRegion(
698 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
699
700 delete [] pDrmConvertedStatus->convertedData->data;
701 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
702 }
703 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
704 drmConvertedStatus
705 = env->NewObject(localRef, constructorId,
706 statusCode, dataArray, pDrmConvertedStatus->offset);
707 }
708
709 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
710
Steve Block71f2cf12011-10-20 11:56:00 +0100711 ALOGV("closeConvertSession - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900712 return drmConvertedStatus;
713}
714
715static JNINativeMethod nativeMethods[] = {
716
Gloria Wanga17d4542011-07-21 15:10:22 -0700717 {"_initialize", "(Ljava/lang/Object;)I",
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900718 (void*)android_drm_DrmManagerClient_initialize},
aimitakeshid074e302010-07-29 10:12:27 +0900719
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900720 {"_finalize", "(I)V",
721 (void*)android_drm_DrmManagerClient_finalize},
aimitakeshid074e302010-07-29 10:12:27 +0900722
723 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
724 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
725
Takeshi Aimidc9186562010-11-16 13:56:11 +0900726 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
727 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
728
aimitakeshid074e302010-07-29 10:12:27 +0900729 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
730 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
731
732 {"_installDrmEngine", "(ILjava/lang/String;)V",
733 (void*)android_drm_DrmManagerClient_installDrmEngine},
734
735 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
736 (void*)android_drm_DrmManagerClient_canHandle},
737
738 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
739 (void*)android_drm_DrmManagerClient_processDrmInfo},
740
741 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
742 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
743
Takeshi Aimidc549d62010-09-20 23:40:41 +0900744 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900745 (void*)android_drm_DrmManagerClient_saveRights},
746
747 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
748 (void*)android_drm_DrmManagerClient_getDrmObjectType},
749
750 {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
751 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
752
753 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
754 (void*)android_drm_DrmManagerClient_checkRightsStatus},
755
Takeshi Aimidc549d62010-09-20 23:40:41 +0900756 {"_removeRights", "(ILjava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900757 (void*)android_drm_DrmManagerClient_removeRights},
758
Takeshi Aimidc549d62010-09-20 23:40:41 +0900759 {"_removeAllRights", "(I)I",
aimitakeshid074e302010-07-29 10:12:27 +0900760 (void*)android_drm_DrmManagerClient_removeAllRights},
761
762 {"_openConvertSession", "(ILjava/lang/String;)I",
763 (void*)android_drm_DrmManagerClient_openConvertSession},
764
765 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
766 (void*)android_drm_DrmManagerClient_convertData},
767
768 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
769 (void*)android_drm_DrmManagerClient_closeConvertSession},
770};
771
772static int registerNativeMethods(JNIEnv* env) {
773 int result = -1;
774
775 /* look up the class */
776 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
777
778 if (NULL != clazz) {
779 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
780 / sizeof(nativeMethods[0])) == JNI_OK) {
781 result = 0;
782 }
783 }
784 return result;
785}
786
787jint JNI_OnLoad(JavaVM* vm, void* reserved) {
788 JNIEnv* env = NULL;
789 jint result = -1;
790
791 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
792 if (NULL != env && registerNativeMethods(env) == 0) {
793 result = JNI_VERSION_1_4;
794 }
795 }
796 return result;
797}
798