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", "J"); 186 187 jlong oldHandle = env->GetLongField(thiz, fieldId); 188 sp<DrmManagerClientImpl> old = reinterpret_cast<DrmManagerClientImpl*>(oldHandle); 189 if (client.get()) { 190 client->incStrong(thiz); 191 } 192 if (old != 0) { 193 old->decStrong(thiz); 194 } 195 env->SetLongField(thiz, fieldId, reinterpret_cast<jlong>(client.get())); 196 return old; 197 } 198 199 static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) { 200 Mutex::Autolock l(sLock); 201 jclass clazz = env->FindClass("android/drm/DrmManagerClient"); 202 jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J"); 203 204 jlong clientHandle = env->GetLongField(thiz, fieldId); 205 DrmManagerClientImpl* const client = reinterpret_cast<DrmManagerClientImpl*>(clientHandle); 206 return sp<DrmManagerClientImpl>(client); 207 } 208 209 static jint android_drm_DrmManagerClient_initialize( 210 JNIEnv* env, jobject thiz) { 211 ALOGV("initialize - Enter"); 212 213 int uniqueId = 0; 214 sp<DrmManagerClientImpl> drmManager = DrmManagerClientImpl::create(&uniqueId, false); 215 drmManager->addClient(uniqueId); 216 217 setDrmManagerClientImpl(env, thiz, drmManager); 218 ALOGV("initialize - Exit"); 219 return static_cast<jint>(uniqueId); 220 } 221 222 static 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 233 static void android_drm_DrmManagerClient_release( 234 JNIEnv* env, jobject thiz, jint uniqueId) { 235 ALOGV("release - Enter"); 236 getDrmManagerClientImpl(env, thiz)->remove(uniqueId); 237 getDrmManagerClientImpl(env, thiz)->setOnInfoListener(uniqueId, NULL); 238 239 sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL); 240 if (oldClient != NULL) { 241 oldClient->setOnInfoListener(uniqueId, NULL); 242 oldClient->removeClient(uniqueId); 243 } 244 ALOGV("release - Exit"); 245 } 246 247 static jobject android_drm_DrmManagerClient_getConstraintsFromContent( 248 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath, jint usage) { 249 ALOGV("GetConstraints - Enter"); 250 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"); 256 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"); 261 jobject constraints = NULL; 262 263 if (NULL != localRef && NULL != pConstraints) { 264 // create the java DrmConstraints object 265 constraints = env->NewObject(localRef, ContentValues_constructor); 266 267 DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator(); 268 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) { 275 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()); 280 } 281 } else { 282 String8 value = pConstraints->get(key); 283 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()); 287 } 288 } 289 } 290 291 delete pConstraints; pConstraints = NULL; 292 ALOGV("GetConstraints - Exit"); 293 return constraints; 294 } 295 296 static jobject android_drm_DrmManagerClient_getMetadataFromContent( 297 JNIEnv* env, jobject thiz, jint uniqueId, jstring jpath) { 298 ALOGV("GetMetadata - Enter"); 299 const String8 pathString = Utility::getStringValue(env, jpath); 300 DrmMetadata* pMetadata = 301 getDrmManagerClientImpl(env, thiz)->getMetadata(uniqueId, &pathString); 302 303 jobject metadata = NULL; 304 305 jclass localRef = env->FindClass("android/content/ContentValues"); 306 jmethodID ContentValues_putString = 307 env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"); 308 309 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); 323 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()); 327 } 328 } 329 } 330 } 331 delete pMetadata; pMetadata = NULL; 332 ALOGV("GetMetadata - Exit"); 333 return metadata; 334 } 335 336 static jobjectArray android_drm_DrmManagerClient_getAllSupportInfo( 337 JNIEnv* env, jobject thiz, jint uniqueId) { 338 ALOGV("GetAllSupportInfo - Enter"); 339 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; 379 ALOGV("GetAllSupportInfo - Exit"); 380 return array; 381 } 382 383 static void android_drm_DrmManagerClient_installDrmEngine( 384 JNIEnv* env, jobject thiz, jint uniqueId, jstring engineFilePath) { 385 ALOGV("installDrmEngine - Enter"); 386 //getDrmManagerClient(env, thiz) 387 // ->installDrmEngine(uniqueId, Utility::getStringValue(env, engineFilePath)); 388 ALOGV("installDrmEngine - Exit"); 389 } 390 391 static jint android_drm_DrmManagerClient_saveRights( 392 JNIEnv* env, jobject thiz, jint uniqueId, 393 jobject drmRights, jstring rightsPath, jstring contentPath) { 394 ALOGV("saveRights - Enter"); 395 int result = DRM_ERROR_UNKNOWN; 396 int dataLength = 0; 397 char* mData = Utility::getByteArrayValue(env, drmRights, "mData", &dataLength); 398 399 if (NULL != mData) { 400 DrmRights rights(DrmBuffer(mData, dataLength), 401 Utility::getStringValue(env, drmRights, "mMimeType"), 402 Utility::getStringValue(env, drmRights, "mAccountId"), 403 Utility::getStringValue(env, drmRights, "mSubscriptionId")); 404 result = getDrmManagerClientImpl(env, thiz) 405 ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath), 406 Utility::getStringValue(env, contentPath)); 407 } 408 409 delete[] mData; mData = NULL; 410 ALOGV("saveRights - Exit"); 411 return static_cast<jint>(result); 412 } 413 414 static jboolean android_drm_DrmManagerClient_canHandle( 415 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) { 416 ALOGV("canHandle - Enter"); 417 jboolean result 418 = getDrmManagerClientImpl(env, thiz) 419 ->canHandle(uniqueId, Utility::getStringValue(env, path), 420 Utility::getStringValue(env, mimeType)); 421 ALOGV("canHandle - Exit"); 422 return result; 423 } 424 425 static jobject android_drm_DrmManagerClient_processDrmInfo( 426 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoObject) { 427 ALOGV("processDrmInfo - Enter"); 428 int dataLength = 0; 429 const String8 mMimeType = Utility::getStringValue(env, drmInfoObject, "mMimeType"); 430 char* mData = Utility::getByteArrayValue(env, drmInfoObject, "mData", &dataLength); 431 int mInfoType = Utility::getIntValue(env, drmInfoObject, "mInfoType"); 432 433 const DrmBuffer buffer(mData, dataLength); 434 DrmInfo drmInfo(mInfoType, buffer, mMimeType); 435 436 jclass clazz = env->FindClass("android/drm/DrmInfo"); 437 jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"); 438 jobject keyIterator 439 = env->CallObjectMethod(drmInfoObject, 440 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;")); 441 442 jclass Iterator_class = env->FindClass("java/util/Iterator"); 443 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z"); 444 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;"); 445 446 jclass Object_class = env->FindClass("java/lang/Object"); 447 jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;"); 448 449 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) { 450 ScopedLocalRef<jstring> key(env, 451 (jstring) env->CallObjectMethod(keyIterator, Iterator_next)); 452 ScopedLocalRef<jobject> valueObject(env, 453 env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get())); 454 ScopedLocalRef<jstring> valString(env, NULL); 455 if (NULL != valueObject.get()) { 456 valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString)); 457 } 458 459 String8 keyString = Utility::getStringValue(env, key.get()); 460 String8 valueString = Utility::getStringValue(env, valString.get()); 461 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string()); 462 463 drmInfo.put(keyString, valueString); 464 } 465 466 DrmInfoStatus* pDrmInfoStatus 467 = getDrmManagerClientImpl(env, thiz)->processDrmInfo(uniqueId, &drmInfo); 468 469 jclass localRef = env->FindClass("android/drm/DrmInfoStatus"); 470 jobject drmInfoStatus = NULL; 471 472 if (NULL != localRef && NULL != pDrmInfoStatus) { 473 int statusCode = pDrmInfoStatus->statusCode; 474 int infoType = pDrmInfoStatus->infoType; 475 476 jbyteArray dataArray = NULL; 477 if (NULL != pDrmInfoStatus->drmBuffer) { 478 int length = pDrmInfoStatus->drmBuffer->length; 479 dataArray = env->NewByteArray(length); 480 env->SetByteArrayRegion( 481 dataArray, 0, length, (jbyte*) pDrmInfoStatus->drmBuffer->data); 482 483 delete [] pDrmInfoStatus->drmBuffer->data; 484 delete pDrmInfoStatus->drmBuffer; pDrmInfoStatus->drmBuffer = NULL; 485 } 486 jclass clazz = env->FindClass("android/drm/ProcessedData"); 487 jmethodID constructorId 488 = env->GetMethodID(clazz, "<init>", "([BLjava/lang/String;Ljava/lang/String;)V"); 489 jobject processedData = env->NewObject(clazz, constructorId, dataArray, 490 env->NewStringUTF((drmInfo.get(DrmInfoRequest::ACCOUNT_ID)).string()), 491 env->NewStringUTF((drmInfo.get(DrmInfoRequest::SUBSCRIPTION_ID)).string())); 492 493 constructorId 494 = env->GetMethodID(localRef, 495 "<init>", "(IILandroid/drm/ProcessedData;Ljava/lang/String;)V"); 496 497 drmInfoStatus = env->NewObject(localRef, constructorId, statusCode, infoType, 498 processedData, env->NewStringUTF(pDrmInfoStatus->mimeType.string())); 499 } 500 501 delete[] mData; mData = NULL; 502 delete pDrmInfoStatus; pDrmInfoStatus = NULL; 503 504 ALOGV("processDrmInfo - Exit"); 505 return drmInfoStatus; 506 } 507 508 static jobject android_drm_DrmManagerClient_acquireDrmInfo( 509 JNIEnv* env, jobject thiz, jint uniqueId, jobject drmInfoRequest) { 510 ALOGV("acquireDrmInfo Enter"); 511 const String8 mMimeType = Utility::getStringValue(env, drmInfoRequest, "mMimeType"); 512 int mInfoType = Utility::getIntValue(env, drmInfoRequest, "mInfoType"); 513 514 DrmInfoRequest drmInfoReq(mInfoType, mMimeType); 515 516 jclass clazz = env->FindClass("android/drm/DrmInfoRequest"); 517 jobject keyIterator 518 = env->CallObjectMethod(drmInfoRequest, 519 env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;")); 520 jmethodID DrmInfoRequest_get = env->GetMethodID(clazz, 521 "get", "(Ljava/lang/String;)Ljava/lang/Object;"); 522 523 jclass Iterator_class = env->FindClass("java/util/Iterator"); 524 jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z"); 525 jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;"); 526 527 while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) { 528 ScopedLocalRef<jstring> key(env, 529 (jstring) env->CallObjectMethod(keyIterator, Iterator_next)); 530 ScopedLocalRef<jstring> value(env, 531 (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get())); 532 533 String8 keyString = Utility::getStringValue(env, key.get()); 534 String8 valueString = Utility::getStringValue(env, value.get()); 535 ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string()); 536 537 drmInfoReq.put(keyString, valueString); 538 } 539 540 DrmInfo* pDrmInfo = getDrmManagerClientImpl(env, thiz)->acquireDrmInfo(uniqueId, &drmInfoReq); 541 542 jobject drmInfoObject = NULL; 543 544 if (NULL != pDrmInfo) { 545 jclass localRef = env->FindClass("android/drm/DrmInfo"); 546 547 if (NULL != localRef) { 548 int length = pDrmInfo->getData().length; 549 550 jbyteArray dataArray = env->NewByteArray(length); 551 env->SetByteArrayRegion(dataArray, 0, length, (jbyte*)pDrmInfo->getData().data); 552 553 drmInfoObject 554 = env->NewObject(localRef, 555 env->GetMethodID(localRef, "<init>", "(I[BLjava/lang/String;)V"), 556 mInfoType, dataArray, env->NewStringUTF(pDrmInfo->getMimeType().string())); 557 558 DrmInfo::KeyIterator it = pDrmInfo->keyIterator(); 559 jmethodID putMethodId 560 = env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/Object;)V"); 561 562 while (it.hasNext()) { 563 String8 key = it.next(); 564 String8 value = pDrmInfo->get(key); 565 ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string())); 566 ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string())); 567 env->CallVoidMethod(drmInfoObject, putMethodId, 568 keyString.get(), valueString.get()); 569 } 570 } 571 delete [] pDrmInfo->getData().data; 572 } 573 574 delete pDrmInfo; pDrmInfo = NULL; 575 576 ALOGV("acquireDrmInfo Exit"); 577 return drmInfoObject; 578 } 579 580 static jint android_drm_DrmManagerClient_getDrmObjectType( 581 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jstring mimeType) { 582 ALOGV("getDrmObjectType Enter"); 583 int drmObjectType 584 = getDrmManagerClientImpl(env, thiz) 585 ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path), 586 Utility::getStringValue(env, mimeType)); 587 ALOGV("getDrmObjectType Exit"); 588 return static_cast<jint>(drmObjectType); 589 } 590 591 static jstring android_drm_DrmManagerClient_getOriginalMimeType( 592 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, jobject fileDescriptor) { 593 ALOGV("getOriginalMimeType Enter"); 594 595 int fd = (fileDescriptor == NULL) 596 ? -1 597 : jniGetFDFromFileDescriptor(env, fileDescriptor); 598 599 String8 mimeType 600 = getDrmManagerClientImpl(env, thiz) 601 ->getOriginalMimeType(uniqueId, 602 Utility::getStringValue(env, path), fd); 603 ALOGV("getOriginalMimeType Exit"); 604 return env->NewStringUTF(mimeType.string()); 605 } 606 607 static jint android_drm_DrmManagerClient_checkRightsStatus( 608 JNIEnv* env, jobject thiz, jint uniqueId, jstring path, int action) { 609 ALOGV("checkRightsStatus Enter"); 610 int rightsStatus 611 = getDrmManagerClientImpl(env, thiz) 612 ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action); 613 ALOGV("checkRightsStatus Exit"); 614 return static_cast<jint>(rightsStatus); 615 } 616 617 static jint android_drm_DrmManagerClient_removeRights( 618 JNIEnv* env, jobject thiz, jint uniqueId, jstring path) { 619 ALOGV("removeRights"); 620 return static_cast<jint>(getDrmManagerClientImpl(env, thiz) 621 ->removeRights(uniqueId, Utility::getStringValue(env, path))); 622 } 623 624 static jint android_drm_DrmManagerClient_removeAllRights( 625 JNIEnv* env, jobject thiz, jint uniqueId) { 626 ALOGV("removeAllRights"); 627 return static_cast<jint>(getDrmManagerClientImpl(env, thiz) 628 ->removeAllRights(uniqueId)); 629 } 630 631 static jint android_drm_DrmManagerClient_openConvertSession( 632 JNIEnv* env, jobject thiz, jint uniqueId, jstring mimeType) { 633 ALOGV("openConvertSession Enter"); 634 int convertId 635 = getDrmManagerClientImpl(env, thiz) 636 ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType)); 637 ALOGV("openConvertSession Exit"); 638 return static_cast<jint>(convertId); 639 } 640 641 static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) { 642 ALOGV("GetConvertedStatus - Enter"); 643 jclass localRef = env->FindClass("android/drm/DrmConvertedStatus"); 644 645 jobject drmConvertedStatus = NULL; 646 647 if (NULL != localRef && NULL != pDrmConvertedStatus) { 648 int statusCode = pDrmConvertedStatus->statusCode; 649 650 jbyteArray dataArray = NULL; 651 if (NULL != pDrmConvertedStatus->convertedData) { 652 int length = pDrmConvertedStatus->convertedData->length; 653 dataArray = env->NewByteArray(length); 654 env->SetByteArrayRegion( 655 dataArray, 0, length, (jbyte*) pDrmConvertedStatus->convertedData->data); 656 657 delete [] pDrmConvertedStatus->convertedData->data; 658 delete pDrmConvertedStatus->convertedData; pDrmConvertedStatus->convertedData = NULL; 659 } 660 jmethodID constructorId = env->GetMethodID(localRef, "<init>", "(I[BI)V"); 661 drmConvertedStatus 662 = env->NewObject(localRef, constructorId, 663 statusCode, dataArray, pDrmConvertedStatus->offset); 664 } 665 666 delete pDrmConvertedStatus; pDrmConvertedStatus = NULL; 667 668 ALOGV("GetConvertedStatus - Exit"); 669 return drmConvertedStatus; 670 } 671 672 static jobject android_drm_DrmManagerClient_convertData( 673 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId, jbyteArray inputData) { 674 ALOGV("convertData Enter"); 675 676 int dataLength = 0; 677 char* mData = Utility::getByteArrayValue(env, inputData, &dataLength); 678 const DrmBuffer buffer(mData, dataLength); 679 680 DrmConvertedStatus* pDrmConvertedStatus 681 = getDrmManagerClientImpl(env, thiz)->convertData(uniqueId, convertId, &buffer); 682 jobject status = GetConvertedStatus(env, pDrmConvertedStatus); 683 684 delete[] mData; 685 mData = NULL; 686 687 ALOGV("convertData - Exit"); 688 return status; 689 } 690 691 static jobject android_drm_DrmManagerClient_closeConvertSession( 692 JNIEnv* env, jobject thiz, jint uniqueId, jint convertId) { 693 694 ALOGV("closeConvertSession Enter"); 695 696 DrmConvertedStatus* pDrmConvertedStatus 697 = getDrmManagerClientImpl(env, thiz)->closeConvertSession(uniqueId, convertId); 698 jobject status = GetConvertedStatus(env, pDrmConvertedStatus); 699 700 ALOGV("closeConvertSession - Exit"); 701 return status; 702 } 703 704 static JNINativeMethod nativeMethods[] = { 705 706 {"_initialize", "()I", 707 (void*)android_drm_DrmManagerClient_initialize}, 708 709 {"_setListeners", "(ILjava/lang/Object;)V", 710 (void*)android_drm_DrmManagerClient_setListeners}, 711 712 {"_release", "(I)V", 713 (void*)android_drm_DrmManagerClient_release}, 714 715 {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;", 716 (void*)android_drm_DrmManagerClient_getConstraintsFromContent}, 717 718 {"_getMetadata", "(ILjava/lang/String;)Landroid/content/ContentValues;", 719 (void*)android_drm_DrmManagerClient_getMetadataFromContent}, 720 721 {"_getAllSupportInfo", "(I)[Landroid/drm/DrmSupportInfo;", 722 (void*)android_drm_DrmManagerClient_getAllSupportInfo}, 723 724 {"_installDrmEngine", "(ILjava/lang/String;)V", 725 (void*)android_drm_DrmManagerClient_installDrmEngine}, 726 727 {"_canHandle", "(ILjava/lang/String;Ljava/lang/String;)Z", 728 (void*)android_drm_DrmManagerClient_canHandle}, 729 730 {"_processDrmInfo", "(ILandroid/drm/DrmInfo;)Landroid/drm/DrmInfoStatus;", 731 (void*)android_drm_DrmManagerClient_processDrmInfo}, 732 733 {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;", 734 (void*)android_drm_DrmManagerClient_acquireDrmInfo}, 735 736 {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I", 737 (void*)android_drm_DrmManagerClient_saveRights}, 738 739 {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I", 740 (void*)android_drm_DrmManagerClient_getDrmObjectType}, 741 742 {"_getOriginalMimeType", "(ILjava/lang/String;Ljava/io/FileDescriptor;)Ljava/lang/String;", 743 (void*)android_drm_DrmManagerClient_getOriginalMimeType}, 744 745 {"_checkRightsStatus", "(ILjava/lang/String;I)I", 746 (void*)android_drm_DrmManagerClient_checkRightsStatus}, 747 748 {"_removeRights", "(ILjava/lang/String;)I", 749 (void*)android_drm_DrmManagerClient_removeRights}, 750 751 {"_removeAllRights", "(I)I", 752 (void*)android_drm_DrmManagerClient_removeAllRights}, 753 754 {"_openConvertSession", "(ILjava/lang/String;)I", 755 (void*)android_drm_DrmManagerClient_openConvertSession}, 756 757 {"_convertData", "(II[B)Landroid/drm/DrmConvertedStatus;", 758 (void*)android_drm_DrmManagerClient_convertData}, 759 760 {"_closeConvertSession", "(II)Landroid/drm/DrmConvertedStatus;", 761 (void*)android_drm_DrmManagerClient_closeConvertSession}, 762 }; 763 764 static int registerNativeMethods(JNIEnv* env) { 765 int result = -1; 766 767 /* look up the class */ 768 jclass clazz = env->FindClass("android/drm/DrmManagerClient"); 769 770 if (NULL != clazz) { 771 if (env->RegisterNatives(clazz, nativeMethods, sizeof(nativeMethods) 772 / sizeof(nativeMethods[0])) == JNI_OK) { 773 result = 0; 774 } 775 } 776 return result; 777 } 778 779 jint JNI_OnLoad(JavaVM* vm, void* reserved) { 780 JNIEnv* env = NULL; 781 jint result = -1; 782 783 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) { 784 if (NULL != env && registerNativeMethods(env) == 0) { 785 result = JNI_VERSION_1_4; 786 } 787 } 788 return result; 789 } 790 791