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