blob: baddf62260189145161d35c787c8aee5b3d9807b [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());
aimitakeshid074e302010-07-29 10:12:27 +0900172
173 env->CallStaticVoidMethod(
174 mClass,
175 env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
176 mObject, uniqueId, type, message);
177}
178
179static Mutex sLock;
180
181static sp<DrmManagerClientImpl> setDrmManagerClientImpl(
182 JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
183 Mutex::Autolock l(sLock);
184 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
185 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
186
187 sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
188 if (client.get()) {
189 client->incStrong(thiz);
190 }
191 if (old != 0) {
192 old->decStrong(thiz);
193 }
194 env->SetIntField(thiz, fieldId, (int)client.get());
195 return old;
196}
197
198static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
199 Mutex::Autolock l(sLock);
200 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
201 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
202
203 DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
204 return sp<DrmManagerClientImpl>(client);
205}
206
Gloria Wanga17d4542011-07-21 15:10:22 -0700207static jint android_drm_DrmManagerClient_initialize(
Kei Takahashi6225df02012-01-31 13:18:45 +0900208 JNIEnv* env, jobject thiz) {
Steve Block06ade6a2011-10-20 11:56:00 +0100209 ALOGV("initialize - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900210
Gloria Wanga17d4542011-07-21 15:10:22 -0700211 int uniqueId = 0;
212 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900213 drmManager->addClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900214
aimitakeshid074e302010-07-29 10:12:27 +0900215 setDrmManagerClientImpl(env, thiz, drmManager);
Steve Block06ade6a2011-10-20 11:56:00 +0100216 ALOGV("initialize - Exit");
Gloria Wanga17d4542011-07-21 15:10:22 -0700217 return uniqueId;
aimitakeshid074e302010-07-29 10:12:27 +0900218}
219
Kei Takahashi6225df02012-01-31 13:18:45 +0900220static void android_drm_DrmManagerClient_setListeners(
221 JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
222 ALOGV("setListeners - Enter");
223
224 // Set the listener to DrmManager
225 sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
226 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
227
228 ALOGV("setListeners - Exit");
229}
230
231static void android_drm_DrmManagerClient_release(
232 JNIEnv* env, jobject thiz, jint uniqueId) {
233 ALOGV("release - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900234 DrmManagerClientImpl::remove(uniqueId);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900235 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
aimitakeshid074e302010-07-29 10:12:27 +0900236
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900237 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
238 if (oldClient != NULL) {
239 oldClient->setOnInfoListener(uniqueId, NULL);
240 oldClient->removeClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900241 }
Kei Takahashi6225df02012-01-31 13:18:45 +0900242 ALOGV("release - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900243}
244
245static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
246 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
Steve Block06ade6a2011-10-20 11:56:00 +0100247 ALOGV("GetConstraints - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900248
249 const String8 pathString = Utility::getStringValue(env, jpath);
250 DrmConstraints* pConstraints
251 = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
252
253 jclass localRef = env->FindClass("android/content/ContentValues");
Henrik B Andersson057b0862012-02-10 13:17:40 +0100254 jmethodID ContentValues_putByteArray =
255 env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
256 jmethodID ContentValues_putString =
257 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
258 jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
aimitakeshid074e302010-07-29 10:12:27 +0900259 jobject constraints = NULL;
260
261 if (NULL != localRef && NULL != pConstraints) {
aimitakeshid074e302010-07-29 10:12:27 +0900262 // create the java DrmConstraints object
Henrik B Andersson057b0862012-02-10 13:17:40 +0100263 constraints = env->NewObject(localRef, ContentValues_constructor);
aimitakeshid074e302010-07-29 10:12:27 +0900264
265 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
aimitakeshid074e302010-07-29 10:12:27 +0900266 while (keyIt.hasNext()) {
267 String8 key = keyIt.next();
268
269 // insert the entry<constraintKey, constraintValue> to newly created java object
270 if (DrmConstraints::EXTENDED_METADATA == key) {
271 const char* value = pConstraints->getAsByteArray(&key);
272 if (NULL != value) {
Henrik B Andersson057b0862012-02-10 13:17:40 +0100273 ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
274 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
275 env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
276 env->CallVoidMethod(constraints, ContentValues_putByteArray,
277 keyString.get(), dataArray.get());
aimitakeshid074e302010-07-29 10:12:27 +0900278 }
279 } else {
280 String8 value = pConstraints->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100281 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
282 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
283 env->CallVoidMethod(constraints, ContentValues_putString,
284 keyString.get(), valueString.get());
aimitakeshid074e302010-07-29 10:12:27 +0900285 }
286 }
287 }
288
289 delete pConstraints; pConstraints = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100290 ALOGV("GetConstraints - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900291 return constraints;
292}
293
Takeshi Aimidc9186562010-11-16 13:56:11 +0900294static jobject android_drm_DrmManagerClient_getMetadataFromContent(
295 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100296 ALOGV("GetMetadata - Enter");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900297 const String8 pathString = Utility::getStringValue(env, jpath);
298 DrmMetadata* pMetadata =
299 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
300
301 jobject metadata = NULL;
302
Henrik B Andersson057b0862012-02-10 13:17:40 +0100303 jclass localRef = env->FindClass("android/content/ContentValues");
304 jmethodID ContentValues_putString =
305 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
306
Takeshi Aimidc9186562010-11-16 13:56:11 +0900307 if (NULL != localRef && NULL != pMetadata) {
308 // Get the constructor id
309 jmethodID constructorId = NULL;
310 constructorId = env->GetMethodID(localRef, "<init>", "()V");
311 if (NULL != constructorId) {
312 // create the java DrmMetadata object
313 metadata = env->NewObject(localRef, constructorId);
314 if (NULL != metadata) {
315 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
316 while (keyIt.hasNext()) {
317 String8 key = keyIt.next();
318 // insert the entry<constraintKey, constraintValue>
319 // to newly created java object
320 String8 value = pMetadata->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100321 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
322 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
323 env->CallVoidMethod(metadata, ContentValues_putString,
324 keyString.get(), valueString.get());
Takeshi Aimidc9186562010-11-16 13:56:11 +0900325 }
326 }
327 }
328 }
329 delete pMetadata; pMetadata = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100330 ALOGV("GetMetadata - Exit");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900331 return metadata;
332}
333
aimitakeshid074e302010-07-29 10:12:27 +0900334static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
335 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100336 ALOGV("GetAllSupportInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900337 DrmSupportInfo* drmSupportInfoArray = NULL;
338
339 int length = 0;
340 getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
341
342 jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
343
344 jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
345
346 for (int i = 0; i < length; i++) {
347 DrmSupportInfo info = drmSupportInfoArray[i];
348
349 jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
350
351 jmethodID addMimeTypeId
352 = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
353 jmethodID addFileSuffixId
354 = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
355
356 env->CallVoidMethod(
357 drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
358 env->NewStringUTF(info.getDescription().string()));
359
360 DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
361 while (iterator.hasNext()) {
362 String8 value = iterator.next();
363 env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
364 }
365
366 DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
367 while (it.hasNext()) {
368 String8 value = it.next();
369 env->CallVoidMethod(
370 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
371 }
372
373 env->SetObjectArrayElement(array, i, drmSupportInfo);
374 }
375
376 delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100377 ALOGV("GetAllSupportInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900378 return array;
379}
380
381static void android_drm_DrmManagerClient_installDrmEngine(
382 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100383 ALOGV("installDrmEngine - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900384 //getDrmManagerClient(env, thiz)
385 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
Steve Block06ade6a2011-10-20 11:56:00 +0100386 ALOGV("installDrmEngine - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900387}
388
Takeshi Aimidc549d62010-09-20 23:40:41 +0900389static jint android_drm_DrmManagerClient_saveRights(
aimitakeshid074e302010-07-29 10:12:27 +0900390 JNIEnv* env, jobject thiz, jint uniqueId,
391 jobject drmRights, jstring rightsPath, jstring contentPath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100392 ALOGV("saveRights - Enter");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900393 int result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900394 int dataLength = 0;
395 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
396
397 if (NULL != mData) {
398 DrmRights rights(DrmBuffer(mData, dataLength),
399 Utility::getStringValue(env, drmRights, "mMimeType"),
400 Utility::getStringValue(env, drmRights, "mAccountId"),
401 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900402 result = getDrmManagerClientImpl(env, thiz)
aimitakeshid074e302010-07-29 10:12:27 +0900403 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
404 Utility::getStringValue(env, contentPath));
405 }
406
James Dongf16a2722012-03-02 16:49:35 -0800407 delete[] mData; mData = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100408 ALOGV("saveRights - Exit");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900409 return result;
aimitakeshid074e302010-07-29 10:12:27 +0900410}
411
412static jboolean android_drm_DrmManagerClient_canHandle(
413 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100414 ALOGV("canHandle - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900415 jboolean result
416 = getDrmManagerClientImpl(env, thiz)
417 ->canHandle(uniqueId, Utility::getStringValue(env, path),
418 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100419 ALOGV("canHandle - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900420 return result;
421}
422
423static jobject android_drm_DrmManagerClient_processDrmInfo(
424 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
Steve Block06ade6a2011-10-20 11:56:00 +0100425 ALOGV("processDrmInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900426 int dataLength = 0;
427 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType");
428 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
429 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
430
431 const DrmBuffer buffer(mData, dataLength);
432 DrmInfo drmInfo(mInfoType, buffer, mMimeType);
433
434 jclass clazz = env->FindClass("android/drm/DrmInfo");
Henrik B Andersson057b0862012-02-10 13:17:40 +0100435 jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900436 jobject keyIterator
437 = env->CallObjectMethod(drmInfoObject,
438 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
439
Henrik B Andersson057b0862012-02-10 13:17:40 +0100440 jclass Iterator_class = env->FindClass("java/util/Iterator");
441 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
442 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900443
Henrik B Andersson057b0862012-02-10 13:17:40 +0100444 jclass Object_class = env->FindClass("java/lang/Object");
445 jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
aimitakeshid074e302010-07-29 10:12:27 +0900446
Henrik B Andersson057b0862012-02-10 13:17:40 +0100447 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
448 ScopedLocalRef<jstring> key(env,
449 (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
450 ScopedLocalRef<jobject> valueObject(env,
451 env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
452 ScopedLocalRef<jstring> valString(env, NULL);
453 if (NULL != valueObject.get()) {
454 valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
aimitakeshid074e302010-07-29 10:12:27 +0900455 }
456
Henrik B Andersson057b0862012-02-10 13:17:40 +0100457 String8 keyString = Utility::getStringValue(env, key.get());
458 String8 valueString = Utility::getStringValue(env, valString.get());
Steve Block06ade6a2011-10-20 11:56:00 +0100459 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900460
461 drmInfo.put(keyString, valueString);
462 }
463
464 DrmInfoStatus* pDrmInfoStatus
465 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
466
467 jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
468 jobject drmInfoStatus = NULL;
469
470 if (NULL != localRef && NULL != pDrmInfoStatus) {
471 int statusCode = pDrmInfoStatus->statusCode;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900472 int infoType = pDrmInfoStatus->infoType;
aimitakeshid074e302010-07-29 10:12:27 +0900473
474 jbyteArray dataArray = NULL;
475 if (NULL != pDrmInfoStatus->drmBuffer) {
476 int length = pDrmInfoStatus->drmBuffer->length;
477 dataArray = env->NewByteArray(length);
478 env->SetByteArrayRegion(
479 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
480
481 delete [] pDrmInfoStatus->drmBuffer->data;
482 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
483 }
484 jclass clazz = env->FindClass("android/drm/ProcessedData");
485 jmethodID constructorId
486 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
487 jobject processedData = env->NewObject(clazz, constructorId, dataArray,
488 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
489 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
490
491 constructorId
492 = env->GetMethodID(localRef,
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900493 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
aimitakeshid074e302010-07-29 10:12:27 +0900494
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900495 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
496 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900497 }
498
James Dongf16a2722012-03-02 16:49:35 -0800499 delete[] mData; mData = NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900500 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
501
Steve Block06ade6a2011-10-20 11:56:00 +0100502 ALOGV("processDrmInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900503 return drmInfoStatus;
504}
505
506static jobject android_drm_DrmManagerClient_acquireDrmInfo(
507 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
Steve Block06ade6a2011-10-20 11:56:00 +0100508 ALOGV("acquireDrmInfo Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900509 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType");
510 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
511
512 DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
513
514 jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
515 jobject keyIterator
516 = env->CallObjectMethod(drmInfoRequest,
517 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
Henrik B Andersson057b0862012-02-10 13:17:40 +0100518 jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
519 "get", "(Ljava/lang/String;)Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900520
Henrik B Andersson057b0862012-02-10 13:17:40 +0100521 jclass Iterator_class = env->FindClass("java/util/Iterator");
522 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
523 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900524
Henrik B Andersson057b0862012-02-10 13:17:40 +0100525 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
526 ScopedLocalRef<jstring> key(env,
527 (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
528 ScopedLocalRef<jstring> value(env,
529 (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
aimitakeshid074e302010-07-29 10:12:27 +0900530
Henrik B Andersson057b0862012-02-10 13:17:40 +0100531 String8 keyString = Utility::getStringValue(env, key.get());
532 String8 valueString = Utility::getStringValue(env, value.get());
Steve Block06ade6a2011-10-20 11:56:00 +0100533 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900534
535 drmInfoReq.put(keyString, valueString);
536 }
537
538 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
539
540 jobject drmInfoObject = NULL;
541
542 if (NULL != pDrmInfo) {
543 jclass localRef = env->FindClass("android/drm/DrmInfo");
544
545 if (NULL != localRef) {
546 int length = pDrmInfo->getData().length;
547
548 jbyteArray dataArray = env->NewByteArray(length);
549 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
550
551 drmInfoObject
552 = env->NewObject(localRef,
553 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
554 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
555
556 DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
557 jmethodID putMethodId
558 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
559
560 while (it.hasNext()) {
561 String8 key = it.next();
562 String8 value = pDrmInfo->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100563 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
564 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900565 env->CallVoidMethod(drmInfoObject, putMethodId,
Henrik B Andersson057b0862012-02-10 13:17:40 +0100566 keyString.get(), valueString.get());
aimitakeshid074e302010-07-29 10:12:27 +0900567 }
568 }
569 delete [] pDrmInfo->getData().data;
570 }
571
572 delete pDrmInfo; pDrmInfo = NULL;
573
Steve Block06ade6a2011-10-20 11:56:00 +0100574 ALOGV("acquireDrmInfo Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900575 return drmInfoObject;
576}
577
578static jint android_drm_DrmManagerClient_getDrmObjectType(
579 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100580 ALOGV("getDrmObjectType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900581 int drmObjectType
582 = getDrmManagerClientImpl(env, thiz)
583 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
584 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100585 ALOGV("getDrmObjectType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900586 return drmObjectType;
587}
588
589static jstring android_drm_DrmManagerClient_getOriginalMimeType(
James Dong0889fda2012-08-08 17:45:59 -0700590 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jobject fileDescriptor) {
Steve Block06ade6a2011-10-20 11:56:00 +0100591 ALOGV("getOriginalMimeType Enter");
James Dong0889fda2012-08-08 17:45:59 -0700592
593 int fd = (fileDescriptor == NULL)
594 ? -1
595 : jniGetFDFromFileDescriptor(env, fileDescriptor);
596
aimitakeshid074e302010-07-29 10:12:27 +0900597 String8 mimeType
598 = getDrmManagerClientImpl(env, thiz)
James Dong0889fda2012-08-08 17:45:59 -0700599 ->getOriginalMimeType(uniqueId,
600 Utility::getStringValue(env, path), fd);
Steve Block06ade6a2011-10-20 11:56:00 +0100601 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900602 return env->NewStringUTF(mimeType.string());
603}
604
605static jint android_drm_DrmManagerClient_checkRightsStatus(
606 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
James Dong0889fda2012-08-08 17:45:59 -0700607 ALOGV("checkRightsStatus Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900608 int rightsStatus
609 = getDrmManagerClientImpl(env, thiz)
610 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
James Dong0889fda2012-08-08 17:45:59 -0700611 ALOGV("checkRightsStatus Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900612 return rightsStatus;
613}
614
Takeshi Aimidc549d62010-09-20 23:40:41 +0900615static jint android_drm_DrmManagerClient_removeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900616 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100617 ALOGV("removeRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900618 return getDrmManagerClientImpl(env, thiz)
619 ->removeRights(uniqueId, Utility::getStringValue(env, path));
aimitakeshid074e302010-07-29 10:12:27 +0900620}
621
Takeshi Aimidc549d62010-09-20 23:40:41 +0900622static jint android_drm_DrmManagerClient_removeAllRights(
aimitakeshid074e302010-07-29 10:12:27 +0900623 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100624 ALOGV("removeAllRights");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900625 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900626}
627
628static jint android_drm_DrmManagerClient_openConvertSession(
629 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100630 ALOGV("openConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900631 int convertId
632 = getDrmManagerClientImpl(env, thiz)
633 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100634 ALOGV("openConvertSession Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900635 return convertId;
636}
637
James Dong9864b252012-03-02 18:36:53 -0800638static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) {
639 ALOGV("GetConvertedStatus - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900640 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
641
642 jobject drmConvertedStatus = NULL;
643
644 if (NULL != localRef && NULL != pDrmConvertedStatus) {
645 int statusCode = pDrmConvertedStatus->statusCode;
646
647 jbyteArray dataArray = NULL;
648 if (NULL != pDrmConvertedStatus->convertedData) {
649 int length = pDrmConvertedStatus->convertedData->length;
650 dataArray = env->NewByteArray(length);
651 env->SetByteArrayRegion(
652 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
653
654 delete [] pDrmConvertedStatus->convertedData->data;
655 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
656 }
657 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
658 drmConvertedStatus
659 = env->NewObject(localRef, constructorId,
660 statusCode, dataArray, pDrmConvertedStatus->offset);
661 }
662
663 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
664
James Dong9864b252012-03-02 18:36:53 -0800665 ALOGV("GetConvertedStatus - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900666 return drmConvertedStatus;
667}
668
James Dong9864b252012-03-02 18:36:53 -0800669static jobject android_drm_DrmManagerClient_convertData(
670 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
671 ALOGV("convertData Enter");
672
673 int dataLength = 0;
674 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
675 const DrmBuffer buffer(mData, dataLength);
676
677 DrmConvertedStatus* pDrmConvertedStatus
678 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
679 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
680
681 delete[] mData;
682 mData = NULL;
683
684 ALOGV("convertData - Exit");
685 return status;
686}
687
688static jobject android_drm_DrmManagerClient_closeConvertSession(
689 JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
690
691 ALOGV("closeConvertSession Enter");
692
693 DrmConvertedStatus* pDrmConvertedStatus
694 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
695 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
696
697 ALOGV("closeConvertSession - Exit");
698 return status;
699}
700
aimitakeshid074e302010-07-29 10:12:27 +0900701static JNINativeMethod nativeMethods[] = {
702
Kei Takahashi6225df02012-01-31 13:18:45 +0900703 {"_initialize", "()I",
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900704 (void*)android_drm_DrmManagerClient_initialize},
aimitakeshid074e302010-07-29 10:12:27 +0900705
Kei Takahashi6225df02012-01-31 13:18:45 +0900706 {"_setListeners", "(ILjava/lang/Object;)V",
707 (void*)android_drm_DrmManagerClient_setListeners},
708
709 {"_release", "(I)V",
710 (void*)android_drm_DrmManagerClient_release},
aimitakeshid074e302010-07-29 10:12:27 +0900711
712 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
713 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
714
Takeshi Aimidc9186562010-11-16 13:56:11 +0900715 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
716 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
717
aimitakeshid074e302010-07-29 10:12:27 +0900718 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
719 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
720
721 {"_installDrmEngine", "(ILjava/lang/String;)V",
722 (void*)android_drm_DrmManagerClient_installDrmEngine},
723
724 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
725 (void*)android_drm_DrmManagerClient_canHandle},
726
727 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
728 (void*)android_drm_DrmManagerClient_processDrmInfo},
729
730 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
731 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
732
Takeshi Aimidc549d62010-09-20 23:40:41 +0900733 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900734 (void*)android_drm_DrmManagerClient_saveRights},
735
736 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
737 (void*)android_drm_DrmManagerClient_getDrmObjectType},
738
James Dong0889fda2012-08-08 17:45:59 -0700739 {"_getOriginalMimeType", "(ILjava/lang/String;Ljava/io/FileDescriptor;)Ljava/lang/String;",
aimitakeshid074e302010-07-29 10:12:27 +0900740 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
741
742 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
743 (void*)android_drm_DrmManagerClient_checkRightsStatus},
744
Takeshi Aimidc549d62010-09-20 23:40:41 +0900745 {"_removeRights", "(ILjava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900746 (void*)android_drm_DrmManagerClient_removeRights},
747
Takeshi Aimidc549d62010-09-20 23:40:41 +0900748 {"_removeAllRights", "(I)I",
aimitakeshid074e302010-07-29 10:12:27 +0900749 (void*)android_drm_DrmManagerClient_removeAllRights},
750
751 {"_openConvertSession", "(ILjava/lang/String;)I",
752 (void*)android_drm_DrmManagerClient_openConvertSession},
753
754 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
755 (void*)android_drm_DrmManagerClient_convertData},
756
757 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
758 (void*)android_drm_DrmManagerClient_closeConvertSession},
759};
760
761static int registerNativeMethods(JNIEnv* env) {
762 int result = -1;
763
764 /* look up the class */
765 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
766
767 if (NULL != clazz) {
768 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
769 / sizeof(nativeMethods[0])) == JNI_OK) {
770 result = 0;
771 }
772 }
773 return result;
774}
775
776jint JNI_OnLoad(JavaVM* vm, void* reserved) {
777 JNIEnv* env = NULL;
778 jint result = -1;
779
780 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
781 if (NULL != env && registerNativeMethods(env) == 0) {
782 result = JNI_VERSION_1_4;
783 }
784 }
785 return result;
786}
787