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