blob: cf58177010f3b49954c8f050ada17bb22c93fa5e [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 Block06ade6a2011-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) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000172 ALOGE("Can't find android/drm/DrmManagerClient");
aimitakeshid074e302010-07-29 10:12:27 +0900173 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 Block06ade6a2011-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(
Kei Takahashi6225df02012-01-31 13:18:45 +0900228 JNIEnv* env, jobject thiz) {
Steve Block06ade6a2011-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
aimitakeshid074e302010-07-29 10:12:27 +0900235 setDrmManagerClientImpl(env, thiz, drmManager);
Steve Block06ade6a2011-10-20 11:56:00 +0100236 ALOGV("initialize - Exit");
Gloria Wanga17d4542011-07-21 15:10:22 -0700237 return uniqueId;
aimitakeshid074e302010-07-29 10:12:27 +0900238}
239
Kei Takahashi6225df02012-01-31 13:18:45 +0900240static void android_drm_DrmManagerClient_setListeners(
241 JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
242 ALOGV("setListeners - Enter");
243
244 // Set the listener to DrmManager
245 sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
246 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
247
248 ALOGV("setListeners - Exit");
249}
250
251static void android_drm_DrmManagerClient_release(
252 JNIEnv* env, jobject thiz, jint uniqueId) {
253 ALOGV("release - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900254 DrmManagerClientImpl::remove(uniqueId);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900255 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
aimitakeshid074e302010-07-29 10:12:27 +0900256
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900257 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
258 if (oldClient != NULL) {
259 oldClient->setOnInfoListener(uniqueId, NULL);
260 oldClient->removeClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900261 }
Kei Takahashi6225df02012-01-31 13:18:45 +0900262 ALOGV("release - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900263}
264
265static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
266 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
Steve Block06ade6a2011-10-20 11:56:00 +0100267 ALOGV("GetConstraints - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900268
269 const String8 pathString = Utility::getStringValue(env, jpath);
270 DrmConstraints* pConstraints
271 = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
272
273 jclass localRef = env->FindClass("android/content/ContentValues");
274 jobject constraints = NULL;
275
276 if (NULL != localRef && NULL != pConstraints) {
277 // Get the constructor id
278 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
279 // create the java DrmConstraints object
280 constraints = env->NewObject(localRef, constructorId);
281
282 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
283
284 while (keyIt.hasNext()) {
285 String8 key = keyIt.next();
286
287 // insert the entry<constraintKey, constraintValue> to newly created java object
288 if (DrmConstraints::EXTENDED_METADATA == key) {
289 const char* value = pConstraints->getAsByteArray(&key);
290 if (NULL != value) {
291 jbyteArray dataArray = env->NewByteArray(strlen(value));
292 env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
293 env->CallVoidMethod(
294 constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
295 env->NewStringUTF(key.string()), dataArray);
296 }
297 } else {
298 String8 value = pConstraints->get(key);
299 env->CallVoidMethod(
300 constraints,
301 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
302 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
303 }
304 }
305 }
306
307 delete pConstraints; pConstraints = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100308 ALOGV("GetConstraints - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900309 return constraints;
310}
311
Takeshi Aimidc9186562010-11-16 13:56:11 +0900312static jobject android_drm_DrmManagerClient_getMetadataFromContent(
313 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100314 ALOGV("GetMetadata - Enter");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900315 const String8 pathString = Utility::getStringValue(env, jpath);
316 DrmMetadata* pMetadata =
317 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
318
319 jobject metadata = NULL;
320
321 jclass localRef = NULL;
322 localRef = env->FindClass("android/content/ContentValues");
323 if (NULL != localRef && NULL != pMetadata) {
324 // Get the constructor id
325 jmethodID constructorId = NULL;
326 constructorId = env->GetMethodID(localRef, "<init>", "()V");
327 if (NULL != constructorId) {
328 // create the java DrmMetadata object
329 metadata = env->NewObject(localRef, constructorId);
330 if (NULL != metadata) {
331 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
332 while (keyIt.hasNext()) {
333 String8 key = keyIt.next();
334 // insert the entry<constraintKey, constraintValue>
335 // to newly created java object
336 String8 value = pMetadata->get(key);
337 env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
338 "(Ljava/lang/String;Ljava/lang/String;)V"),
339 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
340 }
341 }
342 }
343 }
344 delete pMetadata; pMetadata = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100345 ALOGV("GetMetadata - Exit");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900346 return metadata;
347}
348
aimitakeshid074e302010-07-29 10:12:27 +0900349static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
350 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100351 ALOGV("GetAllSupportInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900352 DrmSupportInfo* drmSupportInfoArray = NULL;
353
354 int length = 0;
355 getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
356
357 jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
358
359 jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
360
361 for (int i = 0; i < length; i++) {
362 DrmSupportInfo info = drmSupportInfoArray[i];
363
364 jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
365
366 jmethodID addMimeTypeId
367 = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
368 jmethodID addFileSuffixId
369 = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
370
371 env->CallVoidMethod(
372 drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
373 env->NewStringUTF(info.getDescription().string()));
374
375 DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
376 while (iterator.hasNext()) {
377 String8 value = iterator.next();
378 env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
379 }
380
381 DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
382 while (it.hasNext()) {
383 String8 value = it.next();
384 env->CallVoidMethod(
385 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
386 }
387
388 env->SetObjectArrayElement(array, i, drmSupportInfo);
389 }
390
391 delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100392 ALOGV("GetAllSupportInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900393 return array;
394}
395
396static void android_drm_DrmManagerClient_installDrmEngine(
397 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100398 ALOGV("installDrmEngine - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900399 //getDrmManagerClient(env, thiz)
400 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
Steve Block06ade6a2011-10-20 11:56:00 +0100401 ALOGV("installDrmEngine - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900402}
403
Takeshi Aimidc549d62010-09-20 23:40:41 +0900404static jint android_drm_DrmManagerClient_saveRights(
aimitakeshid074e302010-07-29 10:12:27 +0900405 JNIEnv* env, jobject thiz, jint uniqueId,
406 jobject drmRights, jstring rightsPath, jstring contentPath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100407 ALOGV("saveRights - Enter");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900408 int result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900409 int dataLength = 0;
410 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
411
412 if (NULL != mData) {
413 DrmRights rights(DrmBuffer(mData, dataLength),
414 Utility::getStringValue(env, drmRights, "mMimeType"),
415 Utility::getStringValue(env, drmRights, "mAccountId"),
416 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900417 result = getDrmManagerClientImpl(env, thiz)
aimitakeshid074e302010-07-29 10:12:27 +0900418 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
419 Utility::getStringValue(env, contentPath));
420 }
421
422 delete mData; mData = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100423 ALOGV("saveRights - Exit");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900424 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900425}
426
427static jboolean android_drm_DrmManagerClient_canHandle(
428 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100429 ALOGV("canHandle - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900430 jboolean result
431 = getDrmManagerClientImpl(env, thiz)
432 ->canHandle(uniqueId, Utility::getStringValue(env, path),
433 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100434 ALOGV("canHandle - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900435 return result;
436}
437
438static jobject android_drm_DrmManagerClient_processDrmInfo(
439 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
Steve Block06ade6a2011-10-20 11:56:00 +0100440 ALOGV("processDrmInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900441 int dataLength = 0;
442 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType");
443 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
444 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
445
446 const DrmBuffer buffer(mData, dataLength);
447 DrmInfo drmInfo(mInfoType, buffer, mMimeType);
448
449 jclass clazz = env->FindClass("android/drm/DrmInfo");
450 jobject keyIterator
451 = env->CallObjectMethod(drmInfoObject,
452 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
453
454 jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
455
456 while (env->CallBooleanMethod(keyIterator, hasNextId)) {
457 jstring key = (jstring) env->CallObjectMethod(keyIterator,
458 env->GetMethodID(env->FindClass("java/util/Iterator"),
459 "next", "()Ljava/lang/Object;"));
460
461 jobject valueObject = env->CallObjectMethod(drmInfoObject,
462 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
463
464 jstring valString = NULL;
465 if (NULL != valueObject) {
466 valString = (jstring) env->CallObjectMethod(valueObject,
467 env->GetMethodID(env->FindClass("java/lang/Object"),
468 "toString", "()Ljava/lang/String;"));
469 }
470
471 String8 keyString = Utility::getStringValue(env, key);
472 String8 valueString = Utility::getStringValue(env, valString);
Steve Block06ade6a2011-10-20 11:56:00 +0100473 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900474
475 drmInfo.put(keyString, valueString);
476 }
477
478 DrmInfoStatus* pDrmInfoStatus
479 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
480
481 jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
482 jobject drmInfoStatus = NULL;
483
484 if (NULL != localRef && NULL != pDrmInfoStatus) {
485 int statusCode = pDrmInfoStatus->statusCode;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900486 int infoType = pDrmInfoStatus->infoType;
aimitakeshid074e302010-07-29 10:12:27 +0900487
488 jbyteArray dataArray = NULL;
489 if (NULL != pDrmInfoStatus->drmBuffer) {
490 int length = pDrmInfoStatus->drmBuffer->length;
491 dataArray = env->NewByteArray(length);
492 env->SetByteArrayRegion(
493 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
494
495 delete [] pDrmInfoStatus->drmBuffer->data;
496 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
497 }
498 jclass clazz = env->FindClass("android/drm/ProcessedData");
499 jmethodID constructorId
500 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
501 jobject processedData = env->NewObject(clazz, constructorId, dataArray,
502 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
503 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
504
505 constructorId
506 = env->GetMethodID(localRef,
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900507 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
aimitakeshid074e302010-07-29 10:12:27 +0900508
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900509 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
510 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900511 }
512
513 delete mData; mData = NULL;
514 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
515
Steve Block06ade6a2011-10-20 11:56:00 +0100516 ALOGV("processDrmInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900517 return drmInfoStatus;
518}
519
520static jobject android_drm_DrmManagerClient_acquireDrmInfo(
521 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
Steve Block06ade6a2011-10-20 11:56:00 +0100522 ALOGV("acquireDrmInfo Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900523 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType");
524 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
525
526 DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
527
528 jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
529 jobject keyIterator
530 = env->CallObjectMethod(drmInfoRequest,
531 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
532
533 jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
534
535 while (env->CallBooleanMethod(keyIterator, hasNextId)) {
536 jstring key
537 = (jstring) env->CallObjectMethod(keyIterator,
538 env->GetMethodID(env->FindClass("java/util/Iterator"),
539 "next", "()Ljava/lang/Object;"));
540
541 jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
542 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
543
544 String8 keyString = Utility::getStringValue(env, key);
545 String8 valueString = Utility::getStringValue(env, value);
Steve Block06ade6a2011-10-20 11:56:00 +0100546 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900547
548 drmInfoReq.put(keyString, valueString);
549 }
550
551 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
552
553 jobject drmInfoObject = NULL;
554
555 if (NULL != pDrmInfo) {
556 jclass localRef = env->FindClass("android/drm/DrmInfo");
557
558 if (NULL != localRef) {
559 int length = pDrmInfo->getData().length;
560
561 jbyteArray dataArray = env->NewByteArray(length);
562 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
563
564 drmInfoObject
565 = env->NewObject(localRef,
566 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
567 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
568
569 DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
570 jmethodID putMethodId
571 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
572
573 while (it.hasNext()) {
574 String8 key = it.next();
575 String8 value = pDrmInfo->get(key);
576
577 env->CallVoidMethod(drmInfoObject, putMethodId,
578 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
579 }
580 }
581 delete [] pDrmInfo->getData().data;
582 }
583
584 delete pDrmInfo; pDrmInfo = NULL;
585
Steve Block06ade6a2011-10-20 11:56:00 +0100586 ALOGV("acquireDrmInfo Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900587 return drmInfoObject;
588}
589
590static jint android_drm_DrmManagerClient_getDrmObjectType(
591 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100592 ALOGV("getDrmObjectType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900593 int drmObjectType
594 = getDrmManagerClientImpl(env, thiz)
595 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
596 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100597 ALOGV("getDrmObjectType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900598 return drmObjectType;
599}
600
601static jstring android_drm_DrmManagerClient_getOriginalMimeType(
602 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100603 ALOGV("getOriginalMimeType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900604 String8 mimeType
605 = getDrmManagerClientImpl(env, thiz)
606 ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
Steve Block06ade6a2011-10-20 11:56:00 +0100607 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900608 return env->NewStringUTF(mimeType.string());
609}
610
611static jint android_drm_DrmManagerClient_checkRightsStatus(
612 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
Steve Block06ade6a2011-10-20 11:56:00 +0100613 ALOGV("getOriginalMimeType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900614 int rightsStatus
615 = getDrmManagerClientImpl(env, thiz)
616 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
Steve Block06ade6a2011-10-20 11:56:00 +0100617 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900618 return rightsStatus;
619}
620
Takeshi Aimidc549d62010-09-20 23:40:41 +0900621static jint android_drm_DrmManagerClient_removeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900622 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100623 ALOGV("removeRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900624 return getDrmManagerClientImpl(env, thiz)
625 ->removeRights(uniqueId, Utility::getStringValue(env, path));
aimitakeshid074e302010-07-29 10:12:27 +0900626}
627
Takeshi Aimidc549d62010-09-20 23:40:41 +0900628static jint android_drm_DrmManagerClient_removeAllRights(
aimitakeshid074e302010-07-29 10:12:27 +0900629 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100630 ALOGV("removeAllRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900631 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900632}
633
634static jint android_drm_DrmManagerClient_openConvertSession(
635 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100636 ALOGV("openConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900637 int convertId
638 = getDrmManagerClientImpl(env, thiz)
639 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100640 ALOGV("openConvertSession Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900641 return convertId;
642}
643
644static jobject android_drm_DrmManagerClient_convertData(
645 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
Steve Block06ade6a2011-10-20 11:56:00 +0100646 ALOGV("convertData Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900647
648 int dataLength = 0;
649 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
650 const DrmBuffer buffer(mData, dataLength);
651
652 DrmConvertedStatus* pDrmConvertedStatus
653 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
654
655 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
656
657 jobject drmConvertedStatus = NULL;
658
659 if (NULL != localRef && NULL != pDrmConvertedStatus) {
660 int statusCode = pDrmConvertedStatus->statusCode;
661
662 jbyteArray dataArray = NULL;
663 if (NULL != pDrmConvertedStatus->convertedData) {
664 int length = pDrmConvertedStatus->convertedData->length;
665 dataArray = env->NewByteArray(length);
666 env->SetByteArrayRegion(dataArray, 0, length,
667 (jbyte*) pDrmConvertedStatus->convertedData->data);
668
669 delete [] pDrmConvertedStatus->convertedData->data;
670 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
671 }
672 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
673 drmConvertedStatus
674 = env->NewObject(localRef, constructorId,
675 statusCode, dataArray, pDrmConvertedStatus->offset);
676 }
677
678 delete mData; mData = NULL;
679 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
680
Steve Block06ade6a2011-10-20 11:56:00 +0100681 ALOGV("convertData - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900682 return drmConvertedStatus;
683}
684
685static jobject android_drm_DrmManagerClient_closeConvertSession(
686 JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
687
Steve Block06ade6a2011-10-20 11:56:00 +0100688 ALOGV("closeConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900689
690 DrmConvertedStatus* pDrmConvertedStatus
691 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
692
693 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
694
695 jobject drmConvertedStatus = NULL;
696
697 if (NULL != localRef && NULL != pDrmConvertedStatus) {
698 int statusCode = pDrmConvertedStatus->statusCode;
699
700 jbyteArray dataArray = NULL;
701 if (NULL != pDrmConvertedStatus->convertedData) {
702 int length = pDrmConvertedStatus->convertedData->length;
703 dataArray = env->NewByteArray(length);
704 env->SetByteArrayRegion(
705 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
706
707 delete [] pDrmConvertedStatus->convertedData->data;
708 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
709 }
710 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
711 drmConvertedStatus
712 = env->NewObject(localRef, constructorId,
713 statusCode, dataArray, pDrmConvertedStatus->offset);
714 }
715
716 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
717
Steve Block06ade6a2011-10-20 11:56:00 +0100718 ALOGV("closeConvertSession - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900719 return drmConvertedStatus;
720}
721
722static JNINativeMethod nativeMethods[] = {
723
Kei Takahashi6225df02012-01-31 13:18:45 +0900724 {"_initialize", "()I",
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900725 (void*)android_drm_DrmManagerClient_initialize},
aimitakeshid074e302010-07-29 10:12:27 +0900726
Kei Takahashi6225df02012-01-31 13:18:45 +0900727 {"_setListeners", "(ILjava/lang/Object;)V",
728 (void*)android_drm_DrmManagerClient_setListeners},
729
730 {"_release", "(I)V",
731 (void*)android_drm_DrmManagerClient_release},
aimitakeshid074e302010-07-29 10:12:27 +0900732
733 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
734 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
735
Takeshi Aimidc9186562010-11-16 13:56:11 +0900736 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
737 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
738
aimitakeshid074e302010-07-29 10:12:27 +0900739 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
740 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
741
742 {"_installDrmEngine", "(ILjava/lang/String;)V",
743 (void*)android_drm_DrmManagerClient_installDrmEngine},
744
745 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
746 (void*)android_drm_DrmManagerClient_canHandle},
747
748 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
749 (void*)android_drm_DrmManagerClient_processDrmInfo},
750
751 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
752 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
753
Takeshi Aimidc549d62010-09-20 23:40:41 +0900754 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900755 (void*)android_drm_DrmManagerClient_saveRights},
756
757 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
758 (void*)android_drm_DrmManagerClient_getDrmObjectType},
759
760 {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
761 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
762
763 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
764 (void*)android_drm_DrmManagerClient_checkRightsStatus},
765
Takeshi Aimidc549d62010-09-20 23:40:41 +0900766 {"_removeRights", "(ILjava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900767 (void*)android_drm_DrmManagerClient_removeRights},
768
Takeshi Aimidc549d62010-09-20 23:40:41 +0900769 {"_removeAllRights", "(I)I",
aimitakeshid074e302010-07-29 10:12:27 +0900770 (void*)android_drm_DrmManagerClient_removeAllRights},
771
772 {"_openConvertSession", "(ILjava/lang/String;)I",
773 (void*)android_drm_DrmManagerClient_openConvertSession},
774
775 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
776 (void*)android_drm_DrmManagerClient_convertData},
777
778 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
779 (void*)android_drm_DrmManagerClient_closeConvertSession},
780};
781
782static int registerNativeMethods(JNIEnv* env) {
783 int result = -1;
784
785 /* look up the class */
786 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
787
788 if (NULL != clazz) {
789 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
790 / sizeof(nativeMethods[0])) == JNI_OK) {
791 result = 0;
792 }
793 }
794 return result;
795}
796
797jint JNI_OnLoad(JavaVM* vm, void* reserved) {
798 JNIEnv* env = NULL;
799 jint result = -1;
800
801 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
802 if (NULL != env && registerNativeMethods(env) == 0) {
803 result = JNI_VERSION_1_4;
804 }
805 }
806 return result;
807}
808