• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "android_drm_DrmManagerClient"
19 #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>
32 #include <drm/DrmMetadata.h>
33 #include <drm/DrmConvertedStatus.h>
34 #include <drm/drm_framework_common.h>
35 
36 #include <DrmManagerClientImpl.h>
37 
38 using 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  */
44 class Utility {
45 public:
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 
getStringValue(JNIEnv * env,jobject object,const char * fieldName)59 String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) {
60     /* Look for the instance field with the name fieldName */
61     jfieldID fieldID
62         = env->GetFieldID(env->GetObjectClass(object), fieldName , "Ljava/lang/String;");
63 
64     if (NULL != fieldID) {
65         jstring valueString = (jstring) env->GetObjectField(object, fieldID);
66         return Utility::getStringValue(env, valueString);
67     }
68 
69     String8 dataString("");
70     return dataString;
71 }
72 
getStringValue(JNIEnv * env,jstring string)73 String8 Utility::getStringValue(JNIEnv* env, jstring string) {
74     String8 dataString("");
75 
76     if (NULL != string && string != env->NewStringUTF("")) {
77         char* bytes = const_cast< char* > (env->GetStringUTFChars(string, NULL));
78 
79         const int length = strlen(bytes) + 1;
80         char *data = new char[length];
81         strncpy(data, bytes, length);
82         dataString = String8(data);
83 
84         env->ReleaseStringUTFChars(string, bytes);
85         delete [] data; data = NULL;
86     }
87     return dataString;
88 }
89 
getByteArrayValue(JNIEnv * env,jobject object,const char * fieldName,int * dataLength)90 char* Utility::getByteArrayValue(
91             JNIEnv* env, jobject object, const char* fieldName, int* dataLength) {
92 
93     *dataLength = 0;
94 
95     jfieldID fieldID = env->GetFieldID(env->GetObjectClass(object), fieldName , "[B");
96 
97     if (NULL != fieldID) {
98         jbyteArray byteArray = (jbyteArray) env->GetObjectField(object, fieldID);
99         return Utility::getByteArrayValue(env, byteArray, dataLength);
100     }
101     return NULL;
102 }
103 
getByteArrayValue(JNIEnv * env,jbyteArray byteArray,int * dataLength)104 char* Utility::getByteArrayValue(JNIEnv* env, jbyteArray byteArray, int* dataLength) {
105     char* data = NULL;
106     if (NULL != byteArray) {
107         jint length = env->GetArrayLength(byteArray);
108 
109         *dataLength = length;
110         if (0 < *dataLength) {
111             data = new char[length];
112             env->GetByteArrayRegion(byteArray, (jint)0, length, (jbyte *) data);
113         }
114     }
115     return data;
116 }
117 
getIntValue(JNIEnv * env,jobject object,const char * fieldName)118 int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) {
119     jfieldID fieldID;
120     int intValue = -1;
121 
122     /* Get a reference to obj’s class */
123     jclass clazz = env->GetObjectClass(object);
124     /* Look for the instance field with the name fieldName */
125     fieldID = env->GetFieldID(clazz, fieldName , "I");
126 
127     if (NULL != fieldID) {
128         intValue = (int) env->GetIntField(object, fieldID);
129     }
130 
131     return intValue;
132 }
133 
134 class JNIOnInfoListener : public DrmManagerClient::OnInfoListener {
135 public:
136     JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz);
137 
138     virtual ~JNIOnInfoListener();
139     void onInfo(const DrmInfoEvent& event);
140 
141 private:
142     JNIOnInfoListener();
143     jclass mClass;
144     jobject mObject;
145 };
146 
JNIOnInfoListener(JNIEnv * env,jobject thiz,jobject weak_thiz)147 JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
148     jclass clazz = env->GetObjectClass(thiz);
149 
150     if (clazz == NULL) {
151         ALOGE("Can't find android/drm/DrmManagerClient");
152         jniThrowException(env, "java/lang/Exception", NULL);
153         return;
154     }
155     mClass = (jclass)env->NewGlobalRef(clazz);
156     mObject  = env->NewGlobalRef(weak_thiz);
157 }
158 
~JNIOnInfoListener()159 JNIOnInfoListener::~JNIOnInfoListener() {
160     JNIEnv *env = AndroidRuntime::getJNIEnv();
161     env->DeleteGlobalRef(mObject);
162     env->DeleteGlobalRef(mClass);
163 }
164 
onInfo(const DrmInfoEvent & event)165 void JNIOnInfoListener::onInfo(const DrmInfoEvent& event) {
166     jint uniqueId = event.getUniqueId();
167     jint type = event.getType();
168     JNIEnv *env = AndroidRuntime::getJNIEnv();
169     jstring message = env->NewStringUTF(event.getMessage().string());
170     ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string());
171 
172     env->CallStaticVoidMethod(
173             mClass,
174             env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"),
175             mObject, uniqueId, type, message);
176 }
177 
178 static Mutex sLock;
179 
setDrmManagerClientImpl(JNIEnv * env,jobject thiz,const sp<DrmManagerClientImpl> & client)180 static sp<DrmManagerClientImpl> setDrmManagerClientImpl(
181             JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) {
182     Mutex::Autolock l(sLock);
183     jclass clazz = env->FindClass("android/drm/DrmManagerClient");
184     jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
185 
186     sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
187     if (client.get()) {
188         client->incStrong(thiz);
189     }
190     if (old != 0) {
191         old->decStrong(thiz);
192     }
193     env->SetIntField(thiz, fieldId, (int)client.get());
194     return old;
195 }
196 
getDrmManagerClientImpl(JNIEnv * env,jobject thiz)197 static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) {
198     Mutex::Autolock l(sLock);
199     jclass clazz = env->FindClass("android/drm/DrmManagerClient");
200     jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I");
201 
202     DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId);
203     return sp<DrmManagerClientImpl>(client);
204 }
205 
android_drm_DrmManagerClient_initialize(JNIEnv * env,jobject thiz)206 static jint android_drm_DrmManagerClient_initialize(
207         JNIEnv* env, jobject thiz) {
208     ALOGV("initialize - Enter");
209 
210     int uniqueId = 0;
211     sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false);
212     drmManager->addClient(uniqueId);
213 
214     setDrmManagerClientImpl(env, thiz, drmManager);
215     ALOGV("initialize - Exit");
216     return uniqueId;
217 }
218 
android_drm_DrmManagerClient_setListeners(JNIEnv * env,jobject thiz,jint uniqueId,jobject weak_thiz)219 static void android_drm_DrmManagerClient_setListeners(
220         JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
221     ALOGV("setListeners - Enter");
222 
223     // Set the listener to DrmManager
224     sp<DrmManagerClient::OnInfoListener> listener = new JNIOnInfoListener(env, thiz, weak_thiz);
225     getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, listener);
226 
227     ALOGV("setListeners - Exit");
228 }
229 
android_drm_DrmManagerClient_release(JNIEnv * env,jobject thiz,jint uniqueId)230 static void android_drm_DrmManagerClient_release(
231         JNIEnv* env, jobject thiz, jint uniqueId) {
232     ALOGV("release - Enter");
233     DrmManagerClientImpl::remove(uniqueId);
234     getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL);
235 
236     sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
237     if (oldClient != NULL) {
238         oldClient->setOnInfoListener(uniqueId, NULL);
239         oldClient->removeClient(uniqueId);
240     }
241     ALOGV("release - Exit");
242 }
243 
android_drm_DrmManagerClient_getConstraintsFromContent(JNIEnv * env,jobject thiz,jint uniqueId,jstring jpath,jint usage)244 static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
245             JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) {
246     ALOGV("GetConstraints - Enter");
247 
248     const String8 pathString = Utility::getStringValue(env, jpath);
249     DrmConstraints* pConstraints
250         = getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
251 
252     jclass localRef = env->FindClass("android/content/ContentValues");
253     jobject constraints = NULL;
254 
255     if (NULL != localRef && NULL != pConstraints) {
256         // Get the constructor id
257         jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
258         // create the java DrmConstraints object
259         constraints = env->NewObject(localRef, constructorId);
260 
261         DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
262 
263         while (keyIt.hasNext()) {
264             String8 key = keyIt.next();
265 
266             // insert the entry<constraintKey, constraintValue> to newly created java object
267             if (DrmConstraints::EXTENDED_METADATA == key) {
268                 const char* value = pConstraints->getAsByteArray(&key);
269                 if (NULL != value) {
270                     jbyteArray dataArray = env->NewByteArray(strlen(value));
271                     env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
272                     env->CallVoidMethod(
273                         constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
274                                      env->NewStringUTF(key.string()), dataArray);
275                 }
276             } else {
277                 String8 value = pConstraints->get(key);
278                 env->CallVoidMethod(
279                     constraints,
280                     env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
281                 env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
282             }
283         }
284     }
285 
286     delete pConstraints; pConstraints = NULL;
287     ALOGV("GetConstraints - Exit");
288     return constraints;
289 }
290 
android_drm_DrmManagerClient_getMetadataFromContent(JNIEnv * env,jobject thiz,jint uniqueId,jstring jpath)291 static jobject android_drm_DrmManagerClient_getMetadataFromContent(
292             JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) {
293     ALOGV("GetMetadata - Enter");
294     const String8 pathString = Utility::getStringValue(env, jpath);
295     DrmMetadata* pMetadata =
296             getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString);
297 
298     jobject metadata = NULL;
299 
300     jclass localRef = NULL;
301     localRef = env->FindClass("android/content/ContentValues");
302     if (NULL != localRef && NULL != pMetadata) {
303         // Get the constructor id
304         jmethodID constructorId = NULL;
305         constructorId = env->GetMethodID(localRef, "<init>", "()V");
306         if (NULL != constructorId) {
307             // create the java DrmMetadata object
308             metadata = env->NewObject(localRef, constructorId);
309             if (NULL != metadata) {
310                 DrmMetadata::KeyIterator keyIt = pMetadata->keyIterator();
311                 while (keyIt.hasNext()) {
312                     String8 key = keyIt.next();
313                     // insert the entry<constraintKey, constraintValue>
314                     // to newly created java object
315                     String8 value = pMetadata->get(key);
316                     env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
317                             "(Ljava/lang/String;Ljava/lang/String;)V"),
318                     env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
319                 }
320             }
321         }
322     }
323     delete pMetadata; pMetadata = NULL;
324     ALOGV("GetMetadata - Exit");
325     return metadata;
326 }
327 
android_drm_DrmManagerClient_getAllSupportInfo(JNIEnv * env,jobject thiz,jint uniqueId)328 static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo(
329             JNIEnv* env, jobject thiz, jint uniqueId) {
330     ALOGV("GetAllSupportInfo - Enter");
331     DrmSupportInfo* drmSupportInfoArray = NULL;
332 
333     int length = 0;
334     getDrmManagerClientImpl(env, thiz)->getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
335 
336     jclass clazz = env->FindClass("android/drm/DrmSupportInfo");
337 
338     jobjectArray array = (jobjectArray)env->NewObjectArray(length, clazz, NULL);
339 
340     for (int i = 0; i < length; i++) {
341         DrmSupportInfo info = drmSupportInfoArray[i];
342 
343         jobject drmSupportInfo = env->NewObject(clazz, env->GetMethodID(clazz, "<init>", "()V"));
344 
345         jmethodID addMimeTypeId
346             = env->GetMethodID(clazz, "addMimeType", "(Ljava/lang/String;)V");
347         jmethodID addFileSuffixId
348             = env->GetMethodID(clazz, "addFileSuffix", "(Ljava/lang/String;)V");
349 
350         env->CallVoidMethod(
351             drmSupportInfo, env->GetMethodID(clazz, "setDescription", "(Ljava/lang/String;)V"),
352             env->NewStringUTF(info.getDescription().string()));
353 
354         DrmSupportInfo::MimeTypeIterator iterator = info.getMimeTypeIterator();
355         while (iterator.hasNext()) {
356             String8  value = iterator.next();
357             env->CallVoidMethod(drmSupportInfo, addMimeTypeId, env->NewStringUTF(value.string()));
358         }
359 
360         DrmSupportInfo::FileSuffixIterator it = info.getFileSuffixIterator();
361         while (it.hasNext()) {
362             String8 value = it.next();
363             env->CallVoidMethod(
364                 drmSupportInfo, addFileSuffixId, env->NewStringUTF(value.string()));
365         }
366 
367         env->SetObjectArrayElement(array, i, drmSupportInfo);
368     }
369 
370     delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
371     ALOGV("GetAllSupportInfo - Exit");
372     return array;
373 }
374 
android_drm_DrmManagerClient_installDrmEngine(JNIEnv * env,jobject thiz,jint uniqueId,jstring engineFilePath)375 static void android_drm_DrmManagerClient_installDrmEngine(
376             JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) {
377     ALOGV("installDrmEngine - Enter");
378     //getDrmManagerClient(env, thiz)
379     //  ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath));
380     ALOGV("installDrmEngine - Exit");
381 }
382 
android_drm_DrmManagerClient_saveRights(JNIEnv * env,jobject thiz,jint uniqueId,jobject drmRights,jstring rightsPath,jstring contentPath)383 static jint android_drm_DrmManagerClient_saveRights(
384             JNIEnv* env, jobject thiz, jint uniqueId,
385             jobject drmRights, jstring rightsPath, jstring contentPath) {
386     ALOGV("saveRights - Enter");
387     int result = DRM_ERROR_UNKNOWN;
388     int dataLength = 0;
389     char* mData =  Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
390 
391     if (NULL != mData) {
392         DrmRights rights(DrmBuffer(mData, dataLength),
393                 Utility::getStringValue(env, drmRights, "mMimeType"),
394                 Utility::getStringValue(env, drmRights, "mAccountId"),
395                 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
396         result = getDrmManagerClientImpl(env, thiz)
397             ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
398                                 Utility::getStringValue(env, contentPath));
399     }
400 
401     delete[] mData; mData = NULL;
402     ALOGV("saveRights - Exit");
403     return result;
404 }
405 
android_drm_DrmManagerClient_canHandle(JNIEnv * env,jobject thiz,jint uniqueId,jstring path,jstring mimeType)406 static jboolean android_drm_DrmManagerClient_canHandle(
407             JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
408     ALOGV("canHandle - Enter");
409     jboolean result
410         = getDrmManagerClientImpl(env, thiz)
411             ->canHandle(uniqueId, Utility::getStringValue(env, path),
412                     Utility::getStringValue(env, mimeType));
413     ALOGV("canHandle - Exit");
414     return result;
415 }
416 
android_drm_DrmManagerClient_processDrmInfo(JNIEnv * env,jobject thiz,jint uniqueId,jobject drmInfoObject)417 static jobject android_drm_DrmManagerClient_processDrmInfo(
418             JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) {
419     ALOGV("processDrmInfo - Enter");
420     int dataLength = 0;
421     const String8 mMimeType =  Utility::getStringValue(env, drmInfoObject, "mMimeType");
422     char* mData =  Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength);
423     int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType");
424 
425     const DrmBuffer buffer(mData, dataLength);
426     DrmInfo drmInfo(mInfoType, buffer, mMimeType);
427 
428     jclass clazz = env->FindClass("android/drm/DrmInfo");
429     jobject keyIterator
430         = env->CallObjectMethod(drmInfoObject,
431                 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
432 
433     jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
434 
435     while (env->CallBooleanMethod(keyIterator, hasNextId)) {
436         jstring key = (jstring) env->CallObjectMethod(keyIterator,
437                 env->GetMethodID(env->FindClass("java/util/Iterator"),
438                 "next", "()Ljava/lang/Object;"));
439 
440         jobject valueObject = env->CallObjectMethod(drmInfoObject,
441                 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
442 
443         jstring valString = NULL;
444         if (NULL != valueObject) {
445             valString = (jstring) env->CallObjectMethod(valueObject,
446                 env->GetMethodID(env->FindClass("java/lang/Object"),
447                 "toString", "()Ljava/lang/String;"));
448         }
449 
450         String8 keyString = Utility::getStringValue(env, key);
451         String8 valueString = Utility::getStringValue(env, valString);
452         ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
453 
454         drmInfo.put(keyString, valueString);
455     }
456 
457     DrmInfoStatus* pDrmInfoStatus
458         = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo);
459 
460     jclass localRef = env->FindClass("android/drm/DrmInfoStatus");
461     jobject drmInfoStatus = NULL;
462 
463     if (NULL != localRef && NULL != pDrmInfoStatus) {
464         int statusCode = pDrmInfoStatus->statusCode;
465         int infoType = pDrmInfoStatus->infoType;
466 
467         jbyteArray dataArray = NULL;
468         if (NULL != pDrmInfoStatus->drmBuffer) {
469             int length = pDrmInfoStatus->drmBuffer->length;
470             dataArray = env->NewByteArray(length);
471             env->SetByteArrayRegion(
472                 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data);
473 
474             delete [] pDrmInfoStatus->drmBuffer->data;
475             delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL;
476         }
477         jclass clazz = env->FindClass("android/drm/ProcessedData");
478         jmethodID constructorId
479             = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V");
480         jobject processedData = env->NewObject(clazz, constructorId, dataArray,
481                     env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()),
482                     env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string()));
483 
484         constructorId
485             = env->GetMethodID(localRef,
486                 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V");
487 
488         drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType,
489                 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string()));
490     }
491 
492     delete[] mData; mData = NULL;
493     delete pDrmInfoStatus; pDrmInfoStatus = NULL;
494 
495     ALOGV("processDrmInfo - Exit");
496     return drmInfoStatus;
497 }
498 
android_drm_DrmManagerClient_acquireDrmInfo(JNIEnv * env,jobject thiz,jint uniqueId,jobject drmInfoRequest)499 static jobject android_drm_DrmManagerClient_acquireDrmInfo(
500             JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) {
501     ALOGV("acquireDrmInfo Enter");
502     const String8 mMimeType =  Utility::getStringValue(env, drmInfoRequest, "mMimeType");
503     int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType");
504 
505     DrmInfoRequest drmInfoReq(mInfoType, mMimeType);
506 
507     jclass clazz = env->FindClass("android/drm/DrmInfoRequest");
508     jobject keyIterator
509         = env->CallObjectMethod(drmInfoRequest,
510                 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
511 
512     jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
513 
514     while (env->CallBooleanMethod(keyIterator, hasNextId)) {
515         jstring key
516             = (jstring) env->CallObjectMethod(keyIterator,
517                 env->GetMethodID(env->FindClass("java/util/Iterator"),
518                                 "next", "()Ljava/lang/Object;"));
519 
520         jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
521                 env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
522 
523         String8 keyString = Utility::getStringValue(env, key);
524         String8 valueString = Utility::getStringValue(env, value);
525         ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
526 
527         drmInfoReq.put(keyString, valueString);
528     }
529 
530     DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq);
531 
532     jobject drmInfoObject = NULL;
533 
534     if (NULL != pDrmInfo) {
535         jclass localRef = env->FindClass("android/drm/DrmInfo");
536 
537         if (NULL != localRef) {
538             int length = pDrmInfo->getData().length;
539 
540             jbyteArray dataArray = env->NewByteArray(length);
541             env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data);
542 
543             drmInfoObject
544                 = env->NewObject(localRef,
545                     env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"),
546                     mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string()));
547 
548             DrmInfo::KeyIterator it = pDrmInfo->keyIterator();
549             jmethodID putMethodId
550                 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V");
551 
552             while (it.hasNext()) {
553                 String8 key = it.next();
554                 String8 value = pDrmInfo->get(key);
555 
556                 env->CallVoidMethod(drmInfoObject, putMethodId,
557                     env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
558             }
559         }
560         delete [] pDrmInfo->getData().data;
561     }
562 
563     delete pDrmInfo; pDrmInfo = NULL;
564 
565     ALOGV("acquireDrmInfo Exit");
566     return drmInfoObject;
567 }
568 
android_drm_DrmManagerClient_getDrmObjectType(JNIEnv * env,jobject thiz,jint uniqueId,jstring path,jstring mimeType)569 static jint android_drm_DrmManagerClient_getDrmObjectType(
570             JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) {
571     ALOGV("getDrmObjectType Enter");
572     int drmObjectType
573         = getDrmManagerClientImpl(env, thiz)
574             ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path),
575                                 Utility::getStringValue(env, mimeType));
576     ALOGV("getDrmObjectType Exit");
577     return drmObjectType;
578 }
579 
android_drm_DrmManagerClient_getOriginalMimeType(JNIEnv * env,jobject thiz,jint uniqueId,jstring path)580 static jstring android_drm_DrmManagerClient_getOriginalMimeType(
581             JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
582     ALOGV("getOriginalMimeType Enter");
583     String8 mimeType
584         = getDrmManagerClientImpl(env, thiz)
585             ->getOriginalMimeType(uniqueId, Utility::getStringValue(env, path));
586     ALOGV("getOriginalMimeType Exit");
587     return env->NewStringUTF(mimeType.string());
588 }
589 
android_drm_DrmManagerClient_checkRightsStatus(JNIEnv * env,jobject thiz,jint uniqueId,jstring path,int action)590 static jint android_drm_DrmManagerClient_checkRightsStatus(
591             JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) {
592     ALOGV("getOriginalMimeType Enter");
593     int rightsStatus
594         = getDrmManagerClientImpl(env, thiz)
595             ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action);
596     ALOGV("getOriginalMimeType Exit");
597     return rightsStatus;
598 }
599 
android_drm_DrmManagerClient_removeRights(JNIEnv * env,jobject thiz,jint uniqueId,jstring path)600 static jint android_drm_DrmManagerClient_removeRights(
601             JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
602     ALOGV("removeRights");
603     return getDrmManagerClientImpl(env, thiz)
604                ->removeRights(uniqueId, Utility::getStringValue(env, path));
605 }
606 
android_drm_DrmManagerClient_removeAllRights(JNIEnv * env,jobject thiz,jint uniqueId)607 static jint android_drm_DrmManagerClient_removeAllRights(
608             JNIEnv* env, jobject thiz, jint uniqueId) {
609     ALOGV("removeAllRights");
610     return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
611 }
612 
android_drm_DrmManagerClient_openConvertSession(JNIEnv * env,jobject thiz,jint uniqueId,jstring mimeType)613 static jint android_drm_DrmManagerClient_openConvertSession(
614             JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) {
615     ALOGV("openConvertSession Enter");
616     int convertId
617         = getDrmManagerClientImpl(env, thiz)
618             ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType));
619     ALOGV("openConvertSession Exit");
620     return convertId;
621 }
622 
GetConvertedStatus(JNIEnv * env,DrmConvertedStatus * pDrmConvertedStatus)623 static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) {
624     ALOGV("GetConvertedStatus - Enter");
625     jclass localRef = env->FindClass("android/drm/DrmConvertedStatus");
626 
627     jobject drmConvertedStatus = NULL;
628 
629     if (NULL != localRef && NULL != pDrmConvertedStatus) {
630         int statusCode = pDrmConvertedStatus->statusCode;
631 
632         jbyteArray dataArray = NULL;
633         if (NULL != pDrmConvertedStatus->convertedData) {
634             int length = pDrmConvertedStatus->convertedData->length;
635             dataArray = env->NewByteArray(length);
636             env->SetByteArrayRegion(
637                 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data);
638 
639             delete [] pDrmConvertedStatus->convertedData->data;
640             delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL;
641         }
642         jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V");
643         drmConvertedStatus
644             = env->NewObject(localRef, constructorId,
645                              statusCode, dataArray, pDrmConvertedStatus->offset);
646     }
647 
648     delete pDrmConvertedStatus; pDrmConvertedStatus = NULL;
649 
650     ALOGV("GetConvertedStatus - Exit");
651     return drmConvertedStatus;
652 }
653 
android_drm_DrmManagerClient_convertData(JNIEnv * env,jobject thiz,jint uniqueId,jint convertId,jbyteArray inputData)654 static jobject android_drm_DrmManagerClient_convertData(
655             JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) {
656     ALOGV("convertData Enter");
657 
658     int dataLength = 0;
659     char* mData = Utility::getByteArrayValue(env, inputData, &dataLength);
660     const DrmBuffer buffer(mData, dataLength);
661 
662     DrmConvertedStatus* pDrmConvertedStatus
663             = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer);
664     jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
665 
666     delete[] mData;
667     mData = NULL;
668 
669     ALOGV("convertData - Exit");
670     return status;
671 }
672 
android_drm_DrmManagerClient_closeConvertSession(JNIEnv * env,jobject thiz,int uniqueId,jint convertId)673 static jobject android_drm_DrmManagerClient_closeConvertSession(
674             JNIEnv* env, jobject thiz, int uniqueId, jint convertId) {
675 
676     ALOGV("closeConvertSession Enter");
677 
678     DrmConvertedStatus* pDrmConvertedStatus
679                 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId);
680     jobject status = GetConvertedStatus(env, pDrmConvertedStatus);
681 
682     ALOGV("closeConvertSession - Exit");
683     return status;
684 }
685 
686 static JNINativeMethod nativeMethods[] = {
687 
688     {"_initialize", "()I",
689                                     (void*)android_drm_DrmManagerClient_initialize},
690 
691     {"_setListeners", "(ILjava/lang/Object;)V",
692                                     (void*)android_drm_DrmManagerClient_setListeners},
693 
694     {"_release", "(I)V",
695                                     (void*)android_drm_DrmManagerClient_release},
696 
697     {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
698                                     (void*)android_drm_DrmManagerClient_getConstraintsFromContent},
699 
700     {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;",
701                                     (void*)android_drm_DrmManagerClient_getMetadataFromContent},
702 
703     {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;",
704                                     (void*)android_drm_DrmManagerClient_getAllSupportInfo},
705 
706     {"_installDrmEngine", "(ILjava/lang/String;)V",
707                                     (void*)android_drm_DrmManagerClient_installDrmEngine},
708 
709     {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z",
710                                     (void*)android_drm_DrmManagerClient_canHandle},
711 
712     {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;",
713                                     (void*)android_drm_DrmManagerClient_processDrmInfo},
714 
715     {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
716                                     (void*)android_drm_DrmManagerClient_acquireDrmInfo},
717 
718     {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
719                                     (void*)android_drm_DrmManagerClient_saveRights},
720 
721     {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
722                                     (void*)android_drm_DrmManagerClient_getDrmObjectType},
723 
724     {"_getOriginalMimeType", "(ILjava/lang/String;)Ljava/lang/String;",
725                                     (void*)android_drm_DrmManagerClient_getOriginalMimeType},
726 
727     {"_checkRightsStatus", "(ILjava/lang/String;I)I",
728                                     (void*)android_drm_DrmManagerClient_checkRightsStatus},
729 
730     {"_removeRights", "(ILjava/lang/String;)I",
731                                     (void*)android_drm_DrmManagerClient_removeRights},
732 
733     {"_removeAllRights", "(I)I",
734                                     (void*)android_drm_DrmManagerClient_removeAllRights},
735 
736     {"_openConvertSession", "(ILjava/lang/String;)I",
737                                     (void*)android_drm_DrmManagerClient_openConvertSession},
738 
739     {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;",
740                                     (void*)android_drm_DrmManagerClient_convertData},
741 
742     {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;",
743                                     (void*)android_drm_DrmManagerClient_closeConvertSession},
744 };
745 
registerNativeMethods(JNIEnv * env)746 static int registerNativeMethods(JNIEnv* env) {
747     int result = -1;
748 
749     /* look up the class */
750     jclass clazz = env->FindClass("android/drm/DrmManagerClient");
751 
752     if (NULL != clazz) {
753         if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods)
754                 / sizeof(nativeMethods[0])) == JNI_OK) {
755             result = 0;
756         }
757     }
758     return result;
759 }
760 
JNI_OnLoad(JavaVM * vm,void * reserved)761 jint JNI_OnLoad(JavaVM* vm, void* reserved) {
762     JNIEnv* env = NULL;
763     jint result = -1;
764 
765     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
766         if (NULL != env && registerNativeMethods(env) == 0) {
767             result = JNI_VERSION_1_4;
768         }
769     }
770     return result;
771 }
772 
773