1 /* 2 * Copyright (C) 2017 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 "DrmHal" 19 #include <iomanip> 20 21 #include <utils/Log.h> 22 23 #include <binder/IPCThreadState.h> 24 #include <binder/IServiceManager.h> 25 26 #include <android/hardware/drm/1.2/types.h> 27 #include <android/hidl/manager/1.2/IServiceManager.h> 28 #include <hidl/ServiceManagement.h> 29 30 #include <media/EventMetric.h> 31 #include <media/PluginMetricsReporting.h> 32 #include <media/drm/DrmAPI.h> 33 #include <media/stagefright/foundation/ADebug.h> 34 #include <media/stagefright/foundation/AString.h> 35 #include <media/stagefright/foundation/base64.h> 36 #include <media/stagefright/foundation/hexdump.h> 37 #include <media/stagefright/MediaErrors.h> 38 #include <mediadrm/DrmHal.h> 39 #include <mediadrm/DrmSessionClientInterface.h> 40 #include <mediadrm/DrmSessionManager.h> 41 42 using drm::V1_0::KeyedVector; 43 using drm::V1_0::KeyRequestType; 44 using drm::V1_0::KeyType; 45 using drm::V1_0::KeyValue; 46 using drm::V1_0::SecureStop; 47 using drm::V1_0::SecureStopId; 48 using drm::V1_0::Status; 49 using drm::V1_1::HdcpLevel; 50 using drm::V1_1::SecureStopRelease; 51 using drm::V1_1::SecurityLevel; 52 using drm::V1_2::KeySetId; 53 using drm::V1_2::KeyStatusType; 54 using ::android::hardware::drm::V1_1::DrmMetricGroup; 55 using ::android::hardware::hidl_array; 56 using ::android::hardware::hidl_string; 57 using ::android::hardware::hidl_vec; 58 using ::android::hardware::Return; 59 using ::android::hardware::Void; 60 using ::android::hidl::manager::V1_0::IServiceManager; 61 using ::android::os::PersistableBundle; 62 using ::android::sp; 63 64 typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1; 65 typedef drm::V1_2::Status Status_V1_2; 66 typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2; 67 68 namespace { 69 70 // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant 71 // in the MediaDrm API. 72 constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId"; 73 constexpr char kEqualsSign[] = "="; 74 75 template<typename T> 76 std::string toBase64StringNoPad(const T* data, size_t size) { 77 // Note that the base 64 conversion only works with arrays of single-byte 78 // values. If the source is empty or is not an array of single-byte values, 79 // return empty string. 80 if (size == 0 || sizeof(data[0]) != 1) { 81 return ""; 82 } 83 84 android::AString outputString; 85 encodeBase64(data, size, &outputString); 86 // Remove trailing equals padding if it exists. 87 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) { 88 outputString.erase(outputString.size() - 1, 1); 89 } 90 91 return std::string(outputString.c_str(), outputString.size()); 92 } 93 94 } // anonymous namespace 95 96 namespace android { 97 98 #define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;} 99 100 static inline int getCallingPid() { 101 return IPCThreadState::self()->getCallingPid(); 102 } 103 104 static bool checkPermission(const char* permissionString) { 105 if (getpid() == IPCThreadState::self()->getCallingPid()) return true; 106 bool ok = checkCallingPermission(String16(permissionString)); 107 if (!ok) ALOGE("Request requires %s", permissionString); 108 return ok; 109 } 110 111 static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) { 112 Vector<uint8_t> vector; 113 vector.appendArray(vec.data(), vec.size()); 114 return *const_cast<const Vector<uint8_t> *>(&vector); 115 } 116 117 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) { 118 hidl_vec<uint8_t> vec; 119 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size()); 120 return vec; 121 } 122 123 static String8 toString8(const hidl_string &string) { 124 return String8(string.c_str()); 125 } 126 127 static hidl_string toHidlString(const String8& string) { 128 return hidl_string(string.string()); 129 } 130 131 static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) { 132 switch(level) { 133 case SecurityLevel::SW_SECURE_CRYPTO: 134 return DrmPlugin::kSecurityLevelSwSecureCrypto; 135 case SecurityLevel::SW_SECURE_DECODE: 136 return DrmPlugin::kSecurityLevelSwSecureDecode; 137 case SecurityLevel::HW_SECURE_CRYPTO: 138 return DrmPlugin::kSecurityLevelHwSecureCrypto; 139 case SecurityLevel::HW_SECURE_DECODE: 140 return DrmPlugin::kSecurityLevelHwSecureDecode; 141 case SecurityLevel::HW_SECURE_ALL: 142 return DrmPlugin::kSecurityLevelHwSecureAll; 143 default: 144 return DrmPlugin::kSecurityLevelUnknown; 145 } 146 } 147 148 static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) { 149 switch(level) { 150 case DrmPlugin::kSecurityLevelSwSecureCrypto: 151 return SecurityLevel::SW_SECURE_CRYPTO; 152 case DrmPlugin::kSecurityLevelSwSecureDecode: 153 return SecurityLevel::SW_SECURE_DECODE; 154 case DrmPlugin::kSecurityLevelHwSecureCrypto: 155 return SecurityLevel::HW_SECURE_CRYPTO; 156 case DrmPlugin::kSecurityLevelHwSecureDecode: 157 return SecurityLevel::HW_SECURE_DECODE; 158 case DrmPlugin::kSecurityLevelHwSecureAll: 159 return SecurityLevel::HW_SECURE_ALL; 160 default: 161 return SecurityLevel::UNKNOWN; 162 } 163 } 164 165 static DrmPlugin::OfflineLicenseState toOfflineLicenseState( 166 OfflineLicenseState licenseState) { 167 switch(licenseState) { 168 case OfflineLicenseState::USABLE: 169 return DrmPlugin::kOfflineLicenseStateUsable; 170 case OfflineLicenseState::INACTIVE: 171 return DrmPlugin::kOfflineLicenseStateReleased; 172 default: 173 return DrmPlugin::kOfflineLicenseStateUnknown; 174 } 175 } 176 177 static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) { 178 switch(level) { 179 case HdcpLevel_V1_2::HDCP_NONE: 180 return DrmPlugin::kHdcpNone; 181 case HdcpLevel_V1_2::HDCP_V1: 182 return DrmPlugin::kHdcpV1; 183 case HdcpLevel_V1_2::HDCP_V2: 184 return DrmPlugin::kHdcpV2; 185 case HdcpLevel_V1_2::HDCP_V2_1: 186 return DrmPlugin::kHdcpV2_1; 187 case HdcpLevel_V1_2::HDCP_V2_2: 188 return DrmPlugin::kHdcpV2_2; 189 case HdcpLevel_V1_2::HDCP_V2_3: 190 return DrmPlugin::kHdcpV2_3; 191 case HdcpLevel_V1_2::HDCP_NO_OUTPUT: 192 return DrmPlugin::kHdcpNoOutput; 193 default: 194 return DrmPlugin::kHdcpLevelUnknown; 195 } 196 } 197 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>& 198 keyedVector) { 199 std::vector<KeyValue> stdKeyedVector; 200 for (size_t i = 0; i < keyedVector.size(); i++) { 201 KeyValue keyValue; 202 keyValue.key = toHidlString(keyedVector.keyAt(i)); 203 keyValue.value = toHidlString(keyedVector.valueAt(i)); 204 stdKeyedVector.push_back(keyValue); 205 } 206 return ::KeyedVector(stdKeyedVector); 207 } 208 209 static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector& 210 hKeyedVector) { 211 KeyedVector<String8, String8> keyedVector; 212 for (size_t i = 0; i < hKeyedVector.size(); i++) { 213 keyedVector.add(toString8(hKeyedVector[i].key), 214 toString8(hKeyedVector[i].value)); 215 } 216 return keyedVector; 217 } 218 219 static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>& 220 hSecureStops) { 221 List<Vector<uint8_t>> secureStops; 222 for (size_t i = 0; i < hSecureStops.size(); i++) { 223 secureStops.push_back(toVector(hSecureStops[i].opaqueData)); 224 } 225 return secureStops; 226 } 227 228 static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>& 229 hSecureStopIds) { 230 List<Vector<uint8_t>> secureStopIds; 231 for (size_t i = 0; i < hSecureStopIds.size(); i++) { 232 secureStopIds.push_back(toVector(hSecureStopIds[i])); 233 } 234 return secureStopIds; 235 } 236 237 static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>& 238 hKeySetIds) { 239 List<Vector<uint8_t>> keySetIds; 240 for (size_t i = 0; i < hKeySetIds.size(); i++) { 241 keySetIds.push_back(toVector(hKeySetIds[i])); 242 } 243 return keySetIds; 244 } 245 246 static status_t toStatusT(Status status) { 247 switch (status) { 248 case Status::OK: 249 return OK; 250 break; 251 case Status::ERROR_DRM_NO_LICENSE: 252 return ERROR_DRM_NO_LICENSE; 253 break; 254 case Status::ERROR_DRM_LICENSE_EXPIRED: 255 return ERROR_DRM_LICENSE_EXPIRED; 256 break; 257 case Status::ERROR_DRM_SESSION_NOT_OPENED: 258 return ERROR_DRM_SESSION_NOT_OPENED; 259 break; 260 case Status::ERROR_DRM_CANNOT_HANDLE: 261 return ERROR_DRM_CANNOT_HANDLE; 262 break; 263 case Status::ERROR_DRM_INVALID_STATE: 264 return ERROR_DRM_INVALID_STATE; 265 break; 266 case Status::BAD_VALUE: 267 return BAD_VALUE; 268 break; 269 case Status::ERROR_DRM_NOT_PROVISIONED: 270 return ERROR_DRM_NOT_PROVISIONED; 271 break; 272 case Status::ERROR_DRM_RESOURCE_BUSY: 273 return ERROR_DRM_RESOURCE_BUSY; 274 break; 275 case Status::ERROR_DRM_DEVICE_REVOKED: 276 return ERROR_DRM_DEVICE_REVOKED; 277 break; 278 case Status::ERROR_DRM_UNKNOWN: 279 default: 280 return ERROR_DRM_UNKNOWN; 281 break; 282 } 283 } 284 285 static status_t toStatusT_1_2(Status_V1_2 status) { 286 switch (status) { 287 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION: 288 return ERROR_DRM_RESOURCE_CONTENTION; 289 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE: 290 return ERROR_DRM_FRAME_TOO_LARGE; 291 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY: 292 return ERROR_DRM_INSUFFICIENT_SECURITY; 293 default: 294 return toStatusT(static_cast<Status>(status)); 295 } 296 } 297 298 299 Mutex DrmHal::mLock; 300 301 struct DrmSessionClient : public DrmSessionClientInterface { 302 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {} 303 304 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { 305 sp<DrmHal> drm = mDrm.promote(); 306 if (drm == NULL) { 307 return true; 308 } 309 status_t err = drm->closeSession(sessionId); 310 if (err != OK) { 311 return false; 312 } 313 drm->sendEvent(EventType::SESSION_RECLAIMED, 314 toHidlVec(sessionId), hidl_vec<uint8_t>()); 315 return true; 316 } 317 318 protected: 319 virtual ~DrmSessionClient() {} 320 321 private: 322 wp<DrmHal> mDrm; 323 324 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient); 325 }; 326 327 DrmHal::DrmHal() 328 : mDrmSessionClient(new DrmSessionClient(this)), 329 mFactories(makeDrmFactories()), 330 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) { 331 } 332 333 void DrmHal::closeOpenSessions() { 334 Mutex::Autolock autoLock(mLock); 335 auto openSessions = mOpenSessions; 336 for (size_t i = 0; i < openSessions.size(); i++) { 337 mLock.unlock(); 338 closeSession(openSessions[i]); 339 mLock.lock(); 340 } 341 mOpenSessions.clear(); 342 } 343 344 DrmHal::~DrmHal() { 345 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient); 346 } 347 348 void DrmHal::cleanup() { 349 closeOpenSessions(); 350 351 Mutex::Autolock autoLock(mLock); 352 reportPluginMetrics(); 353 reportFrameworkMetrics(); 354 355 setListener(NULL); 356 mInitCheck = NO_INIT; 357 if (mPluginV1_2 != NULL) { 358 if (!mPluginV1_2->setListener(NULL).isOk()) { 359 mInitCheck = DEAD_OBJECT; 360 } 361 } else if (mPlugin != NULL) { 362 if (!mPlugin->setListener(NULL).isOk()) { 363 mInitCheck = DEAD_OBJECT; 364 } 365 } 366 mPlugin.clear(); 367 mPluginV1_1.clear(); 368 mPluginV1_2.clear(); 369 } 370 371 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() { 372 Vector<sp<IDrmFactory>> factories; 373 374 auto manager = hardware::defaultServiceManager1_2(); 375 376 if (manager != NULL) { 377 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor, 378 [&factories](const hidl_vec<hidl_string> ®istered) { 379 for (const auto &instance : registered) { 380 auto factory = drm::V1_0::IDrmFactory::getService(instance); 381 if (factory != NULL) { 382 factories.push_back(factory); 383 } 384 } 385 } 386 ); 387 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor, 388 [&factories](const hidl_vec<hidl_string> ®istered) { 389 for (const auto &instance : registered) { 390 auto factory = drm::V1_1::IDrmFactory::getService(instance); 391 if (factory != NULL) { 392 factories.push_back(factory); 393 } 394 } 395 } 396 ); 397 manager->listByInterface(drm::V1_2::IDrmFactory::descriptor, 398 [&factories](const hidl_vec<hidl_string> ®istered) { 399 for (const auto &instance : registered) { 400 auto factory = drm::V1_2::IDrmFactory::getService(instance); 401 if (factory != NULL) { 402 factories.push_back(factory); 403 } 404 } 405 } 406 ); 407 } 408 409 if (factories.size() == 0) { 410 // must be in passthrough mode, load the default passthrough service 411 auto passthrough = IDrmFactory::getService(); 412 if (passthrough != NULL) { 413 ALOGI("makeDrmFactories: using default passthrough drm instance"); 414 factories.push_back(passthrough); 415 } else { 416 ALOGE("Failed to find any drm factories"); 417 } 418 } 419 return factories; 420 } 421 422 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory, 423 const uint8_t uuid[16], const String8& appPackageName) { 424 mAppPackageName = appPackageName; 425 mMetrics.SetAppPackageName(appPackageName); 426 427 sp<IDrmPlugin> plugin; 428 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(), 429 [&](Status status, const sp<IDrmPlugin>& hPlugin) { 430 if (status != Status::OK) { 431 ALOGE("Failed to make drm plugin"); 432 return; 433 } 434 plugin = hPlugin; 435 } 436 ); 437 438 if (!hResult.isOk()) { 439 ALOGE("createPlugin remote call failed"); 440 } 441 442 return plugin; 443 } 444 445 status_t DrmHal::initCheck() const { 446 return mInitCheck; 447 } 448 449 status_t DrmHal::setListener(const sp<IDrmClient>& listener) 450 { 451 Mutex::Autolock lock(mEventLock); 452 if (mListener != NULL){ 453 IInterface::asBinder(mListener)->unlinkToDeath(this); 454 } 455 if (listener != NULL) { 456 IInterface::asBinder(listener)->linkToDeath(this); 457 } 458 mListener = listener; 459 return NO_ERROR; 460 } 461 462 Return<void> DrmHal::sendEvent(EventType hEventType, 463 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { 464 mMetrics.mEventCounter.Increment(hEventType); 465 466 mEventLock.lock(); 467 sp<IDrmClient> listener = mListener; 468 mEventLock.unlock(); 469 470 if (listener != NULL) { 471 Parcel obj; 472 writeByteArray(obj, sessionId); 473 writeByteArray(obj, data); 474 475 Mutex::Autolock lock(mNotifyLock); 476 DrmPlugin::EventType eventType; 477 switch(hEventType) { 478 case EventType::PROVISION_REQUIRED: 479 eventType = DrmPlugin::kDrmPluginEventProvisionRequired; 480 break; 481 case EventType::KEY_NEEDED: 482 eventType = DrmPlugin::kDrmPluginEventKeyNeeded; 483 break; 484 case EventType::KEY_EXPIRED: 485 eventType = DrmPlugin::kDrmPluginEventKeyExpired; 486 break; 487 case EventType::VENDOR_DEFINED: 488 eventType = DrmPlugin::kDrmPluginEventVendorDefined; 489 break; 490 case EventType::SESSION_RECLAIMED: 491 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed; 492 break; 493 default: 494 return Void(); 495 } 496 listener->notify(eventType, 0, &obj); 497 } 498 return Void(); 499 } 500 501 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, 502 int64_t expiryTimeInMS) { 503 504 mEventLock.lock(); 505 sp<IDrmClient> listener = mListener; 506 mEventLock.unlock(); 507 508 if (listener != NULL) { 509 Parcel obj; 510 writeByteArray(obj, sessionId); 511 obj.writeInt64(expiryTimeInMS); 512 513 Mutex::Autolock lock(mNotifyLock); 514 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj); 515 } 516 return Void(); 517 } 518 519 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId, 520 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) { 521 std::vector<KeyStatus> keyStatusVec; 522 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) { 523 keyStatusVec.push_back({keyStatus_V1_0.keyId, 524 static_cast<KeyStatusType>(keyStatus_V1_0.type)}); 525 } 526 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec); 527 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey); 528 } 529 530 Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId, 531 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) { 532 533 mEventLock.lock(); 534 sp<IDrmClient> listener = mListener; 535 mEventLock.unlock(); 536 537 if (listener != NULL) { 538 Parcel obj; 539 writeByteArray(obj, sessionId); 540 541 size_t nKeys = keyStatusList.size(); 542 obj.writeInt32(nKeys); 543 for (size_t i = 0; i < nKeys; ++i) { 544 const KeyStatus &keyStatus = keyStatusList[i]; 545 writeByteArray(obj, keyStatus.keyId); 546 uint32_t type; 547 switch(keyStatus.type) { 548 case KeyStatusType::USABLE: 549 type = DrmPlugin::kKeyStatusType_Usable; 550 break; 551 case KeyStatusType::EXPIRED: 552 type = DrmPlugin::kKeyStatusType_Expired; 553 break; 554 case KeyStatusType::OUTPUTNOTALLOWED: 555 type = DrmPlugin::kKeyStatusType_OutputNotAllowed; 556 break; 557 case KeyStatusType::STATUSPENDING: 558 type = DrmPlugin::kKeyStatusType_StatusPending; 559 break; 560 case KeyStatusType::USABLEINFUTURE: 561 type = DrmPlugin::kKeyStatusType_UsableInFuture; 562 break; 563 case KeyStatusType::INTERNALERROR: 564 default: 565 type = DrmPlugin::kKeyStatusType_InternalError; 566 break; 567 } 568 obj.writeInt32(type); 569 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type); 570 } 571 obj.writeInt32(hasNewUsableKey); 572 573 Mutex::Autolock lock(mNotifyLock); 574 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj); 575 } else { 576 // There's no listener. But we still want to count the key change 577 // events. 578 size_t nKeys = keyStatusList.size(); 579 for (size_t i = 0; i < nKeys; i++) { 580 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type); 581 } 582 } 583 584 return Void(); 585 } 586 587 Return<void> DrmHal::sendSessionLostState( 588 const hidl_vec<uint8_t>& sessionId) { 589 590 mEventLock.lock(); 591 sp<IDrmClient> listener = mListener; 592 mEventLock.unlock(); 593 594 if (listener != NULL) { 595 Parcel obj; 596 writeByteArray(obj, sessionId); 597 Mutex::Autolock lock(mNotifyLock); 598 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj); 599 } 600 return Void(); 601 } 602 603 status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory, 604 const uint8_t uuid[16], 605 const String8 &mimeType, 606 DrmPlugin::SecurityLevel level, 607 bool *isSupported) { 608 *isSupported = false; 609 610 // handle default value cases 611 if (level == DrmPlugin::kSecurityLevelUnknown) { 612 if (mimeType == "") { 613 // isCryptoSchemeSupported(uuid) 614 *isSupported = true; 615 } else { 616 // isCryptoSchemeSupported(uuid, mimeType) 617 *isSupported = factory->isContentTypeSupported(mimeType.string()); 618 } 619 return OK; 620 } else if (mimeType == "") { 621 return BAD_VALUE; 622 } 623 624 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory); 625 if (factoryV1_2 == NULL) { 626 return ERROR_UNSUPPORTED; 627 } else { 628 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, 629 mimeType.string(), toHidlSecurityLevel(level)); 630 return OK; 631 } 632 } 633 634 status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], 635 const String8 &mimeType, 636 DrmPlugin::SecurityLevel level, 637 bool *isSupported) { 638 Mutex::Autolock autoLock(mLock); 639 *isSupported = false; 640 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) { 641 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 642 return matchMimeTypeAndSecurityLevel(mFactories[i], 643 uuid, mimeType, level, isSupported); 644 } 645 } 646 return OK; 647 } 648 649 status_t DrmHal::createPlugin(const uint8_t uuid[16], 650 const String8& appPackageName) { 651 Mutex::Autolock autoLock(mLock); 652 653 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) { 654 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 655 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName); 656 if (plugin != NULL) { 657 mPlugin = plugin; 658 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin); 659 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin); 660 break; 661 } 662 } 663 } 664 665 if (mPlugin == NULL) { 666 mInitCheck = ERROR_UNSUPPORTED; 667 } else { 668 mInitCheck = OK; 669 if (mPluginV1_2 != NULL) { 670 if (!mPluginV1_2->setListener(this).isOk()) { 671 mInitCheck = DEAD_OBJECT; 672 } 673 } else if (!mPlugin->setListener(this).isOk()) { 674 mInitCheck = DEAD_OBJECT; 675 } 676 if (mInitCheck != OK) { 677 mPlugin.clear(); 678 mPluginV1_1.clear(); 679 mPluginV1_2.clear(); 680 } 681 } 682 683 684 return mInitCheck; 685 } 686 687 status_t DrmHal::destroyPlugin() { 688 cleanup(); 689 return OK; 690 } 691 692 status_t DrmHal::openSession(DrmPlugin::SecurityLevel level, 693 Vector<uint8_t> &sessionId) { 694 Mutex::Autolock autoLock(mLock); 695 INIT_CHECK(); 696 697 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level); 698 bool setSecurityLevel = true; 699 700 if (level == DrmPlugin::kSecurityLevelMax) { 701 setSecurityLevel = false; 702 } else { 703 if (hSecurityLevel == SecurityLevel::UNKNOWN) { 704 return ERROR_DRM_CANNOT_HANDLE; 705 } 706 } 707 708 status_t err = UNKNOWN_ERROR; 709 bool retry = true; 710 do { 711 hidl_vec<uint8_t> hSessionId; 712 713 Return<void> hResult; 714 if (mPluginV1_1 == NULL || !setSecurityLevel) { 715 hResult = mPlugin->openSession( 716 [&](Status status,const hidl_vec<uint8_t>& id) { 717 if (status == Status::OK) { 718 sessionId = toVector(id); 719 } 720 err = toStatusT(status); 721 } 722 ); 723 } else { 724 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel, 725 [&](Status status, const hidl_vec<uint8_t>& id) { 726 if (status == Status::OK) { 727 sessionId = toVector(id); 728 } 729 err = toStatusT(status); 730 } 731 ); 732 } 733 734 if (!hResult.isOk()) { 735 err = DEAD_OBJECT; 736 } 737 738 if (err == ERROR_DRM_RESOURCE_BUSY && retry) { 739 mLock.unlock(); 740 // reclaimSession may call back to closeSession, since mLock is 741 // shared between Drm instances, we should unlock here to avoid 742 // deadlock. 743 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); 744 mLock.lock(); 745 } else { 746 retry = false; 747 } 748 } while (retry); 749 750 if (err == OK) { 751 DrmSessionManager::Instance()->addSession(getCallingPid(), 752 mDrmSessionClient, sessionId); 753 mOpenSessions.push(sessionId); 754 mMetrics.SetSessionStart(sessionId); 755 } 756 757 mMetrics.mOpenSessionCounter.Increment(err); 758 return err; 759 } 760 761 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { 762 Mutex::Autolock autoLock(mLock); 763 INIT_CHECK(); 764 765 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId)); 766 if (status.isOk()) { 767 if (status == Status::OK) { 768 DrmSessionManager::Instance()->removeSession(sessionId); 769 for (size_t i = 0; i < mOpenSessions.size(); i++) { 770 if (mOpenSessions[i] == sessionId) { 771 mOpenSessions.removeAt(i); 772 break; 773 } 774 } 775 } 776 status_t response = toStatusT(status); 777 mMetrics.SetSessionEnd(sessionId); 778 mMetrics.mCloseSessionCounter.Increment(response); 779 return response; 780 } 781 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT); 782 return DEAD_OBJECT; 783 } 784 785 static DrmPlugin::KeyRequestType toKeyRequestType( 786 KeyRequestType keyRequestType) { 787 switch (keyRequestType) { 788 case KeyRequestType::INITIAL: 789 return DrmPlugin::kKeyRequestType_Initial; 790 break; 791 case KeyRequestType::RENEWAL: 792 return DrmPlugin::kKeyRequestType_Renewal; 793 break; 794 case KeyRequestType::RELEASE: 795 return DrmPlugin::kKeyRequestType_Release; 796 break; 797 default: 798 return DrmPlugin::kKeyRequestType_Unknown; 799 break; 800 } 801 } 802 803 static DrmPlugin::KeyRequestType toKeyRequestType_1_1( 804 KeyRequestType_V1_1 keyRequestType) { 805 switch (keyRequestType) { 806 case KeyRequestType_V1_1::NONE: 807 return DrmPlugin::kKeyRequestType_None; 808 break; 809 case KeyRequestType_V1_1::UPDATE: 810 return DrmPlugin::kKeyRequestType_Update; 811 break; 812 default: 813 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType)); 814 break; 815 } 816 } 817 818 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, 819 Vector<uint8_t> const &initData, String8 const &mimeType, 820 DrmPlugin::KeyType keyType, KeyedVector<String8, 821 String8> const &optionalParameters, Vector<uint8_t> &request, 822 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) { 823 Mutex::Autolock autoLock(mLock); 824 INIT_CHECK(); 825 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs); 826 827 DrmSessionManager::Instance()->useSession(sessionId); 828 829 KeyType hKeyType; 830 if (keyType == DrmPlugin::kKeyType_Streaming) { 831 hKeyType = KeyType::STREAMING; 832 } else if (keyType == DrmPlugin::kKeyType_Offline) { 833 hKeyType = KeyType::OFFLINE; 834 } else if (keyType == DrmPlugin::kKeyType_Release) { 835 hKeyType = KeyType::RELEASE; 836 } else { 837 keyRequestTimer.SetAttribute(BAD_VALUE); 838 return BAD_VALUE; 839 } 840 841 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters); 842 843 status_t err = UNKNOWN_ERROR; 844 Return<void> hResult; 845 846 if (mPluginV1_2 != NULL) { 847 hResult = mPluginV1_2->getKeyRequest_1_2( 848 toHidlVec(sessionId), toHidlVec(initData), 849 toHidlString(mimeType), hKeyType, hOptionalParameters, 850 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest, 851 KeyRequestType_V1_1 hKeyRequestType, 852 const hidl_string& hDefaultUrl) { 853 if (status == Status_V1_2::OK) { 854 request = toVector(hRequest); 855 defaultUrl = toString8(hDefaultUrl); 856 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType); 857 } 858 err = toStatusT_1_2(status); 859 }); 860 } else if (mPluginV1_1 != NULL) { 861 hResult = mPluginV1_1->getKeyRequest_1_1( 862 toHidlVec(sessionId), toHidlVec(initData), 863 toHidlString(mimeType), hKeyType, hOptionalParameters, 864 [&](Status status, const hidl_vec<uint8_t>& hRequest, 865 KeyRequestType_V1_1 hKeyRequestType, 866 const hidl_string& hDefaultUrl) { 867 if (status == Status::OK) { 868 request = toVector(hRequest); 869 defaultUrl = toString8(hDefaultUrl); 870 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType); 871 } 872 err = toStatusT(status); 873 }); 874 } else { 875 hResult = mPlugin->getKeyRequest( 876 toHidlVec(sessionId), toHidlVec(initData), 877 toHidlString(mimeType), hKeyType, hOptionalParameters, 878 [&](Status status, const hidl_vec<uint8_t>& hRequest, 879 KeyRequestType hKeyRequestType, 880 const hidl_string& hDefaultUrl) { 881 if (status == Status::OK) { 882 request = toVector(hRequest); 883 defaultUrl = toString8(hDefaultUrl); 884 *keyRequestType = toKeyRequestType(hKeyRequestType); 885 } 886 err = toStatusT(status); 887 }); 888 } 889 890 err = hResult.isOk() ? err : DEAD_OBJECT; 891 keyRequestTimer.SetAttribute(err); 892 return err; 893 } 894 895 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, 896 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { 897 Mutex::Autolock autoLock(mLock); 898 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs); 899 900 INIT_CHECK(); 901 902 DrmSessionManager::Instance()->useSession(sessionId); 903 904 status_t err = UNKNOWN_ERROR; 905 906 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId), 907 toHidlVec(response), 908 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) { 909 if (status == Status::OK) { 910 keySetId = toVector(hKeySetId); 911 } 912 err = toStatusT(status); 913 } 914 ); 915 err = hResult.isOk() ? err : DEAD_OBJECT; 916 keyResponseTimer.SetAttribute(err); 917 return err; 918 } 919 920 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { 921 Mutex::Autolock autoLock(mLock); 922 INIT_CHECK(); 923 924 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId)); 925 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 926 } 927 928 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId, 929 Vector<uint8_t> const &keySetId) { 930 Mutex::Autolock autoLock(mLock); 931 INIT_CHECK(); 932 933 DrmSessionManager::Instance()->useSession(sessionId); 934 935 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), 936 toHidlVec(keySetId)); 937 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 938 } 939 940 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId, 941 KeyedVector<String8, String8> &infoMap) const { 942 Mutex::Autolock autoLock(mLock); 943 INIT_CHECK(); 944 945 DrmSessionManager::Instance()->useSession(sessionId); 946 947 ::KeyedVector hInfoMap; 948 949 status_t err = UNKNOWN_ERROR; 950 951 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId), 952 [&](Status status, const hidl_vec<KeyValue>& map) { 953 if (status == Status::OK) { 954 infoMap = toKeyedVector(map); 955 } 956 err = toStatusT(status); 957 } 958 ); 959 960 return hResult.isOk() ? err : DEAD_OBJECT; 961 } 962 963 status_t DrmHal::getProvisionRequest(String8 const &certType, 964 String8 const &certAuthority, Vector<uint8_t> &request, 965 String8 &defaultUrl) { 966 Mutex::Autolock autoLock(mLock); 967 INIT_CHECK(); 968 969 status_t err = UNKNOWN_ERROR; 970 Return<void> hResult; 971 972 if (mPluginV1_2 != NULL) { 973 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2( 974 toHidlString(certType), toHidlString(certAuthority), 975 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest, 976 const hidl_string& hDefaultUrl) { 977 if (status == Status_V1_2::OK) { 978 request = toVector(hRequest); 979 defaultUrl = toString8(hDefaultUrl); 980 } 981 err = toStatusT_1_2(status); 982 } 983 ); 984 } else { 985 Return<void> hResult = mPlugin->getProvisionRequest( 986 toHidlString(certType), toHidlString(certAuthority), 987 [&](Status status, const hidl_vec<uint8_t>& hRequest, 988 const hidl_string& hDefaultUrl) { 989 if (status == Status::OK) { 990 request = toVector(hRequest); 991 defaultUrl = toString8(hDefaultUrl); 992 } 993 err = toStatusT(status); 994 } 995 ); 996 } 997 998 err = hResult.isOk() ? err : DEAD_OBJECT; 999 mMetrics.mGetProvisionRequestCounter.Increment(err); 1000 return err; 1001 } 1002 1003 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, 1004 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 1005 Mutex::Autolock autoLock(mLock); 1006 INIT_CHECK(); 1007 1008 status_t err = UNKNOWN_ERROR; 1009 1010 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response), 1011 [&](Status status, const hidl_vec<uint8_t>& hCertificate, 1012 const hidl_vec<uint8_t>& hWrappedKey) { 1013 if (status == Status::OK) { 1014 certificate = toVector(hCertificate); 1015 wrappedKey = toVector(hWrappedKey); 1016 } 1017 err = toStatusT(status); 1018 } 1019 ); 1020 1021 err = hResult.isOk() ? err : DEAD_OBJECT; 1022 mMetrics.mProvideProvisionResponseCounter.Increment(err); 1023 return err; 1024 } 1025 1026 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { 1027 Mutex::Autolock autoLock(mLock); 1028 INIT_CHECK(); 1029 1030 status_t err = UNKNOWN_ERROR; 1031 1032 Return<void> hResult = mPlugin->getSecureStops( 1033 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) { 1034 if (status == Status::OK) { 1035 secureStops = toSecureStops(hSecureStops); 1036 } 1037 err = toStatusT(status); 1038 } 1039 ); 1040 1041 return hResult.isOk() ? err : DEAD_OBJECT; 1042 } 1043 1044 1045 status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) { 1046 Mutex::Autolock autoLock(mLock); 1047 1048 if (mInitCheck != OK) { 1049 return mInitCheck; 1050 } 1051 1052 if (mPluginV1_1 == NULL) { 1053 return ERROR_DRM_CANNOT_HANDLE; 1054 } 1055 1056 status_t err = UNKNOWN_ERROR; 1057 1058 Return<void> hResult = mPluginV1_1->getSecureStopIds( 1059 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) { 1060 if (status == Status::OK) { 1061 secureStopIds = toSecureStopIds(hSecureStopIds); 1062 } 1063 err = toStatusT(status); 1064 } 1065 ); 1066 1067 return hResult.isOk() ? err : DEAD_OBJECT; 1068 } 1069 1070 1071 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { 1072 Mutex::Autolock autoLock(mLock); 1073 INIT_CHECK(); 1074 1075 status_t err = UNKNOWN_ERROR; 1076 1077 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid), 1078 [&](Status status, const SecureStop& hSecureStop) { 1079 if (status == Status::OK) { 1080 secureStop = toVector(hSecureStop.opaqueData); 1081 } 1082 err = toStatusT(status); 1083 } 1084 ); 1085 1086 return hResult.isOk() ? err : DEAD_OBJECT; 1087 } 1088 1089 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) { 1090 Mutex::Autolock autoLock(mLock); 1091 INIT_CHECK(); 1092 1093 Return<Status> status(Status::ERROR_DRM_UNKNOWN); 1094 if (mPluginV1_1 != NULL) { 1095 SecureStopRelease secureStopRelease; 1096 secureStopRelease.opaqueData = toHidlVec(ssRelease); 1097 status = mPluginV1_1->releaseSecureStops(secureStopRelease); 1098 } else { 1099 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease)); 1100 } 1101 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1102 } 1103 1104 status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) { 1105 Mutex::Autolock autoLock(mLock); 1106 1107 if (mInitCheck != OK) { 1108 return mInitCheck; 1109 } 1110 1111 if (mPluginV1_1 == NULL) { 1112 return ERROR_DRM_CANNOT_HANDLE; 1113 } 1114 1115 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid)); 1116 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1117 } 1118 1119 status_t DrmHal::removeAllSecureStops() { 1120 Mutex::Autolock autoLock(mLock); 1121 INIT_CHECK(); 1122 1123 Return<Status> status(Status::ERROR_DRM_UNKNOWN); 1124 if (mPluginV1_1 != NULL) { 1125 status = mPluginV1_1->removeAllSecureStops(); 1126 } else { 1127 status = mPlugin->releaseAllSecureStops(); 1128 } 1129 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1130 } 1131 1132 status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected, 1133 DrmPlugin::HdcpLevel *max) const { 1134 Mutex::Autolock autoLock(mLock); 1135 INIT_CHECK(); 1136 1137 if (connected == NULL || max == NULL) { 1138 return BAD_VALUE; 1139 } 1140 status_t err = UNKNOWN_ERROR; 1141 1142 *connected = DrmPlugin::kHdcpLevelUnknown; 1143 *max = DrmPlugin::kHdcpLevelUnknown; 1144 1145 Return<void> hResult; 1146 if (mPluginV1_2 != NULL) { 1147 hResult = mPluginV1_2->getHdcpLevels_1_2( 1148 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) { 1149 if (status == Status_V1_2::OK) { 1150 *connected = toHdcpLevel(hConnected); 1151 *max = toHdcpLevel(hMax); 1152 } 1153 err = toStatusT_1_2(status); 1154 }); 1155 } else if (mPluginV1_1 != NULL) { 1156 hResult = mPluginV1_1->getHdcpLevels( 1157 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) { 1158 if (status == Status::OK) { 1159 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected)); 1160 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax)); 1161 } 1162 err = toStatusT(status); 1163 }); 1164 } else { 1165 return ERROR_DRM_CANNOT_HANDLE; 1166 } 1167 1168 return hResult.isOk() ? err : DEAD_OBJECT; 1169 } 1170 1171 status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const { 1172 Mutex::Autolock autoLock(mLock); 1173 INIT_CHECK(); 1174 1175 if (open == NULL || max == NULL) { 1176 return BAD_VALUE; 1177 } 1178 status_t err = UNKNOWN_ERROR; 1179 1180 *open = 0; 1181 *max = 0; 1182 1183 if (mPluginV1_1 == NULL) { 1184 return ERROR_DRM_CANNOT_HANDLE; 1185 } 1186 1187 Return<void> hResult = mPluginV1_1->getNumberOfSessions( 1188 [&](Status status, uint32_t hOpen, uint32_t hMax) { 1189 if (status == Status::OK) { 1190 *open = hOpen; 1191 *max = hMax; 1192 } 1193 err = toStatusT(status); 1194 } 1195 ); 1196 1197 return hResult.isOk() ? err : DEAD_OBJECT; 1198 } 1199 1200 status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId, 1201 DrmPlugin::SecurityLevel *level) const { 1202 Mutex::Autolock autoLock(mLock); 1203 INIT_CHECK(); 1204 1205 if (level == NULL) { 1206 return BAD_VALUE; 1207 } 1208 status_t err = UNKNOWN_ERROR; 1209 1210 if (mPluginV1_1 == NULL) { 1211 return ERROR_DRM_CANNOT_HANDLE; 1212 } 1213 1214 *level = DrmPlugin::kSecurityLevelUnknown; 1215 1216 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId), 1217 [&](Status status, SecurityLevel hLevel) { 1218 if (status == Status::OK) { 1219 *level = toSecurityLevel(hLevel); 1220 } 1221 err = toStatusT(status); 1222 } 1223 ); 1224 1225 return hResult.isOk() ? err : DEAD_OBJECT; 1226 } 1227 1228 status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const { 1229 Mutex::Autolock autoLock(mLock); 1230 1231 if (mInitCheck != OK) { 1232 return mInitCheck; 1233 } 1234 1235 if (mPluginV1_2 == NULL) { 1236 return ERROR_UNSUPPORTED; 1237 } 1238 1239 status_t err = UNKNOWN_ERROR; 1240 1241 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds( 1242 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) { 1243 if (status == Status::OK) { 1244 keySetIds = toKeySetIds(hKeySetIds); 1245 } 1246 err = toStatusT(status); 1247 } 1248 ); 1249 1250 return hResult.isOk() ? err : DEAD_OBJECT; 1251 } 1252 1253 status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) { 1254 Mutex::Autolock autoLock(mLock); 1255 1256 if (mInitCheck != OK) { 1257 return mInitCheck; 1258 } 1259 1260 if (mPluginV1_2 == NULL) { 1261 return ERROR_UNSUPPORTED; 1262 } 1263 1264 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId)); 1265 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1266 } 1267 1268 status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId, 1269 DrmPlugin::OfflineLicenseState *licenseState) const { 1270 Mutex::Autolock autoLock(mLock); 1271 1272 if (mInitCheck != OK) { 1273 return mInitCheck; 1274 } 1275 1276 if (mPluginV1_2 == NULL) { 1277 return ERROR_UNSUPPORTED; 1278 } 1279 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown; 1280 1281 status_t err = UNKNOWN_ERROR; 1282 1283 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId), 1284 [&](Status status, OfflineLicenseState hLicenseState) { 1285 if (status == Status::OK) { 1286 *licenseState = toOfflineLicenseState(hLicenseState); 1287 } 1288 err = toStatusT(status); 1289 } 1290 ); 1291 1292 return hResult.isOk() ? err : DEAD_OBJECT; 1293 } 1294 1295 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const { 1296 Mutex::Autolock autoLock(mLock); 1297 return getPropertyStringInternal(name, value); 1298 } 1299 1300 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const { 1301 // This function is internal to the class and should only be called while 1302 // mLock is already held. 1303 INIT_CHECK(); 1304 1305 status_t err = UNKNOWN_ERROR; 1306 1307 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name), 1308 [&](Status status, const hidl_string& hValue) { 1309 if (status == Status::OK) { 1310 value = toString8(hValue); 1311 } 1312 err = toStatusT(status); 1313 } 1314 ); 1315 1316 return hResult.isOk() ? err : DEAD_OBJECT; 1317 } 1318 1319 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const { 1320 Mutex::Autolock autoLock(mLock); 1321 return getPropertyByteArrayInternal(name, value); 1322 } 1323 1324 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const { 1325 // This function is internal to the class and should only be called while 1326 // mLock is already held. 1327 INIT_CHECK(); 1328 1329 status_t err = UNKNOWN_ERROR; 1330 1331 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name), 1332 [&](Status status, const hidl_vec<uint8_t>& hValue) { 1333 if (status == Status::OK) { 1334 value = toVector(hValue); 1335 } 1336 err = toStatusT(status); 1337 } 1338 ); 1339 1340 err = hResult.isOk() ? err : DEAD_OBJECT; 1341 if (name == kPropertyDeviceUniqueId) { 1342 mMetrics.mGetDeviceUniqueIdCounter.Increment(err); 1343 } 1344 return err; 1345 } 1346 1347 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { 1348 Mutex::Autolock autoLock(mLock); 1349 INIT_CHECK(); 1350 1351 Return<Status> status = mPlugin->setPropertyString(toHidlString(name), 1352 toHidlString(value)); 1353 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1354 } 1355 1356 status_t DrmHal::setPropertyByteArray(String8 const &name, 1357 Vector<uint8_t> const &value ) const { 1358 Mutex::Autolock autoLock(mLock); 1359 INIT_CHECK(); 1360 1361 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), 1362 toHidlVec(value)); 1363 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1364 } 1365 1366 status_t DrmHal::getMetrics(PersistableBundle* metrics) { 1367 if (metrics == nullptr) { 1368 return UNEXPECTED_NULL; 1369 } 1370 mMetrics.Export(metrics); 1371 1372 // Append vendor metrics if they are supported. 1373 if (mPluginV1_1 != NULL) { 1374 String8 vendor; 1375 String8 description; 1376 if (getPropertyStringInternal(String8("vendor"), vendor) != OK 1377 || vendor.isEmpty()) { 1378 ALOGE("Get vendor failed or is empty"); 1379 vendor = "NONE"; 1380 } 1381 if (getPropertyStringInternal(String8("description"), description) != OK 1382 || description.isEmpty()) { 1383 ALOGE("Get description failed or is empty."); 1384 description = "NONE"; 1385 } 1386 vendor += "."; 1387 vendor += description; 1388 1389 hidl_vec<DrmMetricGroup> pluginMetrics; 1390 status_t err = UNKNOWN_ERROR; 1391 1392 Return<void> status = mPluginV1_1->getMetrics( 1393 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) { 1394 if (status != Status::OK) { 1395 ALOGV("Error getting plugin metrics: %d", status); 1396 } else { 1397 PersistableBundle pluginBundle; 1398 if (MediaDrmMetrics::HidlMetricsToBundle( 1399 pluginMetrics, &pluginBundle) == OK) { 1400 metrics->putPersistableBundle(String16(vendor), pluginBundle); 1401 } 1402 } 1403 err = toStatusT(status); 1404 }); 1405 return status.isOk() ? err : DEAD_OBJECT; 1406 } 1407 1408 return OK; 1409 } 1410 1411 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId, 1412 String8 const &algorithm) { 1413 Mutex::Autolock autoLock(mLock); 1414 INIT_CHECK(); 1415 1416 DrmSessionManager::Instance()->useSession(sessionId); 1417 1418 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId), 1419 toHidlString(algorithm)); 1420 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1421 } 1422 1423 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId, 1424 String8 const &algorithm) { 1425 Mutex::Autolock autoLock(mLock); 1426 INIT_CHECK(); 1427 1428 DrmSessionManager::Instance()->useSession(sessionId); 1429 1430 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), 1431 toHidlString(algorithm)); 1432 return status.isOk() ? toStatusT(status) : DEAD_OBJECT; 1433 } 1434 1435 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId, 1436 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 1437 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 1438 Mutex::Autolock autoLock(mLock); 1439 INIT_CHECK(); 1440 1441 DrmSessionManager::Instance()->useSession(sessionId); 1442 1443 status_t err = UNKNOWN_ERROR; 1444 1445 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId), 1446 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 1447 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 1448 if (status == Status::OK) { 1449 output = toVector(hOutput); 1450 } 1451 err = toStatusT(status); 1452 } 1453 ); 1454 1455 return hResult.isOk() ? err : DEAD_OBJECT; 1456 } 1457 1458 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId, 1459 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 1460 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 1461 Mutex::Autolock autoLock(mLock); 1462 INIT_CHECK(); 1463 1464 DrmSessionManager::Instance()->useSession(sessionId); 1465 1466 status_t err = UNKNOWN_ERROR; 1467 1468 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId), 1469 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 1470 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 1471 if (status == Status::OK) { 1472 output = toVector(hOutput); 1473 } 1474 err = toStatusT(status); 1475 } 1476 ); 1477 1478 return hResult.isOk() ? err : DEAD_OBJECT; 1479 } 1480 1481 status_t DrmHal::sign(Vector<uint8_t> const &sessionId, 1482 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 1483 Vector<uint8_t> &signature) { 1484 Mutex::Autolock autoLock(mLock); 1485 INIT_CHECK(); 1486 1487 DrmSessionManager::Instance()->useSession(sessionId); 1488 1489 status_t err = UNKNOWN_ERROR; 1490 1491 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), 1492 toHidlVec(keyId), toHidlVec(message), 1493 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 1494 if (status == Status::OK) { 1495 signature = toVector(hSignature); 1496 } 1497 err = toStatusT(status); 1498 } 1499 ); 1500 1501 return hResult.isOk() ? err : DEAD_OBJECT; 1502 } 1503 1504 status_t DrmHal::verify(Vector<uint8_t> const &sessionId, 1505 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 1506 Vector<uint8_t> const &signature, bool &match) { 1507 Mutex::Autolock autoLock(mLock); 1508 INIT_CHECK(); 1509 1510 DrmSessionManager::Instance()->useSession(sessionId); 1511 1512 status_t err = UNKNOWN_ERROR; 1513 1514 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId), 1515 toHidlVec(message), toHidlVec(signature), 1516 [&](Status status, bool hMatch) { 1517 if (status == Status::OK) { 1518 match = hMatch; 1519 } else { 1520 match = false; 1521 } 1522 err = toStatusT(status); 1523 } 1524 ); 1525 1526 return hResult.isOk() ? err : DEAD_OBJECT; 1527 } 1528 1529 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId, 1530 String8 const &algorithm, Vector<uint8_t> const &message, 1531 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 1532 Mutex::Autolock autoLock(mLock); 1533 INIT_CHECK(); 1534 1535 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) { 1536 return -EPERM; 1537 } 1538 1539 DrmSessionManager::Instance()->useSession(sessionId); 1540 1541 status_t err = UNKNOWN_ERROR; 1542 1543 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId), 1544 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey), 1545 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 1546 if (status == Status::OK) { 1547 signature = toVector(hSignature); 1548 } 1549 err = toStatusT(status); 1550 } 1551 ); 1552 1553 return hResult.isOk() ? err : DEAD_OBJECT; 1554 } 1555 1556 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused) 1557 { 1558 cleanup(); 1559 } 1560 1561 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec) 1562 { 1563 if (vec.size()) { 1564 obj.writeInt32(vec.size()); 1565 obj.write(vec.data(), vec.size()); 1566 } else { 1567 obj.writeInt32(0); 1568 } 1569 } 1570 1571 void DrmHal::reportFrameworkMetrics() const 1572 { 1573 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm")); 1574 item->generateSessionID(); 1575 item->setPkgName(mMetrics.GetAppPackageName().c_str()); 1576 String8 vendor; 1577 String8 description; 1578 status_t result = getPropertyStringInternal(String8("vendor"), vendor); 1579 if (result != OK) { 1580 ALOGE("Failed to get vendor from drm plugin: %d", result); 1581 } else { 1582 item->setCString("vendor", vendor.c_str()); 1583 } 1584 result = getPropertyStringInternal(String8("description"), description); 1585 if (result != OK) { 1586 ALOGE("Failed to get description from drm plugin: %d", result); 1587 } else { 1588 item->setCString("description", description.c_str()); 1589 } 1590 1591 std::string serializedMetrics; 1592 result = mMetrics.GetSerializedMetrics(&serializedMetrics); 1593 if (result != OK) { 1594 ALOGE("Failed to serialize framework metrics: %d", result); 1595 } 1596 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(), 1597 serializedMetrics.size()); 1598 if (!b64EncodedMetrics.empty()) { 1599 item->setCString("serialized_metrics", b64EncodedMetrics.c_str()); 1600 } 1601 if (!item->selfrecord()) { 1602 ALOGE("Failed to self record framework metrics"); 1603 } 1604 } 1605 1606 void DrmHal::reportPluginMetrics() const 1607 { 1608 Vector<uint8_t> metricsVector; 1609 String8 vendor; 1610 String8 description; 1611 if (getPropertyStringInternal(String8("vendor"), vendor) == OK && 1612 getPropertyStringInternal(String8("description"), description) == OK && 1613 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) { 1614 std::string metricsString = toBase64StringNoPad(metricsVector.array(), 1615 metricsVector.size()); 1616 status_t res = android::reportDrmPluginMetrics(metricsString, vendor, 1617 description, mAppPackageName); 1618 if (res != OK) { 1619 ALOGE("Metrics were retrieved but could not be reported: %d", res); 1620 } 1621 } 1622 } 1623 1624 } // namespace android 1625