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