DrmHal.cpp revision 15177d7eab8c2300b4f1d577267e528bd7e4eedc
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 auto openSessions = mOpenSessions; 256 for (size_t i = 0; i < openSessions.size(); i++) { 257 closeSession(openSessions[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 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin); 476 } 477 } 478 479 if (mPlugin == NULL) { 480 mInitCheck = ERROR_UNSUPPORTED; 481 } else { 482 if (!mPlugin->setListener(this).isOk()) { 483 mInitCheck = DEAD_OBJECT; 484 } else { 485 mInitCheck = OK; 486 } 487 } 488 489 return mInitCheck; 490} 491 492status_t DrmHal::destroyPlugin() { 493 Mutex::Autolock autoLock(mLock); 494 INIT_CHECK(); 495 496 closeOpenSessions(); 497 reportMetrics(); 498 setListener(NULL); 499 mInitCheck = NO_INIT; 500 501 if (mPlugin != NULL) { 502 if (!mPlugin->setListener(NULL).isOk()) { 503 mInitCheck = DEAD_OBJECT; 504 } 505 } 506 mPlugin.clear(); 507 return OK; 508} 509 510status_t DrmHal::openSession(Vector<uint8_t> &sessionId) { 511 Mutex::Autolock autoLock(mLock); 512 INIT_CHECK(); 513 514 status_t err = UNKNOWN_ERROR; 515 516 bool retry = true; 517 do { 518 hidl_vec<uint8_t> hSessionId; 519 520 Return<void> hResult = mPlugin->openSession( 521 [&](Status status, const hidl_vec<uint8_t>& id) { 522 if (status == Status::OK) { 523 sessionId = toVector(id); 524 } 525 err = toStatusT(status); 526 } 527 ); 528 529 if (!hResult.isOk()) { 530 err = DEAD_OBJECT; 531 } 532 533 if (err == ERROR_DRM_RESOURCE_BUSY && retry) { 534 mLock.unlock(); 535 // reclaimSession may call back to closeSession, since mLock is 536 // shared between Drm instances, we should unlock here to avoid 537 // deadlock. 538 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); 539 mLock.lock(); 540 } else { 541 retry = false; 542 } 543 } while (retry); 544 545 if (err == OK) { 546 DrmSessionManager::Instance()->addSession(getCallingPid(), 547 mDrmSessionClient, sessionId); 548 mOpenSessions.push(sessionId); 549 } 550 551 mMetrics.mOpenSessionCounter.Increment(err); 552 return err; 553} 554 555status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { 556 Mutex::Autolock autoLock(mLock); 557 INIT_CHECK(); 558 559 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId)); 560 if (status.isOk()) { 561 if (status == Status::OK) { 562 DrmSessionManager::Instance()->removeSession(sessionId); 563 for (size_t i = 0; i < mOpenSessions.size(); i++) { 564 if (mOpenSessions[i] == sessionId) { 565 mOpenSessions.removeAt(i); 566 break; 567 } 568 } 569 } 570 reportMetrics(); 571 status_t response = toStatusT(status); 572 mMetrics.mCloseSessionCounter.Increment(response); 573 return response; 574 } 575 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT); 576 return DEAD_OBJECT; 577} 578 579status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, 580 Vector<uint8_t> const &initData, String8 const &mimeType, 581 DrmPlugin::KeyType keyType, KeyedVector<String8, 582 String8> const &optionalParameters, Vector<uint8_t> &request, 583 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) { 584 Mutex::Autolock autoLock(mLock); 585 INIT_CHECK(); 586 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming); 587 588 DrmSessionManager::Instance()->useSession(sessionId); 589 590 KeyType hKeyType; 591 if (keyType == DrmPlugin::kKeyType_Streaming) { 592 hKeyType = KeyType::STREAMING; 593 } else if (keyType == DrmPlugin::kKeyType_Offline) { 594 hKeyType = KeyType::OFFLINE; 595 } else if (keyType == DrmPlugin::kKeyType_Release) { 596 hKeyType = KeyType::RELEASE; 597 } else { 598 keyRequestTimer.SetAttribute(BAD_VALUE); 599 return BAD_VALUE; 600 } 601 602 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters); 603 604 status_t err = UNKNOWN_ERROR; 605 606 if (mPluginV1_1 != NULL) { 607 Return<void> hResult = 608 mPluginV1_1->getKeyRequest_1_1( 609 toHidlVec(sessionId), toHidlVec(initData), 610 toHidlString(mimeType), hKeyType, hOptionalParameters, 611 [&](Status status, const hidl_vec<uint8_t>& hRequest, 612 drm::V1_1::KeyRequestType hKeyRequestType, 613 const hidl_string& hDefaultUrl) { 614 615 if (status == Status::OK) { 616 request = toVector(hRequest); 617 defaultUrl = toString8(hDefaultUrl); 618 619 switch (hKeyRequestType) { 620 case drm::V1_1::KeyRequestType::INITIAL: 621 *keyRequestType = DrmPlugin::kKeyRequestType_Initial; 622 break; 623 case drm::V1_1::KeyRequestType::RENEWAL: 624 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal; 625 break; 626 case drm::V1_1::KeyRequestType::RELEASE: 627 *keyRequestType = DrmPlugin::kKeyRequestType_Release; 628 break; 629 case drm::V1_1::KeyRequestType::NONE: 630 *keyRequestType = DrmPlugin::kKeyRequestType_None; 631 break; 632 case drm::V1_1::KeyRequestType::UPDATE: 633 *keyRequestType = DrmPlugin::kKeyRequestType_Update; 634 break; 635 default: 636 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown; 637 break; 638 } 639 err = toStatusT(status); 640 } 641 }); 642 return hResult.isOk() ? err : DEAD_OBJECT; 643 } 644 645 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId), 646 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters, 647 [&](Status status, const hidl_vec<uint8_t>& hRequest, 648 drm::V1_0::KeyRequestType hKeyRequestType, 649 const hidl_string& hDefaultUrl) { 650 651 if (status == Status::OK) { 652 request = toVector(hRequest); 653 defaultUrl = toString8(hDefaultUrl); 654 655 switch (hKeyRequestType) { 656 case drm::V1_0::KeyRequestType::INITIAL: 657 *keyRequestType = DrmPlugin::kKeyRequestType_Initial; 658 break; 659 case drm::V1_0::KeyRequestType::RENEWAL: 660 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal; 661 break; 662 case drm::V1_0::KeyRequestType::RELEASE: 663 *keyRequestType = DrmPlugin::kKeyRequestType_Release; 664 break; 665 default: 666 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown; 667 break; 668 } 669 err = toStatusT(status); 670 } 671 }); 672 673 err = hResult.isOk() ? err : DEAD_OBJECT; 674 keyRequestTimer.SetAttribute(err); 675 return err; 676} 677 678status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, 679 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { 680 Mutex::Autolock autoLock(mLock); 681 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming); 682 683 INIT_CHECK(); 684 685 DrmSessionManager::Instance()->useSession(sessionId); 686 687 status_t err = UNKNOWN_ERROR; 688 689 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId), 690 toHidlVec(response), 691 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) { 692 if (status == Status::OK) { 693 keySetId = toVector(hKeySetId); 694 } 695 err = toStatusT(status); 696 } 697 ); 698 err = hResult.isOk() ? err : DEAD_OBJECT; 699 keyResponseTimer.SetAttribute(err); 700 return err; 701} 702 703status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { 704 Mutex::Autolock autoLock(mLock); 705 INIT_CHECK(); 706 707 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId))); 708} 709 710status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId, 711 Vector<uint8_t> const &keySetId) { 712 Mutex::Autolock autoLock(mLock); 713 INIT_CHECK(); 714 715 DrmSessionManager::Instance()->useSession(sessionId); 716 717 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId), 718 toHidlVec(keySetId))); 719} 720 721status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId, 722 KeyedVector<String8, String8> &infoMap) const { 723 Mutex::Autolock autoLock(mLock); 724 INIT_CHECK(); 725 726 DrmSessionManager::Instance()->useSession(sessionId); 727 728 ::KeyedVector hInfoMap; 729 730 status_t err = UNKNOWN_ERROR; 731 732 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId), 733 [&](Status status, const hidl_vec<KeyValue>& map) { 734 if (status == Status::OK) { 735 infoMap = toKeyedVector(map); 736 } 737 err = toStatusT(status); 738 } 739 ); 740 741 return hResult.isOk() ? err : DEAD_OBJECT; 742} 743 744status_t DrmHal::getProvisionRequest(String8 const &certType, 745 String8 const &certAuthority, Vector<uint8_t> &request, 746 String8 &defaultUrl) { 747 Mutex::Autolock autoLock(mLock); 748 INIT_CHECK(); 749 750 status_t err = UNKNOWN_ERROR; 751 752 Return<void> hResult = mPlugin->getProvisionRequest( 753 toHidlString(certType), toHidlString(certAuthority), 754 [&](Status status, const hidl_vec<uint8_t>& hRequest, 755 const hidl_string& hDefaultUrl) { 756 if (status == Status::OK) { 757 request = toVector(hRequest); 758 defaultUrl = toString8(hDefaultUrl); 759 } 760 err = toStatusT(status); 761 } 762 ); 763 764 err = hResult.isOk() ? err : DEAD_OBJECT; 765 mMetrics.mGetProvisionRequestCounter.Increment(err); 766 return err; 767} 768 769status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, 770 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 771 Mutex::Autolock autoLock(mLock); 772 INIT_CHECK(); 773 774 status_t err = UNKNOWN_ERROR; 775 776 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response), 777 [&](Status status, const hidl_vec<uint8_t>& hCertificate, 778 const hidl_vec<uint8_t>& hWrappedKey) { 779 if (status == Status::OK) { 780 certificate = toVector(hCertificate); 781 wrappedKey = toVector(hWrappedKey); 782 } 783 err = toStatusT(status); 784 } 785 ); 786 787 err = hResult.isOk() ? err : DEAD_OBJECT; 788 mMetrics.mProvideProvisionResponseCounter.Increment(err); 789 return err; 790} 791 792status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { 793 Mutex::Autolock autoLock(mLock); 794 INIT_CHECK(); 795 796 status_t err = UNKNOWN_ERROR; 797 798 Return<void> hResult = mPlugin->getSecureStops( 799 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) { 800 if (status == Status::OK) { 801 secureStops = toSecureStops(hSecureStops); 802 } 803 err = toStatusT(status); 804 } 805 ); 806 807 return hResult.isOk() ? err : DEAD_OBJECT; 808} 809 810 811status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) { 812 Mutex::Autolock autoLock(mLock); 813 814 if (mInitCheck != OK) { 815 return mInitCheck; 816 } 817 818 if (mPluginV1_1 == NULL) { 819 return ERROR_DRM_CANNOT_HANDLE; 820 } 821 822 status_t err = UNKNOWN_ERROR; 823 824 Return<void> hResult = mPluginV1_1->getSecureStopIds( 825 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) { 826 if (status == Status::OK) { 827 secureStopIds = toSecureStopIds(hSecureStopIds); 828 } 829 err = toStatusT(status); 830 } 831 ); 832 833 return hResult.isOk() ? err : DEAD_OBJECT; 834} 835 836 837status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { 838 Mutex::Autolock autoLock(mLock); 839 INIT_CHECK(); 840 841 status_t err = UNKNOWN_ERROR; 842 843 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid), 844 [&](Status status, const SecureStop& hSecureStop) { 845 if (status == Status::OK) { 846 secureStop = toVector(hSecureStop.opaqueData); 847 } 848 err = toStatusT(status); 849 } 850 ); 851 852 return hResult.isOk() ? err : DEAD_OBJECT; 853} 854 855status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) { 856 Mutex::Autolock autoLock(mLock); 857 INIT_CHECK(); 858 859 if (mPluginV1_1 != NULL) { 860 SecureStopRelease secureStopRelease; 861 secureStopRelease.opaqueData = toHidlVec(ssRelease); 862 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease)); 863 } 864 865 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease))); 866} 867 868status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) { 869 Mutex::Autolock autoLock(mLock); 870 871 if (mInitCheck != OK) { 872 return mInitCheck; 873 } 874 875 if (mPluginV1_1 == NULL) { 876 return ERROR_DRM_CANNOT_HANDLE; 877 } 878 879 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid))); 880} 881 882status_t DrmHal::removeAllSecureStops() { 883 Mutex::Autolock autoLock(mLock); 884 INIT_CHECK(); 885 886 if (mPluginV1_1 != NULL) { 887 return toStatusT(mPluginV1_1->removeAllSecureStops()); 888 } 889 return toStatusT(mPlugin->releaseAllSecureStops()); 890} 891 892status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected, 893 DrmPlugin::HdcpLevel *max) const { 894 Mutex::Autolock autoLock(mLock); 895 INIT_CHECK(); 896 897 if (connected == NULL || max == NULL) { 898 return BAD_VALUE; 899 } 900 status_t err = UNKNOWN_ERROR; 901 902 if (mPluginV1_1 == NULL) { 903 return ERROR_DRM_CANNOT_HANDLE; 904 } 905 906 *connected = DrmPlugin::kHdcpLevelUnknown; 907 *max = DrmPlugin::kHdcpLevelUnknown; 908 909 Return<void> hResult = mPluginV1_1->getHdcpLevels( 910 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) { 911 if (status == Status::OK) { 912 *connected = toHdcpLevel(hConnected); 913 *max = toHdcpLevel(hMax); 914 } 915 err = toStatusT(status); 916 } 917 ); 918 919 return hResult.isOk() ? err : DEAD_OBJECT; 920} 921 922status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const { 923 Mutex::Autolock autoLock(mLock); 924 INIT_CHECK(); 925 926 if (open == NULL || max == NULL) { 927 return BAD_VALUE; 928 } 929 status_t err = UNKNOWN_ERROR; 930 931 *open = 0; 932 *max = 0; 933 934 if (mPluginV1_1 == NULL) { 935 return ERROR_DRM_CANNOT_HANDLE; 936 } 937 938 Return<void> hResult = mPluginV1_1->getNumberOfSessions( 939 [&](Status status, uint32_t hOpen, uint32_t hMax) { 940 if (status == Status::OK) { 941 *open = hOpen; 942 *max = hMax; 943 } 944 err = toStatusT(status); 945 } 946 ); 947 948 return hResult.isOk() ? err : DEAD_OBJECT; 949} 950 951status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId, 952 DrmPlugin::SecurityLevel *level) const { 953 Mutex::Autolock autoLock(mLock); 954 INIT_CHECK(); 955 956 if (level == NULL) { 957 return BAD_VALUE; 958 } 959 status_t err = UNKNOWN_ERROR; 960 961 if (mPluginV1_1 == NULL) { 962 return ERROR_DRM_CANNOT_HANDLE; 963 } 964 965 *level = DrmPlugin::kSecurityLevelUnknown; 966 967 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId), 968 [&](Status status, SecurityLevel hLevel) { 969 if (status == Status::OK) { 970 *level = toSecurityLevel(hLevel); 971 } 972 err = toStatusT(status); 973 } 974 ); 975 976 return hResult.isOk() ? err : DEAD_OBJECT; 977} 978 979status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId, 980 const DrmPlugin::SecurityLevel& level) { 981 Mutex::Autolock autoLock(mLock); 982 INIT_CHECK(); 983 984 if (mPluginV1_1 == NULL) { 985 return ERROR_DRM_CANNOT_HANDLE; 986 } 987 988 SecurityLevel hSecurityLevel; 989 990 switch(level) { 991 case DrmPlugin::kSecurityLevelSwSecureCrypto: 992 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO; 993 break; 994 case DrmPlugin::kSecurityLevelSwSecureDecode: 995 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE; 996 break; 997 case DrmPlugin::kSecurityLevelHwSecureCrypto: 998 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO; 999 break; 1000 case DrmPlugin::kSecurityLevelHwSecureDecode: 1001 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE; 1002 break; 1003 case DrmPlugin::kSecurityLevelHwSecureAll: 1004 hSecurityLevel = SecurityLevel::HW_SECURE_ALL; 1005 break; 1006 default: 1007 return ERROR_DRM_CANNOT_HANDLE; 1008 } 1009 1010 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId), 1011 hSecurityLevel); 1012 return toStatusT(status); 1013} 1014 1015status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const { 1016 Mutex::Autolock autoLock(mLock); 1017 return getPropertyStringInternal(name, value); 1018} 1019 1020status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const { 1021 // This function is internal to the class and should only be called while 1022 // mLock is already held. 1023 INIT_CHECK(); 1024 1025 status_t err = UNKNOWN_ERROR; 1026 1027 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name), 1028 [&](Status status, const hidl_string& hValue) { 1029 if (status == Status::OK) { 1030 value = toString8(hValue); 1031 } 1032 err = toStatusT(status); 1033 } 1034 ); 1035 1036 return hResult.isOk() ? err : DEAD_OBJECT; 1037} 1038 1039status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const { 1040 Mutex::Autolock autoLock(mLock); 1041 return getPropertyByteArrayInternal(name, value); 1042} 1043 1044status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const { 1045 // This function is internal to the class and should only be called while 1046 // mLock is already held. 1047 INIT_CHECK(); 1048 1049 status_t err = UNKNOWN_ERROR; 1050 1051 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name), 1052 [&](Status status, const hidl_vec<uint8_t>& hValue) { 1053 if (status == Status::OK) { 1054 value = toVector(hValue); 1055 } 1056 err = toStatusT(status); 1057 } 1058 ); 1059 1060 err = hResult.isOk() ? err : DEAD_OBJECT; 1061 if (name == kPropertyDeviceUniqueId) { 1062 mMetrics.mGetDeviceUniqueIdCounter.Increment(err); 1063 } 1064 return err; 1065} 1066 1067status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { 1068 Mutex::Autolock autoLock(mLock); 1069 INIT_CHECK(); 1070 1071 Status status = mPlugin->setPropertyString(toHidlString(name), 1072 toHidlString(value)); 1073 return toStatusT(status); 1074} 1075 1076status_t DrmHal::setPropertyByteArray(String8 const &name, 1077 Vector<uint8_t> const &value ) const { 1078 Mutex::Autolock autoLock(mLock); 1079 INIT_CHECK(); 1080 1081 Status status = mPlugin->setPropertyByteArray(toHidlString(name), 1082 toHidlVec(value)); 1083 return toStatusT(status); 1084} 1085 1086status_t DrmHal::getMetrics(MediaAnalyticsItem* item) { 1087 if (item == nullptr) { 1088 return UNEXPECTED_NULL; 1089 } 1090 1091 mMetrics.Export(item); 1092 return OK; 1093} 1094 1095status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId, 1096 String8 const &algorithm) { 1097 Mutex::Autolock autoLock(mLock); 1098 INIT_CHECK(); 1099 1100 DrmSessionManager::Instance()->useSession(sessionId); 1101 1102 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId), 1103 toHidlString(algorithm)); 1104 return toStatusT(status); 1105} 1106 1107status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId, 1108 String8 const &algorithm) { 1109 Mutex::Autolock autoLock(mLock); 1110 INIT_CHECK(); 1111 1112 DrmSessionManager::Instance()->useSession(sessionId); 1113 1114 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), 1115 toHidlString(algorithm)); 1116 return toStatusT(status); 1117} 1118 1119status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId, 1120 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 1121 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 1122 Mutex::Autolock autoLock(mLock); 1123 INIT_CHECK(); 1124 1125 DrmSessionManager::Instance()->useSession(sessionId); 1126 1127 status_t err = UNKNOWN_ERROR; 1128 1129 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId), 1130 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 1131 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 1132 if (status == Status::OK) { 1133 output = toVector(hOutput); 1134 } 1135 err = toStatusT(status); 1136 } 1137 ); 1138 1139 return hResult.isOk() ? err : DEAD_OBJECT; 1140} 1141 1142status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId, 1143 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 1144 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 1145 Mutex::Autolock autoLock(mLock); 1146 INIT_CHECK(); 1147 1148 DrmSessionManager::Instance()->useSession(sessionId); 1149 1150 status_t err = UNKNOWN_ERROR; 1151 1152 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId), 1153 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 1154 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 1155 if (status == Status::OK) { 1156 output = toVector(hOutput); 1157 } 1158 err = toStatusT(status); 1159 } 1160 ); 1161 1162 return hResult.isOk() ? err : DEAD_OBJECT; 1163} 1164 1165status_t DrmHal::sign(Vector<uint8_t> const &sessionId, 1166 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 1167 Vector<uint8_t> &signature) { 1168 Mutex::Autolock autoLock(mLock); 1169 INIT_CHECK(); 1170 1171 DrmSessionManager::Instance()->useSession(sessionId); 1172 1173 status_t err = UNKNOWN_ERROR; 1174 1175 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), 1176 toHidlVec(keyId), toHidlVec(message), 1177 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 1178 if (status == Status::OK) { 1179 signature = toVector(hSignature); 1180 } 1181 err = toStatusT(status); 1182 } 1183 ); 1184 1185 return hResult.isOk() ? err : DEAD_OBJECT; 1186} 1187 1188status_t DrmHal::verify(Vector<uint8_t> const &sessionId, 1189 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 1190 Vector<uint8_t> const &signature, bool &match) { 1191 Mutex::Autolock autoLock(mLock); 1192 INIT_CHECK(); 1193 1194 DrmSessionManager::Instance()->useSession(sessionId); 1195 1196 status_t err = UNKNOWN_ERROR; 1197 1198 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId), 1199 toHidlVec(message), toHidlVec(signature), 1200 [&](Status status, bool hMatch) { 1201 if (status == Status::OK) { 1202 match = hMatch; 1203 } else { 1204 match = false; 1205 } 1206 err = toStatusT(status); 1207 } 1208 ); 1209 1210 return hResult.isOk() ? err : DEAD_OBJECT; 1211} 1212 1213status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId, 1214 String8 const &algorithm, Vector<uint8_t> const &message, 1215 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 1216 Mutex::Autolock autoLock(mLock); 1217 INIT_CHECK(); 1218 1219 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) { 1220 return -EPERM; 1221 } 1222 1223 DrmSessionManager::Instance()->useSession(sessionId); 1224 1225 status_t err = UNKNOWN_ERROR; 1226 1227 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId), 1228 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey), 1229 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 1230 if (status == Status::OK) { 1231 signature = toVector(hSignature); 1232 } 1233 err = toStatusT(status); 1234 } 1235 ); 1236 1237 return hResult.isOk() ? err : DEAD_OBJECT; 1238} 1239 1240void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused) 1241{ 1242 Mutex::Autolock autoLock(mLock); 1243 closeOpenSessions(); 1244 setListener(NULL); 1245 mInitCheck = NO_INIT; 1246 1247 if (mPlugin != NULL) { 1248 if (!mPlugin->setListener(NULL).isOk()) { 1249 mInitCheck = DEAD_OBJECT; 1250 } 1251 } 1252 mPlugin.clear(); 1253} 1254 1255void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec) 1256{ 1257 if (vec.size()) { 1258 obj.writeInt32(vec.size()); 1259 obj.write(vec.data(), vec.size()); 1260 } else { 1261 obj.writeInt32(0); 1262 } 1263} 1264 1265 1266void DrmHal::reportMetrics() const 1267{ 1268 Vector<uint8_t> metrics; 1269 String8 vendor; 1270 String8 description; 1271 if (getPropertyStringInternal(String8("vendor"), vendor) == OK && 1272 getPropertyStringInternal(String8("description"), description) == OK && 1273 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) { 1274 status_t res = android::reportDrmPluginMetrics( 1275 metrics, vendor, description); 1276 if (res != OK) { 1277 ALOGE("Metrics were retrieved but could not be reported: %i", res); 1278 } 1279 } 1280} 1281 1282} // namespace android 1283