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 <ScopedLocalRef.h> 24 #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> 33 #include <drm/DrmMetadata.h> 34 #include <drm/DrmConvertedStatus.h> 35 #include <drm/drm_framework_common.h> 36 37 #include <DrmManagerClientImpl.h> 38 39 using 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 */ 45 class Utility { 46 public: 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 60 String8 Utility::getStringValue(JNIEnv* env, jobject object, const char* fieldName) { 61 /* 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); 67 return Utility::getStringValue(env, valueString); 68 } 69 70 String8 dataString(""); 71 return dataString; 72 } 73 74 String8 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 91 char* Utility::getByteArrayValue( 92 JNIEnv* env, jobject object, const char* fieldName, int* dataLength) { 93 94 *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); 100 return Utility::getByteArrayValue(env, byteArray, dataLength); 101 } 102 return NULL; 103 } 104 105 char* 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 119 int Utility::getIntValue(JNIEnv* env, jobject object, const char* fieldName) { 120 jfieldID fieldID; 121 int intValue = -1; 122 123 /* Get a reference to objs 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 135 class JNIOnInfoListener : public DrmManagerClient::OnInfoListener { 136 public: 137 JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz); 138 139 virtual ~JNIOnInfoListener(); 140 void onInfo(const DrmInfoEvent& event); 141 142 private: 143 JNIOnInfoListener(); 144 jclass mClass; 145 jobject mObject; 146 }; 147 148 JNIOnInfoListener::JNIOnInfoListener(JNIEnv* env, jobject thiz, jobject weak_thiz) { 149 jclass clazz = env->GetObjectClass(thiz); 150 151 if (clazz == NULL) { 152 ALOGE("Can't find android/drm/DrmManagerClient"); 153 jniThrowException(env, "java/lang/Exception", NULL); 154 return; 155 } 156 mClass = (jclass)env->NewGlobalRef(clazz); 157 mObject = env->NewGlobalRef(weak_thiz); 158 } 159 160 JNIOnInfoListener::~JNIOnInfoListener() { 161 JNIEnv *env = AndroidRuntime::getJNIEnv(); 162 env->DeleteGlobalRef(mObject); 163 env->DeleteGlobalRef(mClass); 164 } 165 166 void 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()); 171 ALOGV("JNIOnInfoListener::onInfo => %d | %d | %s", uniqueId, type, event.getMessage().string()); 172 173 env->CallStaticVoidMethod( 174 mClass, 175 env->GetStaticMethodID(mClass, "notify", "(Ljava/lang/Object;IILjava/lang/String;)V"), 176 mObject, uniqueId, type, message); 177 } 178 179 static Mutex sLock; 180 181 static 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 198 static 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 207 static jint android_drm_DrmManagerClient_initialize( 208 JNIEnv* env, jobject thiz) { 209 ALOGV("initialize - Enter"); 210 211 int uniqueId = 0; 212 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false); 213 drmManager->addClient(uniqueId); 214 215 setDrmManagerClientImpl(env, thiz, drmManager); 216 ALOGV("initialize - Exit"); 217 return uniqueId; 218 } 219 220 static 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 231 static void android_drm_DrmManagerClient_release( 232 JNIEnv* env, jobject thiz, jint uniqueId) { 233 ALOGV("release - Enter"); 234 DrmManagerClientImpl::remove(uniqueId); 235 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL); 236 237 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL); 238 if (oldClient != NULL) { 239 oldClient->setOnInfoListener(uniqueId, NULL); 240 oldClient->removeClient(uniqueId); 241 } 242 ALOGV("release - Exit"); 243 } 244 245 static jobject android_drm_DrmManagerClient_getConstraintsFromContent( 246 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) { 247 ALOGV("GetConstraints - Enter"); 248 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"); 254 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"); 259 jobject constraints = NULL; 260 261 if (NULL != localRef && NULL != pConstraints) { 262 // create the java DrmConstraints object 263 constraints = env->NewObject(localRef, ContentValues_constructor); 264 265 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator(); 266 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) { 273 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()); 278 } 279 } else { 280 String8 value = pConstraints->get(key); 281 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()); 285 } 286 } 287 } 288 289 delete pConstraints; pConstraints = NULL; 290 ALOGV("GetConstraints - Exit"); 291 return constraints; 292 } 293 294 static jobject android_drm_DrmManagerClient_getMetadataFromContent( 295 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) { 296 ALOGV("GetMetadata - Enter"); 297 const String8 pathString = Utility::getStringValue(env, jpath); 298 DrmMetadata* pMetadata = 299 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString); 300 301 jobject metadata = NULL; 302 303 jclass localRef = env->FindClass("android/content/ContentValues"); 304 jmethodID ContentValues_putString = 305 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"); 306 307 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); 321 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()); 325 } 326 } 327 } 328 } 329 delete pMetadata; pMetadata = NULL; 330 ALOGV("GetMetadata - Exit"); 331 return metadata; 332 } 333 334 static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo( 335 JNIEnv* env, jobject thiz, jint uniqueId) { 336 ALOGV("GetAllSupportInfo - Enter"); 337 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; 377 ALOGV("GetAllSupportInfo - Exit"); 378 return array; 379 } 380 381 static void android_drm_DrmManagerClient_installDrmEngine( 382 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) { 383 ALOGV("installDrmEngine - Enter"); 384 //getDrmManagerClient(env, thiz) 385 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath)); 386 ALOGV("installDrmEngine - Exit"); 387 } 388 389 static jint android_drm_DrmManagerClient_saveRights( 390 JNIEnv* env, jobject thiz, jint uniqueId, 391 jobject drmRights, jstring rightsPath, jstring contentPath) { 392 ALOGV("saveRights - Enter"); 393 int result = DRM_ERROR_UNKNOWN; 394 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")); 402 result = getDrmManagerClientImpl(env, thiz) 403 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath), 404 Utility::getStringValue(env, contentPath)); 405 } 406 407 delete[] mData; mData = NULL; 408 ALOGV("saveRights - Exit"); 409 return result; 410 } 411 412 static jboolean android_drm_DrmManagerClient_canHandle( 413 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) { 414 ALOGV("canHandle - Enter"); 415 jboolean result 416 = getDrmManagerClientImpl(env, thiz) 417 ->canHandle(uniqueId, Utility::getStringValue(env, path), 418 Utility::getStringValue(env, mimeType)); 419 ALOGV("canHandle - Exit"); 420 return result; 421 } 422 423 static jobject android_drm_DrmManagerClient_processDrmInfo( 424 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) { 425 ALOGV("processDrmInfo - Enter"); 426 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"); 435 jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"); 436 jobject keyIterator 437 = env->CallObjectMethod(drmInfoObject, 438 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;")); 439 440 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;"); 443 444 jclass Object_class = env->FindClass("java/lang/Object"); 445 jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;"); 446 447 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)); 455 } 456 457 String8 keyString = Utility::getStringValue(env, key.get()); 458 String8 valueString = Utility::getStringValue(env, valString.get()); 459 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string()); 460 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; 472 int infoType = pDrmInfoStatus->infoType; 473 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, 493 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V"); 494 495 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType, 496 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string())); 497 } 498 499 delete[] mData; mData = NULL; 500 delete pDrmInfoStatus; pDrmInfoStatus = NULL; 501 502 ALOGV("processDrmInfo - Exit"); 503 return drmInfoStatus; 504 } 505 506 static jobject android_drm_DrmManagerClient_acquireDrmInfo( 507 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) { 508 ALOGV("acquireDrmInfo Enter"); 509 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;")); 518 jmethodID DrmInfoRequest_get = env->GetMethodID(clazz, 519 "get", "(Ljava/lang/String;)Ljava/lang/Object;"); 520 521 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;"); 524 525 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())); 530 531 String8 keyString = Utility::getStringValue(env, key.get()); 532 String8 valueString = Utility::getStringValue(env, value.get()); 533 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string()); 534 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); 563 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string())); 564 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string())); 565 env->CallVoidMethod(drmInfoObject, putMethodId, 566 keyString.get(), valueString.get()); 567 } 568 } 569 delete [] pDrmInfo->getData().data; 570 } 571 572 delete pDrmInfo; pDrmInfo = NULL; 573 574 ALOGV("acquireDrmInfo Exit"); 575 return drmInfoObject; 576 } 577 578 static jint android_drm_DrmManagerClient_getDrmObjectType( 579 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) { 580 ALOGV("getDrmObjectType Enter"); 581 int drmObjectType 582 = getDrmManagerClientImpl(env, thiz) 583 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path), 584 Utility::getStringValue(env, mimeType)); 585 ALOGV("getDrmObjectType Exit"); 586 return drmObjectType; 587 } 588 589 static jstring android_drm_DrmManagerClient_getOriginalMimeType( 590 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jobject fileDescriptor) { 591 ALOGV("getOriginalMimeType Enter"); 592 593 int fd = (fileDescriptor == NULL) 594 ? -1 595 : jniGetFDFromFileDescriptor(env, fileDescriptor); 596 597 String8 mimeType 598 = getDrmManagerClientImpl(env, thiz) 599 ->getOriginalMimeType(uniqueId, 600 Utility::getStringValue(env, path), fd); 601 ALOGV("getOriginalMimeType Exit"); 602 return env->NewStringUTF(mimeType.string()); 603 } 604 605 static jint android_drm_DrmManagerClient_checkRightsStatus( 606 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) { 607 ALOGV("checkRightsStatus Enter"); 608 int rightsStatus 609 = getDrmManagerClientImpl(env, thiz) 610 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action); 611 ALOGV("checkRightsStatus Exit"); 612 return rightsStatus; 613 } 614 615 static jint android_drm_DrmManagerClient_removeRights( 616 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) { 617 ALOGV("removeRights"); 618 return getDrmManagerClientImpl(env, thiz) 619 ->removeRights(uniqueId, Utility::getStringValue(env, path)); 620 } 621 622 static jint android_drm_DrmManagerClient_removeAllRights( 623 JNIEnv* env, jobject thiz, jint uniqueId) { 624 ALOGV("removeAllRights"); 625 return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId); 626 } 627 628 static jint android_drm_DrmManagerClient_openConvertSession( 629 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) { 630 ALOGV("openConvertSession Enter"); 631 int convertId 632 = getDrmManagerClientImpl(env, thiz) 633 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType)); 634 ALOGV("openConvertSession Exit"); 635 return convertId; 636 } 637 638 static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) { 639 ALOGV("GetConvertedStatus - Enter"); 640 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 665 ALOGV("GetConvertedStatus - Exit"); 666 return drmConvertedStatus; 667 } 668 669 static 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 688 static 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 701 static JNINativeMethod nativeMethods[] = { 702 703 {"_initialize", "()I", 704 (void*)android_drm_DrmManagerClient_initialize}, 705 706 {"_setListeners", "(ILjava/lang/Object;)V", 707 (void*)android_drm_DrmManagerClient_setListeners}, 708 709 {"_release", "(I)V", 710 (void*)android_drm_DrmManagerClient_release}, 711 712 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;", 713 (void*)android_drm_DrmManagerClient_getConstraintsFromContent}, 714 715 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;", 716 (void*)android_drm_DrmManagerClient_getMetadataFromContent}, 717 718 {"_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 733 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I", 734 (void*)android_drm_DrmManagerClient_saveRights}, 735 736 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I", 737 (void*)android_drm_DrmManagerClient_getDrmObjectType}, 738 739 {"_getOriginalMimeType", "(ILjava/lang/String;Ljava/io/FileDescriptor;)Ljava/lang/String;", 740 (void*)android_drm_DrmManagerClient_getOriginalMimeType}, 741 742 {"_checkRightsStatus", "(ILjava/lang/String;I)I", 743 (void*)android_drm_DrmManagerClient_checkRightsStatus}, 744 745 {"_removeRights", "(ILjava/lang/String;)I", 746 (void*)android_drm_DrmManagerClient_removeRights}, 747 748 {"_removeAllRights", "(I)I", 749 (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 761 static 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 776 jint 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 788