DrmHal.cpp revision 5641aa251bf9a6e7b6bf8a73214f92e42c393a2f
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 <utils/Log.h> 20 21#include <binder/IPCThreadState.h> 22#include <binder/IServiceManager.h> 23 24#include <android/hardware/drm/1.0/IDrmFactory.h> 25#include <android/hardware/drm/1.0/IDrmPlugin.h> 26#include <android/hardware/drm/1.0/types.h> 27#include <android/hidl/manager/1.0/IServiceManager.h> 28#include <hidl/ServiceManagement.h> 29 30#include <media/DrmHal.h> 31#include <media/DrmSessionClientInterface.h> 32#include <media/DrmSessionManager.h> 33#include <media/EventMetric.h> 34#include <media/PluginMetricsReporting.h> 35#include <media/drm/DrmAPI.h> 36#include <media/stagefright/foundation/ADebug.h> 37#include <media/stagefright/foundation/AString.h> 38#include <media/stagefright/foundation/hexdump.h> 39#include <media/stagefright/MediaErrors.h> 40 41using drm::V1_0::KeyedVector; 42using drm::V1_0::KeyStatusType; 43using drm::V1_0::KeyType; 44using drm::V1_0::KeyValue; 45using drm::V1_1::HdcpLevel;; 46using drm::V1_0::SecureStop; 47using drm::V1_1::SecureStopRelease; 48using drm::V1_0::SecureStopId; 49using drm::V1_1::SecurityLevel; 50using drm::V1_0::Status; 51using ::android::hardware::hidl_array; 52using ::android::hardware::hidl_string; 53using ::android::hardware::hidl_vec; 54using ::android::hardware::Return; 55using ::android::hardware::Void; 56using ::android::hidl::manager::V1_0::IServiceManager; 57using ::android::sp; 58 59namespace { 60 61// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant 62// in the MediaDrm API. 63constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId"; 64 65} 66 67namespace android { 68 69#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;} 70 71static inline int getCallingPid() { 72 return IPCThreadState::self()->getCallingPid(); 73} 74 75static bool checkPermission(const char* permissionString) { 76 if (getpid() == IPCThreadState::self()->getCallingPid()) return true; 77 bool ok = checkCallingPermission(String16(permissionString)); 78 if (!ok) ALOGE("Request requires %s", permissionString); 79 return ok; 80} 81 82static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) { 83 Vector<uint8_t> vector; 84 vector.appendArray(vec.data(), vec.size()); 85 return *const_cast<const Vector<uint8_t> *>(&vector); 86} 87 88static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) { 89 hidl_vec<uint8_t> vec; 90 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size()); 91 return vec; 92} 93 94static String8 toString8(const hidl_string &string) { 95 return String8(string.c_str()); 96} 97 98static hidl_string toHidlString(const String8& string) { 99 return hidl_string(string.string()); 100} 101 102static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) { 103 switch(level) { 104 case SecurityLevel::SW_SECURE_CRYPTO: 105 return DrmPlugin::kSecurityLevelSwSecureCrypto; 106 case SecurityLevel::SW_SECURE_DECODE: 107 return DrmPlugin::kSecurityLevelSwSecureDecode; 108 case SecurityLevel::HW_SECURE_CRYPTO: 109 return DrmPlugin::kSecurityLevelHwSecureCrypto; 110 case SecurityLevel::HW_SECURE_DECODE: 111 return DrmPlugin::kSecurityLevelHwSecureDecode; 112 case SecurityLevel::HW_SECURE_ALL: 113 return DrmPlugin::kSecurityLevelHwSecureAll; 114 default: 115 return DrmPlugin::kSecurityLevelUnknown; 116 } 117} 118 119static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) { 120 switch(level) { 121 case HdcpLevel::HDCP_NONE: 122 return DrmPlugin::kHdcpNone; 123 case HdcpLevel::HDCP_V1: 124 return DrmPlugin::kHdcpV1; 125 case HdcpLevel::HDCP_V2: 126 return DrmPlugin::kHdcpV2; 127 case HdcpLevel::HDCP_V2_1: 128 return DrmPlugin::kHdcpV2_1; 129 case HdcpLevel::HDCP_V2_2: 130 return DrmPlugin::kHdcpV2_2; 131 case HdcpLevel::HDCP_NO_OUTPUT: 132 return DrmPlugin::kHdcpNoOutput; 133 default: 134 return DrmPlugin::kHdcpLevelUnknown; 135 } 136} 137 138 139static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>& 140 keyedVector) { 141 std::vector<KeyValue> stdKeyedVector; 142 for (size_t i = 0; i < keyedVector.size(); i++) { 143 KeyValue keyValue; 144 keyValue.key = toHidlString(keyedVector.keyAt(i)); 145 keyValue.value = toHidlString(keyedVector.valueAt(i)); 146 stdKeyedVector.push_back(keyValue); 147 } 148 return ::KeyedVector(stdKeyedVector); 149} 150 151static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector& 152 hKeyedVector) { 153 KeyedVector<String8, String8> keyedVector; 154 for (size_t i = 0; i < hKeyedVector.size(); i++) { 155 keyedVector.add(toString8(hKeyedVector[i].key), 156 toString8(hKeyedVector[i].value)); 157 } 158 return keyedVector; 159} 160 161static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>& 162 hSecureStops) { 163 List<Vector<uint8_t>> secureStops; 164 for (size_t i = 0; i < hSecureStops.size(); i++) { 165 secureStops.push_back(toVector(hSecureStops[i].opaqueData)); 166 } 167 return secureStops; 168} 169 170static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>& 171 hSecureStopIds) { 172 List<Vector<uint8_t>> secureStopIds; 173 for (size_t i = 0; i < hSecureStopIds.size(); i++) { 174 secureStopIds.push_back(toVector(hSecureStopIds[i])); 175 } 176 return secureStopIds; 177} 178 179static status_t toStatusT(Status status) { 180 switch (status) { 181 case Status::OK: 182 return OK; 183 break; 184 case Status::ERROR_DRM_NO_LICENSE: 185 return ERROR_DRM_NO_LICENSE; 186 break; 187 case Status::ERROR_DRM_LICENSE_EXPIRED: 188 return ERROR_DRM_LICENSE_EXPIRED; 189 break; 190 case Status::ERROR_DRM_SESSION_NOT_OPENED: 191 return ERROR_DRM_SESSION_NOT_OPENED; 192 break; 193 case Status::ERROR_DRM_CANNOT_HANDLE: 194 return ERROR_DRM_CANNOT_HANDLE; 195 break; 196 case Status::ERROR_DRM_INVALID_STATE: 197 return ERROR_DRM_TAMPER_DETECTED; 198 break; 199 case Status::BAD_VALUE: 200 return BAD_VALUE; 201 break; 202 case Status::ERROR_DRM_NOT_PROVISIONED: 203 return ERROR_DRM_NOT_PROVISIONED; 204 break; 205 case Status::ERROR_DRM_RESOURCE_BUSY: 206 return ERROR_DRM_RESOURCE_BUSY; 207 break; 208 case Status::ERROR_DRM_DEVICE_REVOKED: 209 return ERROR_DRM_DEVICE_REVOKED; 210 break; 211 case Status::ERROR_DRM_UNKNOWN: 212 default: 213 return ERROR_DRM_UNKNOWN; 214 break; 215 } 216} 217 218 219Mutex DrmHal::mLock; 220 221struct DrmSessionClient : public DrmSessionClientInterface { 222 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {} 223 224 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { 225 sp<DrmHal> drm = mDrm.promote(); 226 if (drm == NULL) { 227 return true; 228 } 229 status_t err = drm->closeSession(sessionId); 230 if (err != OK) { 231 return false; 232 } 233 drm->sendEvent(EventType::SESSION_RECLAIMED, 234 toHidlVec(sessionId), hidl_vec<uint8_t>()); 235 return true; 236 } 237 238protected: 239 virtual ~DrmSessionClient() {} 240 241private: 242 wp<DrmHal> mDrm; 243 244 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient); 245}; 246 247DrmHal::DrmHal() 248 : mDrmSessionClient(new DrmSessionClient(this)), 249 mFactories(makeDrmFactories()), 250 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) { 251} 252 253void DrmHal::closeOpenSessions() { 254 if (mPlugin != NULL) { 255 for (size_t i = 0; i < mOpenSessions.size(); i++) { 256 mPlugin->closeSession(toHidlVec(mOpenSessions[i])); 257 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]); 258 } 259 } 260 mOpenSessions.clear(); 261} 262 263DrmHal::~DrmHal() { 264 closeOpenSessions(); 265 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient); 266} 267 268Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() { 269 Vector<sp<IDrmFactory>> factories; 270 271 auto manager = hardware::defaultServiceManager(); 272 273 if (manager != NULL) { 274 manager->listByInterface(IDrmFactory::descriptor, 275 [&factories](const hidl_vec<hidl_string> ®istered) { 276 for (const auto &instance : registered) { 277 auto factory = IDrmFactory::getService(instance); 278 if (factory != NULL) { 279 factories.push_back(factory); 280 ALOGI("makeDrmFactories: factory instance %s is %s", 281 instance.c_str(), 282 factory->isRemote() ? "Remote" : "Not Remote"); 283 } 284 } 285 } 286 ); 287 } 288 289 if (factories.size() == 0) { 290 // must be in passthrough mode, load the default passthrough service 291 auto passthrough = IDrmFactory::getService(); 292 if (passthrough != NULL) { 293 ALOGI("makeDrmFactories: using default drm instance"); 294 factories.push_back(passthrough); 295 } else { 296 ALOGE("Failed to find any drm factories"); 297 } 298 } 299 return factories; 300} 301 302sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory, 303 const uint8_t uuid[16], const String8& appPackageName) { 304 305 sp<IDrmPlugin> plugin; 306 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(), 307 [&](Status status, const sp<IDrmPlugin>& hPlugin) { 308 if (status != Status::OK) { 309 ALOGE("Failed to make drm plugin"); 310 return; 311 } 312 plugin = hPlugin; 313 } 314 ); 315 316 if (!hResult.isOk()) { 317 ALOGE("createPlugin remote call failed"); 318 } 319 320 return plugin; 321} 322 323status_t DrmHal::initCheck() const { 324 return mInitCheck; 325} 326 327status_t DrmHal::setListener(const sp<IDrmClient>& listener) 328{ 329 Mutex::Autolock lock(mEventLock); 330 if (mListener != NULL){ 331 IInterface::asBinder(mListener)->unlinkToDeath(this); 332 } 333 if (listener != NULL) { 334 IInterface::asBinder(listener)->linkToDeath(this); 335 } 336 mListener = listener; 337 return NO_ERROR; 338} 339 340Return<void> DrmHal::sendEvent(EventType hEventType, 341 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { 342 mMetrics.mEventCounter.Increment(hEventType); 343 344 mEventLock.lock(); 345 sp<IDrmClient> listener = mListener; 346 mEventLock.unlock(); 347 348 if (listener != NULL) { 349 Parcel obj; 350 writeByteArray(obj, sessionId); 351 writeByteArray(obj, data); 352 353 Mutex::Autolock lock(mNotifyLock); 354 DrmPlugin::EventType eventType; 355 switch(hEventType) { 356 case EventType::PROVISION_REQUIRED: 357 eventType = DrmPlugin::kDrmPluginEventProvisionRequired; 358 break; 359 case EventType::KEY_NEEDED: 360 eventType = DrmPlugin::kDrmPluginEventKeyNeeded; 361 break; 362 case EventType::KEY_EXPIRED: 363 eventType = DrmPlugin::kDrmPluginEventKeyExpired; 364 break; 365 case EventType::VENDOR_DEFINED: 366 eventType = DrmPlugin::kDrmPluginEventVendorDefined; 367 break; 368 case EventType::SESSION_RECLAIMED: 369 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed; 370 break; 371 default: 372 return Void(); 373 } 374 listener->notify(eventType, 0, &obj); 375 } 376 return Void(); 377} 378 379Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, 380 int64_t expiryTimeInMS) { 381 382 mEventLock.lock(); 383 sp<IDrmClient> listener = mListener; 384 mEventLock.unlock(); 385 386 if (listener != NULL) { 387 Parcel obj; 388 writeByteArray(obj, sessionId); 389 obj.writeInt64(expiryTimeInMS); 390 391 Mutex::Autolock lock(mNotifyLock); 392 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj); 393 } 394 return Void(); 395} 396 397Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId, 398 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) { 399 400 mEventLock.lock(); 401 sp<IDrmClient> listener = mListener; 402 mEventLock.unlock(); 403 404 if (listener != NULL) { 405 Parcel obj; 406 writeByteArray(obj, sessionId); 407 408 size_t nKeys = keyStatusList.size(); 409 obj.writeInt32(nKeys); 410 for (size_t i = 0; i < nKeys; ++i) { 411 const KeyStatus &keyStatus = keyStatusList[i]; 412 writeByteArray(obj, keyStatus.keyId); 413 uint32_t type; 414 switch(keyStatus.type) { 415 case KeyStatusType::USABLE: 416 type = DrmPlugin::kKeyStatusType_Usable; 417 break; 418 case KeyStatusType::EXPIRED: 419 type = DrmPlugin::kKeyStatusType_Expired; 420 break; 421 case KeyStatusType::OUTPUTNOTALLOWED: 422 type = DrmPlugin::kKeyStatusType_OutputNotAllowed; 423 break; 424 case KeyStatusType::STATUSPENDING: 425 type = DrmPlugin::kKeyStatusType_StatusPending; 426 break; 427 case KeyStatusType::INTERNALERROR: 428 default: 429 type = DrmPlugin::kKeyStatusType_InternalError; 430 break; 431 } 432 obj.writeInt32(type); 433 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type); 434 } 435 obj.writeInt32(hasNewUsableKey); 436 437 Mutex::Autolock lock(mNotifyLock); 438 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj); 439 } else { 440 // There's no listener. But we still want to count the key change 441 // events. 442 size_t nKeys = keyStatusList.size(); 443 for (size_t i = 0; i < nKeys; i++) { 444 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type); 445 } 446 } 447 448 return Void(); 449} 450 451bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) { 452 Mutex::Autolock autoLock(mLock); 453 454 for (size_t i = 0; i < mFactories.size(); i++) { 455 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 456 if (mimeType != "") { 457 if (mFactories[i]->isContentTypeSupported(mimeType.string())) { 458 return true; 459 } 460 } else { 461 return true; 462 } 463 } 464 } 465 return false; 466} 467 468status_t DrmHal::createPlugin(const uint8_t uuid[16], 469 const String8& appPackageName) { 470 Mutex::Autolock autoLock(mLock); 471 472 for (size_t i = 0; i < mFactories.size(); i++) { 473 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 474 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName); 475 if (mPlugin != NULL) { 476 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin); 477 } 478 } 479 } 480 481 if (mPlugin == NULL) { 482 mInitCheck = ERROR_UNSUPPORTED; 483 } else { 484 if (!mPlugin->setListener(this).isOk()) { 485 mInitCheck = DEAD_OBJECT; 486 } else { 487 mInitCheck = OK; 488 } 489 } 490 491 return mInitCheck; 492} 493 494status_t DrmHal::destroyPlugin() { 495 Mutex::Autolock autoLock(mLock); 496 INIT_CHECK(); 497 498 closeOpenSessions(); 499 reportMetrics(); 500 setListener(NULL); 501 mInitCheck = NO_INIT; 502 503 if (mPlugin != NULL) { 504 if (!mPlugin->setListener(NULL).isOk()) { 505 mInitCheck = DEAD_OBJECT; 506 } 507 } 508 mPlugin.clear(); 509 mPluginV1_1.clear(); 510 return OK; 511} 512 513status_t DrmHal::openSession(Vector<uint8_t> &sessionId) { 514 Mutex::Autolock autoLock(mLock); 515 INIT_CHECK(); 516 517 status_t err = UNKNOWN_ERROR; 518 519 bool retry = true; 520 do { 521 hidl_vec<uint8_t> hSessionId; 522 523 Return<void> hResult = mPlugin->openSession( 524 [&](Status status, const hidl_vec<uint8_t>& id) { 525 if (status == Status::OK) { 526 sessionId = toVector(id); 527 } 528 err = toStatusT(status); 529 } 530 ); 531 532 if (!hResult.isOk()) { 533 err = DEAD_OBJECT; 534 } 535 536 if (err == ERROR_DRM_RESOURCE_BUSY && retry) { 537 mLock.unlock(); 538 // reclaimSession may call back to closeSession, since mLock is 539 // shared between Drm instances, we should unlock here to avoid 540 // deadlock. 541 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); 542 mLock.lock(); 543 } else { 544 retry = false; 545 } 546 } while (retry); 547 548 if (err == OK) { 549 DrmSessionManager::Instance()->addSession(getCallingPid(), 550 mDrmSessionClient, sessionId); 551 mOpenSessions.push(sessionId); 552 } 553 554 mMetrics.mOpenSessionCounter.Increment(err); 555 return err; 556} 557 558status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { 559 Mutex::Autolock autoLock(mLock); 560 INIT_CHECK(); 561 562 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId)); 563 if (status.isOk()) { 564 if (status == Status::OK) { 565 DrmSessionManager::Instance()->removeSession(sessionId); 566 for (size_t i = 0; i < mOpenSessions.size(); i++) { 567 if (mOpenSessions[i] == sessionId) { 568 mOpenSessions.removeAt(i); 569 break; 570 } 571 } 572 } 573 reportMetrics(); 574 status_t response = toStatusT(status); 575 mMetrics.mCloseSessionCounter.Increment(response); 576 return response; 577 } 578 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT); 579 return DEAD_OBJECT; 580} 581 582status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, 583 Vector<uint8_t> const &initData, String8 const &mimeType, 584 DrmPlugin::KeyType keyType, KeyedVector<String8, 585 String8> const &optionalParameters, Vector<uint8_t> &request, 586 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) { 587 Mutex::Autolock autoLock(mLock); 588 INIT_CHECK(); 589 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming); 590 591 DrmSessionManager::Instance()->useSession(sessionId); 592 593 KeyType hKeyType; 594 if (keyType == DrmPlugin::kKeyType_Streaming) { 595 hKeyType = KeyType::STREAMING; 596 } else if (keyType == DrmPlugin::kKeyType_Offline) { 597 hKeyType = KeyType::OFFLINE; 598 } else if (keyType == DrmPlugin::kKeyType_Release) { 599 hKeyType = KeyType::RELEASE; 600 } else { 601 keyRequestTimer.SetAttribute(BAD_VALUE); 602 return BAD_VALUE; 603 } 604 605 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters); 606 607 status_t err = UNKNOWN_ERROR; 608 609 if (mPluginV1_1 != NULL) { 610 Return<void> hResult = 611 mPluginV1_1->getKeyRequest_1_1( 612 toHidlVec(sessionId), toHidlVec(initData), 613 toHidlString(mimeType), hKeyType, hOptionalParameters, 614 [&](Status status, const hidl_vec<uint8_t>& hRequest, 615 drm::V1_1::KeyRequestType hKeyRequestType, 616 const hidl_string& hDefaultUrl) { 617 618 if (status == Status::OK) { 619 request = toVector(hRequest); 620 defaultUrl = toString8(hDefaultUrl); 621 622 switch (hKeyRequestType) { 623 case drm::V1_1::KeyRequestType::INITIAL: 624 *keyRequestType = DrmPlugin::kKeyRequestType_Initial; 625 break; 626 case drm::V1_1::KeyRequestType::RENEWAL: 627 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal; 628 break; 629 case drm::V1_1::KeyRequestType::RELEASE: 630 *keyRequestType = DrmPlugin::kKeyRequestType_Release; 631 break; 632 case drm::V1_1::KeyRequestType::NONE: 633 *keyRequestType = DrmPlugin::kKeyRequestType_None; 634 break; 635 case drm::V1_1::KeyRequestType::UPDATE: 636 *keyRequestType = DrmPlugin::kKeyRequestType_Update; 637 break; 638 default: 639 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown; 640 break; 641 } 642 err = toStatusT(status); 643 } 644 }); 645 return hResult.isOk() ? err : DEAD_OBJECT; 646 } 647 648 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId), 649 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters, 650 [&](Status status, const hidl_vec<uint8_t>& hRequest, 651 drm::V1_0::KeyRequestType hKeyRequestType, 652 const hidl_string& hDefaultUrl) { 653 654 if (status == Status::OK) { 655 request = toVector(hRequest); 656 defaultUrl = toString8(hDefaultUrl); 657 658 switch (hKeyRequestType) { 659 case drm::V1_0::KeyRequestType::INITIAL: 660 *keyRequestType = DrmPlugin::kKeyRequestType_Initial; 661 break; 662 case drm::V1_0::KeyRequestType::RENEWAL: 663 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal; 664 break; 665 case drm::V1_0::KeyRequestType::RELEASE: 666 *keyRequestType = DrmPlugin::kKeyRequestType_Release; 667 break; 668 default: 669 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown; 670 break; 671 } 672 err = toStatusT(status); 673 } 674 }); 675 676 err = hResult.isOk() ? err : DEAD_OBJECT; 677 keyRequestTimer.SetAttribute(err); 678 return err; 679} 680 681status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, 682 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { 683 Mutex::Autolock autoLock(mLock); 684 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming); 685 686 INIT_CHECK(); 687 688 DrmSessionManager::Instance()->useSession(sessionId); 689 690 status_t err = UNKNOWN_ERROR; 691 692 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId), 693 toHidlVec(response), 694 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) { 695 if (status == Status::OK) { 696 keySetId = toVector(hKeySetId); 697 } 698 err = toStatusT(status); 699 } 700 ); 701 err = hResult.isOk() ? err : DEAD_OBJECT; 702 keyResponseTimer.SetAttribute(err); 703 return err; 704} 705 706status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { 707 Mutex::Autolock autoLock(mLock); 708 INIT_CHECK(); 709 710 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId))); 711} 712 713status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId, 714 Vector<uint8_t> const &keySetId) { 715 Mutex::Autolock autoLock(mLock); 716 INIT_CHECK(); 717 718 DrmSessionManager::Instance()->useSession(sessionId); 719 720 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId), 721 toHidlVec(keySetId))); 722} 723 724status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId, 725 KeyedVector<String8, String8> &infoMap) const { 726 Mutex::Autolock autoLock(mLock); 727 INIT_CHECK(); 728 729 DrmSessionManager::Instance()->useSession(sessionId); 730 731 ::KeyedVector hInfoMap; 732 733 status_t err = UNKNOWN_ERROR; 734 735 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId), 736 [&](Status status, const hidl_vec<KeyValue>& map) { 737 if (status == Status::OK) { 738 infoMap = toKeyedVector(map); 739 } 740 err = toStatusT(status); 741 } 742 ); 743 744 return hResult.isOk() ? err : DEAD_OBJECT; 745} 746 747status_t DrmHal::getProvisionRequest(String8 const &certType, 748 String8 const &certAuthority, Vector<uint8_t> &request, 749 String8 &defaultUrl) { 750 Mutex::Autolock autoLock(mLock); 751 INIT_CHECK(); 752 753 status_t err = UNKNOWN_ERROR; 754 755 Return<void> hResult = mPlugin->getProvisionRequest( 756 toHidlString(certType), toHidlString(certAuthority), 757 [&](Status status, const hidl_vec<uint8_t>& hRequest, 758 const hidl_string& hDefaultUrl) { 759 if (status == Status::OK) { 760 request = toVector(hRequest); 761 defaultUrl = toString8(hDefaultUrl); 762 } 763 err = toStatusT(status); 764 } 765 ); 766 767 err = hResult.isOk() ? err : DEAD_OBJECT; 768 mMetrics.mGetProvisionRequestCounter.Increment(err); 769 return err; 770} 771 772status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, 773 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 774 Mutex::Autolock autoLock(mLock); 775 INIT_CHECK(); 776 777 status_t err = UNKNOWN_ERROR; 778 779 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response), 780 [&](Status status, const hidl_vec<uint8_t>& hCertificate, 781 const hidl_vec<uint8_t>& hWrappedKey) { 782 if (status == Status::OK) { 783 certificate = toVector(hCertificate); 784 wrappedKey = toVector(hWrappedKey); 785 } 786 err = toStatusT(status); 787 } 788 ); 789 790 err = hResult.isOk() ? err : DEAD_OBJECT; 791 mMetrics.mProvideProvisionResponseCounter.Increment(err); 792 return err; 793} 794 795status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { 796 Mutex::Autolock autoLock(mLock); 797 INIT_CHECK(); 798 799 status_t err = UNKNOWN_ERROR; 800 801 Return<void> hResult = mPlugin->getSecureStops( 802 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) { 803 if (status == Status::OK) { 804 secureStops = toSecureStops(hSecureStops); 805 } 806 err = toStatusT(status); 807 } 808 ); 809 810 return hResult.isOk() ? err : DEAD_OBJECT; 811} 812 813 814status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) { 815 Mutex::Autolock autoLock(mLock); 816 817 if (mInitCheck != OK) { 818 return mInitCheck; 819 } 820 821 if (mPluginV1_1 == NULL) { 822 return ERROR_DRM_CANNOT_HANDLE; 823 } 824 825 status_t err = UNKNOWN_ERROR; 826 827 Return<void> hResult = mPluginV1_1->getSecureStopIds( 828 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) { 829 if (status == Status::OK) { 830 secureStopIds = toSecureStopIds(hSecureStopIds); 831 } 832 err = toStatusT(status); 833 } 834 ); 835 836 return hResult.isOk() ? err : DEAD_OBJECT; 837} 838 839 840status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { 841 Mutex::Autolock autoLock(mLock); 842 INIT_CHECK(); 843 844 status_t err = UNKNOWN_ERROR; 845 846 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid), 847 [&](Status status, const SecureStop& hSecureStop) { 848 if (status == Status::OK) { 849 secureStop = toVector(hSecureStop.opaqueData); 850 } 851 err = toStatusT(status); 852 } 853 ); 854 855 return hResult.isOk() ? err : DEAD_OBJECT; 856} 857 858status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) { 859 Mutex::Autolock autoLock(mLock); 860 INIT_CHECK(); 861 862 if (mPluginV1_1 != NULL) { 863 SecureStopRelease secureStopRelease; 864 secureStopRelease.opaqueData = toHidlVec(ssRelease); 865 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease)); 866 } 867 868 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease))); 869} 870 871status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) { 872 Mutex::Autolock autoLock(mLock); 873 874 if (mInitCheck != OK) { 875 return mInitCheck; 876 } 877 878 if (mPluginV1_1 == NULL) { 879 return ERROR_DRM_CANNOT_HANDLE; 880 } 881 882 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid))); 883} 884 885status_t DrmHal::removeAllSecureStops() { 886 Mutex::Autolock autoLock(mLock); 887 INIT_CHECK(); 888 889 if (mPluginV1_1 != NULL) { 890 return toStatusT(mPluginV1_1->removeAllSecureStops()); 891 } 892 return toStatusT(mPlugin->releaseAllSecureStops()); 893} 894 895status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected, 896 DrmPlugin::HdcpLevel *max) const { 897 Mutex::Autolock autoLock(mLock); 898 INIT_CHECK(); 899 900 if (connected == NULL || max == NULL) { 901 return BAD_VALUE; 902 } 903 status_t err = UNKNOWN_ERROR; 904 905 if (mPluginV1_1 == NULL) { 906 return ERROR_DRM_CANNOT_HANDLE; 907 } 908 909 *connected = DrmPlugin::kHdcpLevelUnknown; 910 *max = DrmPlugin::kHdcpLevelUnknown; 911 912 Return<void> hResult = mPluginV1_1->getHdcpLevels( 913 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) { 914 if (status == Status::OK) { 915 *connected = toHdcpLevel(hConnected); 916 *max = toHdcpLevel(hMax); 917 } 918 err = toStatusT(status); 919 } 920 ); 921 922 return hResult.isOk() ? err : DEAD_OBJECT; 923} 924 925status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const { 926 Mutex::Autolock autoLock(mLock); 927 INIT_CHECK(); 928 929 if (open == NULL || max == NULL) { 930 return BAD_VALUE; 931 } 932 status_t err = UNKNOWN_ERROR; 933 934 *open = 0; 935 *max = 0; 936 937 if (mPluginV1_1 == NULL) { 938 return ERROR_DRM_CANNOT_HANDLE; 939 } 940 941 Return<void> hResult = mPluginV1_1->getNumberOfSessions( 942 [&](Status status, uint32_t hOpen, uint32_t hMax) { 943 if (status == Status::OK) { 944 *open = hOpen; 945 *max = hMax; 946 } 947 err = toStatusT(status); 948 } 949 ); 950 951 return hResult.isOk() ? err : DEAD_OBJECT; 952} 953 954status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId, 955 DrmPlugin::SecurityLevel *level) const { 956 Mutex::Autolock autoLock(mLock); 957 INIT_CHECK(); 958 959 if (level == NULL) { 960 return BAD_VALUE; 961 } 962 status_t err = UNKNOWN_ERROR; 963 964 if (mPluginV1_1 == NULL) { 965 return ERROR_DRM_CANNOT_HANDLE; 966 } 967 968 *level = DrmPlugin::kSecurityLevelUnknown; 969 970 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId), 971 [&](Status status, SecurityLevel hLevel) { 972 if (status == Status::OK) { 973 *level = toSecurityLevel(hLevel); 974 } 975 err = toStatusT(status); 976 } 977 ); 978 979 return hResult.isOk() ? err : DEAD_OBJECT; 980} 981 982status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId, 983 const DrmPlugin::SecurityLevel& level) { 984 Mutex::Autolock autoLock(mLock); 985 INIT_CHECK(); 986 987 if (mPluginV1_1 == NULL) { 988 return ERROR_DRM_CANNOT_HANDLE; 989 } 990 991 SecurityLevel hSecurityLevel; 992 993 switch(level) { 994 case DrmPlugin::kSecurityLevelSwSecureCrypto: 995 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO; 996 break; 997 case DrmPlugin::kSecurityLevelSwSecureDecode: 998 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE; 999 break; 1000 case DrmPlugin::kSecurityLevelHwSecureCrypto: 1001 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO; 1002 break; 1003 case DrmPlugin::kSecurityLevelHwSecureDecode: 1004 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE; 1005 break; 1006 case DrmPlugin::kSecurityLevelHwSecureAll: 1007 hSecurityLevel = SecurityLevel::HW_SECURE_ALL; 1008 break; 1009 default: 1010 return ERROR_DRM_CANNOT_HANDLE; 1011 } 1012 1013 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId), 1014 hSecurityLevel); 1015 return toStatusT(status); 1016} 1017 1018status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const { 1019 Mutex::Autolock autoLock(mLock); 1020 return getPropertyStringInternal(name, value); 1021} 1022 1023status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const { 1024 // This function is internal to the class and should only be called while 1025 // mLock is already held. 1026 INIT_CHECK(); 1027 1028 status_t err = UNKNOWN_ERROR; 1029 1030 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name), 1031 [&](Status status, const hidl_string& hValue) { 1032 if (status == Status::OK) { 1033 value = toString8(hValue); 1034 } 1035 err = toStatusT(status); 1036 } 1037 ); 1038 1039 return hResult.isOk() ? err : DEAD_OBJECT; 1040} 1041 1042status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const { 1043 Mutex::Autolock autoLock(mLock); 1044 return getPropertyByteArrayInternal(name, value); 1045} 1046 1047status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const { 1048 // This function is internal to the class and should only be called while 1049 // mLock is already held. 1050 INIT_CHECK(); 1051 1052 status_t err = UNKNOWN_ERROR; 1053 1054 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name), 1055 [&](Status status, const hidl_vec<uint8_t>& hValue) { 1056 if (status == Status::OK) { 1057 value = toVector(hValue); 1058 } 1059 err = toStatusT(status); 1060 } 1061 ); 1062 1063 err = hResult.isOk() ? err : DEAD_OBJECT; 1064 if (name == kPropertyDeviceUniqueId) { 1065 mMetrics.mGetDeviceUniqueIdCounter.Increment(err); 1066 } 1067 return err; 1068} 1069 1070status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { 1071 Mutex::Autolock autoLock(mLock); 1072 INIT_CHECK(); 1073 1074 Status status = mPlugin->setPropertyString(toHidlString(name), 1075 toHidlString(value)); 1076 return toStatusT(status); 1077} 1078 1079status_t DrmHal::setPropertyByteArray(String8 const &name, 1080 Vector<uint8_t> const &value ) const { 1081 Mutex::Autolock autoLock(mLock); 1082 INIT_CHECK(); 1083 1084 Status status = mPlugin->setPropertyByteArray(toHidlString(name), 1085 toHidlVec(value)); 1086 return toStatusT(status); 1087} 1088 1089status_t DrmHal::getMetrics(MediaAnalyticsItem* item) { 1090 if (item == nullptr) { 1091 return UNEXPECTED_NULL; 1092 } 1093 1094 mMetrics.Export(item); 1095 return OK; 1096} 1097 1098status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId, 1099 String8 const &algorithm) { 1100 Mutex::Autolock autoLock(mLock); 1101 INIT_CHECK(); 1102 1103 DrmSessionManager::Instance()->useSession(sessionId); 1104 1105 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId), 1106 toHidlString(algorithm)); 1107 return toStatusT(status); 1108} 1109 1110status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId, 1111 String8 const &algorithm) { 1112 Mutex::Autolock autoLock(mLock); 1113 INIT_CHECK(); 1114 1115 DrmSessionManager::Instance()->useSession(sessionId); 1116 1117 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), 1118 toHidlString(algorithm)); 1119 return toStatusT(status); 1120} 1121 1122status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId, 1123 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 1124 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 1125 Mutex::Autolock autoLock(mLock); 1126 INIT_CHECK(); 1127 1128 DrmSessionManager::Instance()->useSession(sessionId); 1129 1130 status_t err = UNKNOWN_ERROR; 1131 1132 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId), 1133 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 1134 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 1135 if (status == Status::OK) { 1136 output = toVector(hOutput); 1137 } 1138 err = toStatusT(status); 1139 } 1140 ); 1141 1142 return hResult.isOk() ? err : DEAD_OBJECT; 1143} 1144 1145status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId, 1146 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 1147 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 1148 Mutex::Autolock autoLock(mLock); 1149 INIT_CHECK(); 1150 1151 DrmSessionManager::Instance()->useSession(sessionId); 1152 1153 status_t err = UNKNOWN_ERROR; 1154 1155 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId), 1156 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 1157 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 1158 if (status == Status::OK) { 1159 output = toVector(hOutput); 1160 } 1161 err = toStatusT(status); 1162 } 1163 ); 1164 1165 return hResult.isOk() ? err : DEAD_OBJECT; 1166} 1167 1168status_t DrmHal::sign(Vector<uint8_t> const &sessionId, 1169 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 1170 Vector<uint8_t> &signature) { 1171 Mutex::Autolock autoLock(mLock); 1172 INIT_CHECK(); 1173 1174 DrmSessionManager::Instance()->useSession(sessionId); 1175 1176 status_t err = UNKNOWN_ERROR; 1177 1178 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), 1179 toHidlVec(keyId), toHidlVec(message), 1180 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 1181 if (status == Status::OK) { 1182 signature = toVector(hSignature); 1183 } 1184 err = toStatusT(status); 1185 } 1186 ); 1187 1188 return hResult.isOk() ? err : DEAD_OBJECT; 1189} 1190 1191status_t DrmHal::verify(Vector<uint8_t> const &sessionId, 1192 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 1193 Vector<uint8_t> const &signature, bool &match) { 1194 Mutex::Autolock autoLock(mLock); 1195 INIT_CHECK(); 1196 1197 DrmSessionManager::Instance()->useSession(sessionId); 1198 1199 status_t err = UNKNOWN_ERROR; 1200 1201 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId), 1202 toHidlVec(message), toHidlVec(signature), 1203 [&](Status status, bool hMatch) { 1204 if (status == Status::OK) { 1205 match = hMatch; 1206 } else { 1207 match = false; 1208 } 1209 err = toStatusT(status); 1210 } 1211 ); 1212 1213 return hResult.isOk() ? err : DEAD_OBJECT; 1214} 1215 1216status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId, 1217 String8 const &algorithm, Vector<uint8_t> const &message, 1218 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 1219 Mutex::Autolock autoLock(mLock); 1220 INIT_CHECK(); 1221 1222 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) { 1223 return -EPERM; 1224 } 1225 1226 DrmSessionManager::Instance()->useSession(sessionId); 1227 1228 status_t err = UNKNOWN_ERROR; 1229 1230 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId), 1231 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey), 1232 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 1233 if (status == Status::OK) { 1234 signature = toVector(hSignature); 1235 } 1236 err = toStatusT(status); 1237 } 1238 ); 1239 1240 return hResult.isOk() ? err : DEAD_OBJECT; 1241} 1242 1243void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused) 1244{ 1245 Mutex::Autolock autoLock(mLock); 1246 closeOpenSessions(); 1247 setListener(NULL); 1248 mInitCheck = NO_INIT; 1249 1250 if (mPlugin != NULL) { 1251 if (!mPlugin->setListener(NULL).isOk()) { 1252 mInitCheck = DEAD_OBJECT; 1253 } 1254 } 1255 mPlugin.clear(); 1256} 1257 1258void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec) 1259{ 1260 if (vec.size()) { 1261 obj.writeInt32(vec.size()); 1262 obj.write(vec.data(), vec.size()); 1263 } else { 1264 obj.writeInt32(0); 1265 } 1266} 1267 1268 1269void DrmHal::reportMetrics() const 1270{ 1271 Vector<uint8_t> metrics; 1272 String8 vendor; 1273 String8 description; 1274 if (getPropertyStringInternal(String8("vendor"), vendor) == OK && 1275 getPropertyStringInternal(String8("description"), description) == OK && 1276 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) { 1277 status_t res = android::reportDrmPluginMetrics( 1278 metrics, vendor, description); 1279 if (res != OK) { 1280 ALOGE("Metrics were retrieved but could not be reported: %i", res); 1281 } 1282 } 1283} 1284 1285} // namespace android 1286