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