blob: 52ea8e3b161ff9596a9356a4014405f593802714 [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>
Steven Moreland2279b252017-07-19 09:50:45 -070022#include <nativehelper/JNIHelp.h>
23#include <nativehelper/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");
Ashok Bhat33d60382014-01-17 12:05:52 +0000185 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J");
aimitakeshid074e302010-07-29 10:12:27 +0900186
Ashok Bhat33d60382014-01-17 12:05:52 +0000187 jlong oldHandle = env->GetLongField(thiz, fieldId);
188 sp<DrmManagerClientImpl> old = reinterpret_cast<DrmManagerClientImpl*>(oldHandle);
aimitakeshid074e302010-07-29 10:12:27 +0900189 if (client.get()) {
190 client->incStrong(thiz);
191 }
192 if (old != 0) {
193 old->decStrong(thiz);
194 }
Ashok Bhat33d60382014-01-17 12:05:52 +0000195 env->SetLongField(thiz, fieldId, reinterpret_cast<jlong>(client.get()));
aimitakeshid074e302010-07-29 10:12:27 +0900196 return old;
197}
198
199static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
200 Mutex::Autolock l(sLock);
201 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
Ashok Bhat33d60382014-01-17 12:05:52 +0000202 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J");
aimitakeshid074e302010-07-29 10:12:27 +0900203
Ashok Bhat33d60382014-01-17 12:05:52 +0000204 jlong clientHandle = env->GetLongField(thiz, fieldId);
205 DrmManagerClientImpl* const client = reinterpret_cast<DrmManagerClientImpl*>(clientHandle);
aimitakeshid074e302010-07-29 10:12:27 +0900206 return sp<DrmManagerClientImpl>(client);
207}
208
Gloria Wanga17d4542011-07-21 15:10:22 -0700209static jint android_drm_DrmManagerClient_initialize(
Kei Takahashi6225df02012-01-31 13:18:45 +0900210 JNIEnv* env, jobject thiz) {
Steve Block06ade6a2011-10-20 11:56:00 +0100211 ALOGV("initialize - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900212
Gloria Wanga17d4542011-07-21 15:10:22 -0700213 int uniqueId = 0;
214 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900215 drmManager->addClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900216
aimitakeshid074e302010-07-29 10:12:27 +0900217 setDrmManagerClientImpl(env, thiz, drmManager);
Steve Block06ade6a2011-10-20 11:56:00 +0100218 ALOGV("initialize - Exit");
Ashok Bhat33d60382014-01-17 12:05:52 +0000219 return static_cast<jint>(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900220}
221
Kei Takahashi6225df02012-01-31 13:18:45 +0900222static void android_drm_DrmManagerClient_setListeners(
223 JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
224 ALOGV("setListeners - Enter");
225
226 // Set the listener to DrmManager
227 sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
228 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
229
230 ALOGV("setListeners - Exit");
231}
232
233static void android_drm_DrmManagerClient_release(
234 JNIEnv* env, jobject thiz, jint uniqueId) {
235 ALOGV("release - Enter");
Adam Lesinski510ef1b2014-06-04 15:05:56 -0700236 getDrmManagerClientImpl(env, thiz)->remove(uniqueId);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900237 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
aimitakeshid074e302010-07-29 10:12:27 +0900238
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900239 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
240 if (oldClient != NULL) {
241 oldClient->setOnInfoListener(uniqueId, NULL);
242 oldClient->removeClient(uniqueId);
aimitakeshid074e302010-07-29 10:12:27 +0900243 }
Kei Takahashi6225df02012-01-31 13:18:45 +0900244 ALOGV("release - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900245}
246
247static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
248 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
Steve Block06ade6a2011-10-20 11:56:00 +0100249 ALOGV("GetConstraints - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900250
251 const String8 pathString = Utility::getStringValue(env, jpath);
252 DrmConstraints* pConstraints
253 = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
254
255 jclass localRef = env->FindClass("android/content/ContentValues");
Henrik B Andersson057b0862012-02-10 13:17:40 +0100256 jmethodID ContentValues_putByteArray =
257 env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
258 jmethodID ContentValues_putString =
259 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
260 jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
aimitakeshid074e302010-07-29 10:12:27 +0900261 jobject constraints = NULL;
262
263 if (NULL != localRef && NULL != pConstraints) {
aimitakeshid074e302010-07-29 10:12:27 +0900264 // create the java DrmConstraints object
Henrik B Andersson057b0862012-02-10 13:17:40 +0100265 constraints = env->NewObject(localRef, ContentValues_constructor);
aimitakeshid074e302010-07-29 10:12:27 +0900266
267 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
aimitakeshid074e302010-07-29 10:12:27 +0900268 while (keyIt.hasNext()) {
269 String8 key = keyIt.next();
270
271 // insert the entry<constraintKey, constraintValue> to newly created java object
272 if (DrmConstraints::EXTENDED_METADATA == key) {
273 const char* value = pConstraints->getAsByteArray(&key);
274 if (NULL != value) {
Henrik B Andersson057b0862012-02-10 13:17:40 +0100275 ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
276 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
277 env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
278 env->CallVoidMethod(constraints, ContentValues_putByteArray,
279 keyString.get(), dataArray.get());
aimitakeshid074e302010-07-29 10:12:27 +0900280 }
281 } else {
282 String8 value = pConstraints->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100283 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
284 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
285 env->CallVoidMethod(constraints, ContentValues_putString,
286 keyString.get(), valueString.get());
aimitakeshid074e302010-07-29 10:12:27 +0900287 }
288 }
289 }
290
291 delete pConstraints; pConstraints = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100292 ALOGV("GetConstraints - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900293 return constraints;
294}
295
Takeshi Aimidc9186562010-11-16 13:56:11 +0900296static jobject android_drm_DrmManagerClient_getMetadataFromContent(
297 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100298 ALOGV("GetMetadata - Enter");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900299 const String8 pathString = Utility::getStringValue(env, jpath);
300 DrmMetadata* pMetadata =
301 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
302
303 jobject metadata = NULL;
304
Henrik B Andersson057b0862012-02-10 13:17:40 +0100305 jclass localRef = env->FindClass("android/content/ContentValues");
306 jmethodID ContentValues_putString =
307 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
308
Takeshi Aimidc9186562010-11-16 13:56:11 +0900309 if (NULL != localRef && NULL != pMetadata) {
310 // Get the constructor id
311 jmethodID constructorId = NULL;
312 constructorId = env->GetMethodID(localRef, "<init>", "()V");
313 if (NULL != constructorId) {
314 // create the java DrmMetadata object
315 metadata = env->NewObject(localRef, constructorId);
316 if (NULL != metadata) {
317 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
318 while (keyIt.hasNext()) {
319 String8 key = keyIt.next();
320 // insert the entry<constraintKey, constraintValue>
321 // to newly created java object
322 String8 value = pMetadata->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100323 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
324 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
325 env->CallVoidMethod(metadata, ContentValues_putString,
326 keyString.get(), valueString.get());
Takeshi Aimidc9186562010-11-16 13:56:11 +0900327 }
328 }
329 }
330 }
331 delete pMetadata; pMetadata = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100332 ALOGV("GetMetadata - Exit");
Takeshi Aimidc9186562010-11-16 13:56:11 +0900333 return metadata;
334}
335
aimitakeshid074e302010-07-29 10:12:27 +0900336static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
337 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100338 ALOGV("GetAllSupportInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900339 DrmSupportInfo* drmSupportInfoArray = NULL;
340
341 int length = 0;
342 getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
343
344 jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
345
346 jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
347
348 for (int i = 0; i < length; i++) {
349 DrmSupportInfo info = drmSupportInfoArray[i];
350
351 jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
352
353 jmethodID addMimeTypeId
354 = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
355 jmethodID addFileSuffixId
356 = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
357
358 env->CallVoidMethod(
359 drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
360 env->NewStringUTF(info.getDescription().string()));
361
362 DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
363 while (iterator.hasNext()) {
364 String8 value = iterator.next();
365 env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
366 }
367
368 DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
369 while (it.hasNext()) {
370 String8 value = it.next();
371 env->CallVoidMethod(
372 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
373 }
374
375 env->SetObjectArrayElement(array, i, drmSupportInfo);
376 }
377
378 delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100379 ALOGV("GetAllSupportInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900380 return array;
381}
382
383static void android_drm_DrmManagerClient_installDrmEngine(
Andreas Gampe318365e2014-11-10 17:23:02 -0800384 JNIEnv* /* env */, jobject /* thiz */, jint /* uniqueId */,
385 jstring /* engineFilePath */) {
Steve Block06ade6a2011-10-20 11:56:00 +0100386 ALOGV("installDrmEngine - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900387 //getDrmManagerClient(env, thiz)
388 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
Steve Block06ade6a2011-10-20 11:56:00 +0100389 ALOGV("installDrmEngine - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900390}
391
Takeshi Aimidc549d62010-09-20 23:40:41 +0900392static jint android_drm_DrmManagerClient_saveRights(
aimitakeshid074e302010-07-29 10:12:27 +0900393 JNIEnv* env, jobject thiz, jint uniqueId,
394 jobject drmRights, jstring rightsPath, jstring contentPath) {
Steve Block06ade6a2011-10-20 11:56:00 +0100395 ALOGV("saveRights - Enter");
Takeshi Aimidc549d62010-09-20 23:40:41 +0900396 int result = DRM_ERROR_UNKNOWN;
aimitakeshid074e302010-07-29 10:12:27 +0900397 int dataLength = 0;
398 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
399
400 if (NULL != mData) {
401 DrmRights rights(DrmBuffer(mData, dataLength),
402 Utility::getStringValue(env, drmRights, "mMimeType"),
403 Utility::getStringValue(env, drmRights, "mAccountId"),
404 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
Takeshi Aimidc549d62010-09-20 23:40:41 +0900405 result = getDrmManagerClientImpl(env, thiz)
aimitakeshid074e302010-07-29 10:12:27 +0900406 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
407 Utility::getStringValue(env, contentPath));
408 }
409
James Dongf16a2722012-03-02 16:49:35 -0800410 delete[] mData; mData = NULL;
Steve Block06ade6a2011-10-20 11:56:00 +0100411 ALOGV("saveRights - Exit");
Ashok Bhat33d60382014-01-17 12:05:52 +0000412 return static_cast<jint>(result);
aimitakeshid074e302010-07-29 10:12:27 +0900413}
414
415static jboolean android_drm_DrmManagerClient_canHandle(
416 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100417 ALOGV("canHandle - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900418 jboolean result
419 = getDrmManagerClientImpl(env, thiz)
420 ->canHandle(uniqueId, Utility::getStringValue(env, path),
421 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100422 ALOGV("canHandle - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900423 return result;
424}
425
426static jobject android_drm_DrmManagerClient_processDrmInfo(
427 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
Steve Block06ade6a2011-10-20 11:56:00 +0100428 ALOGV("processDrmInfo - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900429 int dataLength = 0;
430 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType");
431 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
432 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
433
434 const DrmBuffer buffer(mData, dataLength);
435 DrmInfo drmInfo(mInfoType, buffer, mMimeType);
436
437 jclass clazz = env->FindClass("android/drm/DrmInfo");
Henrik B Andersson057b0862012-02-10 13:17:40 +0100438 jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900439 jobject keyIterator
440 = env->CallObjectMethod(drmInfoObject,
441 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
442
Henrik B Andersson057b0862012-02-10 13:17:40 +0100443 jclass Iterator_class = env->FindClass("java/util/Iterator");
444 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
445 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900446
Henrik B Andersson057b0862012-02-10 13:17:40 +0100447 jclass Object_class = env->FindClass("java/lang/Object");
448 jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
aimitakeshid074e302010-07-29 10:12:27 +0900449
Henrik B Andersson057b0862012-02-10 13:17:40 +0100450 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
451 ScopedLocalRef<jstring> key(env,
452 (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
453 ScopedLocalRef<jobject> valueObject(env,
454 env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
455 ScopedLocalRef<jstring> valString(env, NULL);
456 if (NULL != valueObject.get()) {
457 valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
aimitakeshid074e302010-07-29 10:12:27 +0900458 }
459
Henrik B Andersson057b0862012-02-10 13:17:40 +0100460 String8 keyString = Utility::getStringValue(env, key.get());
461 String8 valueString = Utility::getStringValue(env, valString.get());
Steve Block06ade6a2011-10-20 11:56:00 +0100462 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900463
464 drmInfo.put(keyString, valueString);
465 }
466
467 DrmInfoStatus* pDrmInfoStatus
468 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
469
470 jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
471 jobject drmInfoStatus = NULL;
472
473 if (NULL != localRef && NULL != pDrmInfoStatus) {
474 int statusCode = pDrmInfoStatus->statusCode;
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900475 int infoType = pDrmInfoStatus->infoType;
aimitakeshid074e302010-07-29 10:12:27 +0900476
477 jbyteArray dataArray = NULL;
478 if (NULL != pDrmInfoStatus->drmBuffer) {
479 int length = pDrmInfoStatus->drmBuffer->length;
480 dataArray = env->NewByteArray(length);
481 env->SetByteArrayRegion(
482 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
483
484 delete [] pDrmInfoStatus->drmBuffer->data;
485 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
486 }
487 jclass clazz = env->FindClass("android/drm/ProcessedData");
488 jmethodID constructorId
489 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
490 jobject processedData = env->NewObject(clazz, constructorId, dataArray,
491 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
492 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
493
494 constructorId
495 = env->GetMethodID(localRef,
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900496 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
aimitakeshid074e302010-07-29 10:12:27 +0900497
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900498 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
499 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900500 }
501
James Dongf16a2722012-03-02 16:49:35 -0800502 delete[] mData; mData = NULL;
aimitakeshid074e302010-07-29 10:12:27 +0900503 delete pDrmInfoStatus; pDrmInfoStatus = NULL;
504
Steve Block06ade6a2011-10-20 11:56:00 +0100505 ALOGV("processDrmInfo - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900506 return drmInfoStatus;
507}
508
509static jobject android_drm_DrmManagerClient_acquireDrmInfo(
510 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
Steve Block06ade6a2011-10-20 11:56:00 +0100511 ALOGV("acquireDrmInfo Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900512 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType");
513 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
514
515 DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
516
517 jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
518 jobject keyIterator
519 = env->CallObjectMethod(drmInfoRequest,
520 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
Henrik B Andersson057b0862012-02-10 13:17:40 +0100521 jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
522 "get", "(Ljava/lang/String;)Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900523
Henrik B Andersson057b0862012-02-10 13:17:40 +0100524 jclass Iterator_class = env->FindClass("java/util/Iterator");
525 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
526 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
aimitakeshid074e302010-07-29 10:12:27 +0900527
Henrik B Andersson057b0862012-02-10 13:17:40 +0100528 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
529 ScopedLocalRef<jstring> key(env,
530 (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
531 ScopedLocalRef<jstring> value(env,
532 (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
aimitakeshid074e302010-07-29 10:12:27 +0900533
Henrik B Andersson057b0862012-02-10 13:17:40 +0100534 String8 keyString = Utility::getStringValue(env, key.get());
535 String8 valueString = Utility::getStringValue(env, value.get());
Steve Block06ade6a2011-10-20 11:56:00 +0100536 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
aimitakeshid074e302010-07-29 10:12:27 +0900537
538 drmInfoReq.put(keyString, valueString);
539 }
540
541 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
542
543 jobject drmInfoObject = NULL;
544
545 if (NULL != pDrmInfo) {
546 jclass localRef = env->FindClass("android/drm/DrmInfo");
547
548 if (NULL != localRef) {
549 int length = pDrmInfo->getData().length;
550
551 jbyteArray dataArray = env->NewByteArray(length);
552 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
553
554 drmInfoObject
555 = env->NewObject(localRef,
556 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
557 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
558
559 DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
560 jmethodID putMethodId
561 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
562
563 while (it.hasNext()) {
564 String8 key = it.next();
565 String8 value = pDrmInfo->get(key);
Henrik B Andersson057b0862012-02-10 13:17:40 +0100566 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
567 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
aimitakeshid074e302010-07-29 10:12:27 +0900568 env->CallVoidMethod(drmInfoObject, putMethodId,
Henrik B Andersson057b0862012-02-10 13:17:40 +0100569 keyString.get(), valueString.get());
aimitakeshid074e302010-07-29 10:12:27 +0900570 }
571 }
572 delete [] pDrmInfo->getData().data;
573 }
574
575 delete pDrmInfo; pDrmInfo = NULL;
576
Steve Block06ade6a2011-10-20 11:56:00 +0100577 ALOGV("acquireDrmInfo Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900578 return drmInfoObject;
579}
580
581static jint android_drm_DrmManagerClient_getDrmObjectType(
582 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100583 ALOGV("getDrmObjectType Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900584 int drmObjectType
585 = getDrmManagerClientImpl(env, thiz)
586 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
587 Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100588 ALOGV("getDrmObjectType Exit");
Ashok Bhat33d60382014-01-17 12:05:52 +0000589 return static_cast<jint>(drmObjectType);
aimitakeshid074e302010-07-29 10:12:27 +0900590}
591
592static jstring android_drm_DrmManagerClient_getOriginalMimeType(
James Dong0889fda2012-08-08 17:45:59 -0700593 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jobject fileDescriptor) {
Steve Block06ade6a2011-10-20 11:56:00 +0100594 ALOGV("getOriginalMimeType Enter");
James Dong0889fda2012-08-08 17:45:59 -0700595
596 int fd = (fileDescriptor == NULL)
597 ? -1
598 : jniGetFDFromFileDescriptor(env, fileDescriptor);
599
aimitakeshid074e302010-07-29 10:12:27 +0900600 String8 mimeType
601 = getDrmManagerClientImpl(env, thiz)
James Dong0889fda2012-08-08 17:45:59 -0700602 ->getOriginalMimeType(uniqueId,
603 Utility::getStringValue(env, path), fd);
Steve Block06ade6a2011-10-20 11:56:00 +0100604 ALOGV("getOriginalMimeType Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900605 return env->NewStringUTF(mimeType.string());
606}
607
608static jint android_drm_DrmManagerClient_checkRightsStatus(
609 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
James Dong0889fda2012-08-08 17:45:59 -0700610 ALOGV("checkRightsStatus Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900611 int rightsStatus
612 = getDrmManagerClientImpl(env, thiz)
613 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
James Dong0889fda2012-08-08 17:45:59 -0700614 ALOGV("checkRightsStatus Exit");
Ashok Bhat33d60382014-01-17 12:05:52 +0000615 return static_cast<jint>(rightsStatus);
aimitakeshid074e302010-07-29 10:12:27 +0900616}
617
Takeshi Aimidc549d62010-09-20 23:40:41 +0900618static jint android_drm_DrmManagerClient_removeRights(
aimitakeshid074e302010-07-29 10:12:27 +0900619 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
Steve Block06ade6a2011-10-20 11:56:00 +0100620 ALOGV("removeRights");
Ashok Bhat33d60382014-01-17 12:05:52 +0000621 return static_cast<jint>(getDrmManagerClientImpl(env, thiz)
622 ->removeRights(uniqueId, Utility::getStringValue(env, path)));
aimitakeshid074e302010-07-29 10:12:27 +0900623}
624
Takeshi Aimidc549d62010-09-20 23:40:41 +0900625static jint android_drm_DrmManagerClient_removeAllRights(
aimitakeshid074e302010-07-29 10:12:27 +0900626 JNIEnv* env, jobject thiz, jint uniqueId) {
Steve Block06ade6a2011-10-20 11:56:00 +0100627 ALOGV("removeAllRights");
Ashok Bhat33d60382014-01-17 12:05:52 +0000628 return static_cast<jint>(getDrmManagerClientImpl(env, thiz)
629 ->removeAllRights(uniqueId));
aimitakeshid074e302010-07-29 10:12:27 +0900630}
631
632static jint android_drm_DrmManagerClient_openConvertSession(
633 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
Steve Block06ade6a2011-10-20 11:56:00 +0100634 ALOGV("openConvertSession Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900635 int convertId
636 = getDrmManagerClientImpl(env, thiz)
637 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
Steve Block06ade6a2011-10-20 11:56:00 +0100638 ALOGV("openConvertSession Exit");
Ashok Bhat33d60382014-01-17 12:05:52 +0000639 return static_cast<jint>(convertId);
aimitakeshid074e302010-07-29 10:12:27 +0900640}
641
James Dong9864b252012-03-02 18:36:53 -0800642static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) {
643 ALOGV("GetConvertedStatus - Enter");
aimitakeshid074e302010-07-29 10:12:27 +0900644 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
645
646 jobject drmConvertedStatus = NULL;
647
648 if (NULL != localRef && NULL != pDrmConvertedStatus) {
649 int statusCode = pDrmConvertedStatus->statusCode;
650
651 jbyteArray dataArray = NULL;
652 if (NULL != pDrmConvertedStatus->convertedData) {
653 int length = pDrmConvertedStatus->convertedData->length;
654 dataArray = env->NewByteArray(length);
655 env->SetByteArrayRegion(
656 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
657
658 delete [] pDrmConvertedStatus->convertedData->data;
659 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
660 }
661 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
662 drmConvertedStatus
663 = env->NewObject(localRef, constructorId,
664 statusCode, dataArray, pDrmConvertedStatus->offset);
665 }
666
667 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
668
James Dong9864b252012-03-02 18:36:53 -0800669 ALOGV("GetConvertedStatus - Exit");
aimitakeshid074e302010-07-29 10:12:27 +0900670 return drmConvertedStatus;
671}
672
James Dong9864b252012-03-02 18:36:53 -0800673static jobject android_drm_DrmManagerClient_convertData(
674 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
675 ALOGV("convertData Enter");
676
677 int dataLength = 0;
678 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
679 const DrmBuffer buffer(mData, dataLength);
680
681 DrmConvertedStatus* pDrmConvertedStatus
682 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
683 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
684
685 delete[] mData;
686 mData = NULL;
687
688 ALOGV("convertData - Exit");
689 return status;
690}
691
692static jobject android_drm_DrmManagerClient_closeConvertSession(
Ashok Bhat33d60382014-01-17 12:05:52 +0000693 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId) {
James Dong9864b252012-03-02 18:36:53 -0800694
695 ALOGV("closeConvertSession Enter");
696
697 DrmConvertedStatus* pDrmConvertedStatus
698 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
699 jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
700
701 ALOGV("closeConvertSession - Exit");
702 return status;
703}
704
Daniel Micay76f6a862015-09-19 17:31:01 -0400705static const JNINativeMethod nativeMethods[] = {
aimitakeshid074e302010-07-29 10:12:27 +0900706
Kei Takahashi6225df02012-01-31 13:18:45 +0900707 {"_initialize", "()I",
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900708 (void*)android_drm_DrmManagerClient_initialize},
aimitakeshid074e302010-07-29 10:12:27 +0900709
Kei Takahashi6225df02012-01-31 13:18:45 +0900710 {"_setListeners", "(ILjava/lang/Object;)V",
711 (void*)android_drm_DrmManagerClient_setListeners},
712
713 {"_release", "(I)V",
714 (void*)android_drm_DrmManagerClient_release},
aimitakeshid074e302010-07-29 10:12:27 +0900715
716 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
717 (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
718
Takeshi Aimidc9186562010-11-16 13:56:11 +0900719 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
720 (void*)android_drm_DrmManagerClient_getMetadataFromContent},
721
aimitakeshid074e302010-07-29 10:12:27 +0900722 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
723 (void*)android_drm_DrmManagerClient_getAllSupportInfo},
724
725 {"_installDrmEngine", "(ILjava/lang/String;)V",
726 (void*)android_drm_DrmManagerClient_installDrmEngine},
727
728 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
729 (void*)android_drm_DrmManagerClient_canHandle},
730
731 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
732 (void*)android_drm_DrmManagerClient_processDrmInfo},
733
734 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
735 (void*)android_drm_DrmManagerClient_acquireDrmInfo},
736
Takeshi Aimidc549d62010-09-20 23:40:41 +0900737 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900738 (void*)android_drm_DrmManagerClient_saveRights},
739
740 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
741 (void*)android_drm_DrmManagerClient_getDrmObjectType},
742
James Dong0889fda2012-08-08 17:45:59 -0700743 {"_getOriginalMimeType", "(ILjava/lang/String;Ljava/io/FileDescriptor;)Ljava/lang/String;",
aimitakeshid074e302010-07-29 10:12:27 +0900744 (void*)android_drm_DrmManagerClient_getOriginalMimeType},
745
746 {"_checkRightsStatus", "(ILjava/lang/String;I)I",
747 (void*)android_drm_DrmManagerClient_checkRightsStatus},
748
Takeshi Aimidc549d62010-09-20 23:40:41 +0900749 {"_removeRights", "(ILjava/lang/String;)I",
aimitakeshid074e302010-07-29 10:12:27 +0900750 (void*)android_drm_DrmManagerClient_removeRights},
751
Takeshi Aimidc549d62010-09-20 23:40:41 +0900752 {"_removeAllRights", "(I)I",
aimitakeshid074e302010-07-29 10:12:27 +0900753 (void*)android_drm_DrmManagerClient_removeAllRights},
754
755 {"_openConvertSession", "(ILjava/lang/String;)I",
756 (void*)android_drm_DrmManagerClient_openConvertSession},
757
758 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
759 (void*)android_drm_DrmManagerClient_convertData},
760
761 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
762 (void*)android_drm_DrmManagerClient_closeConvertSession},
763};
764
765static int registerNativeMethods(JNIEnv* env) {
766 int result = -1;
767
768 /* look up the class */
769 jclass clazz = env->FindClass("android/drm/DrmManagerClient");
770
771 if (NULL != clazz) {
772 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
773 / sizeof(nativeMethods[0])) == JNI_OK) {
774 result = 0;
775 }
776 }
777 return result;
778}
779
Andreas Gampe318365e2014-11-10 17:23:02 -0800780jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
aimitakeshid074e302010-07-29 10:12:27 +0900781 JNIEnv* env = NULL;
782 jint result = -1;
783
784 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
785 if (NULL != env && registerNativeMethods(env) == 0) {
786 result = JNI_VERSION_1_4;
787 }
788 }
789 return result;
790}
791