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 261 if (!hResult.isOk()) { 262 ALOGE("createPlugin remote call failed"); 263 } 264 265 return plugin; 266} 267 268status_t DrmHal::initCheck() const { 269 return mInitCheck; 270} 271 272status_t DrmHal::setListener(const sp<IDrmClient>& listener) 273{ 274 Mutex::Autolock lock(mEventLock); 275 if (mListener != NULL){ 276 IInterface::asBinder(mListener)->unlinkToDeath(this); 277 } 278 if (listener != NULL) { 279 IInterface::asBinder(listener)->linkToDeath(this); 280 } 281 mListener = listener; 282 return NO_ERROR; 283} 284 285Return<void> DrmHal::sendEvent(EventType hEventType, 286 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { 287 288 mEventLock.lock(); 289 sp<IDrmClient> listener = mListener; 290 mEventLock.unlock(); 291 292 if (listener != NULL) { 293 Parcel obj; 294 writeByteArray(obj, sessionId); 295 writeByteArray(obj, data); 296 297 Mutex::Autolock lock(mNotifyLock); 298 DrmPlugin::EventType eventType; 299 switch(hEventType) { 300 case EventType::PROVISION_REQUIRED: 301 eventType = DrmPlugin::kDrmPluginEventProvisionRequired; 302 break; 303 case EventType::KEY_NEEDED: 304 eventType = DrmPlugin::kDrmPluginEventKeyNeeded; 305 break; 306 case EventType::KEY_EXPIRED: 307 eventType = DrmPlugin::kDrmPluginEventKeyExpired; 308 break; 309 case EventType::VENDOR_DEFINED: 310 eventType = DrmPlugin::kDrmPluginEventVendorDefined; 311 break; 312 case EventType::SESSION_RECLAIMED: 313 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed; 314 break; 315 default: 316 return Void(); 317 } 318 listener->notify(eventType, 0, &obj); 319 } 320 return Void(); 321} 322 323Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, 324 int64_t expiryTimeInMS) { 325 326 mEventLock.lock(); 327 sp<IDrmClient> listener = mListener; 328 mEventLock.unlock(); 329 330 if (listener != NULL) { 331 Parcel obj; 332 writeByteArray(obj, sessionId); 333 obj.writeInt64(expiryTimeInMS); 334 335 Mutex::Autolock lock(mNotifyLock); 336 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj); 337 } 338 return Void(); 339} 340 341Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId, 342 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) { 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 352 size_t nKeys = keyStatusList.size(); 353 obj.writeInt32(nKeys); 354 for (size_t i = 0; i < nKeys; ++i) { 355 const KeyStatus &keyStatus = keyStatusList[i]; 356 writeByteArray(obj, keyStatus.keyId); 357 uint32_t type; 358 switch(keyStatus.type) { 359 case KeyStatusType::USABLE: 360 type = DrmPlugin::kKeyStatusType_Usable; 361 break; 362 case KeyStatusType::EXPIRED: 363 type = DrmPlugin::kKeyStatusType_Expired; 364 break; 365 case KeyStatusType::OUTPUTNOTALLOWED: 366 type = DrmPlugin::kKeyStatusType_OutputNotAllowed; 367 break; 368 case KeyStatusType::STATUSPENDING: 369 type = DrmPlugin::kKeyStatusType_StatusPending; 370 break; 371 case KeyStatusType::INTERNALERROR: 372 default: 373 type = DrmPlugin::kKeyStatusType_InternalError; 374 break; 375 } 376 obj.writeInt32(type); 377 } 378 obj.writeInt32(hasNewUsableKey); 379 380 Mutex::Autolock lock(mNotifyLock); 381 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj); 382 } 383 return Void(); 384} 385 386bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) { 387 Mutex::Autolock autoLock(mLock); 388 389 for (size_t i = 0; i < mFactories.size(); i++) { 390 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 391 if (mimeType != "") { 392 if (mFactories[i]->isContentTypeSupported(mimeType.string())) { 393 return true; 394 } 395 } else { 396 return true; 397 } 398 } 399 } 400 return false; 401} 402 403status_t DrmHal::createPlugin(const uint8_t uuid[16], 404 const String8& appPackageName) { 405 Mutex::Autolock autoLock(mLock); 406 407 for (size_t i = 0; i < mFactories.size(); i++) { 408 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 409 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName); 410 } 411 } 412 413 if (mPlugin == NULL) { 414 mInitCheck = ERROR_UNSUPPORTED; 415 } else { 416 if (!mPlugin->setListener(this).isOk()) { 417 mInitCheck = DEAD_OBJECT; 418 } else { 419 mInitCheck = OK; 420 } 421 } 422 423 return mInitCheck; 424} 425 426status_t DrmHal::destroyPlugin() { 427 Mutex::Autolock autoLock(mLock); 428 if (mInitCheck != OK) { 429 return mInitCheck; 430 } 431 432 closeOpenSessions(); 433 reportMetrics(); 434 setListener(NULL); 435 mInitCheck = NO_INIT; 436 437 if (mPlugin != NULL) { 438 if (!mPlugin->setListener(NULL).isOk()) { 439 mInitCheck = DEAD_OBJECT; 440 } 441 } 442 mPlugin.clear(); 443 return OK; 444} 445 446status_t DrmHal::openSession(Vector<uint8_t> &sessionId) { 447 Mutex::Autolock autoLock(mLock); 448 449 if (mInitCheck != OK) { 450 return mInitCheck; 451 } 452 453 status_t err = UNKNOWN_ERROR; 454 455 bool retry = true; 456 do { 457 hidl_vec<uint8_t> hSessionId; 458 459 Return<void> hResult = mPlugin->openSession( 460 [&](Status status, const hidl_vec<uint8_t>& id) { 461 if (status == Status::OK) { 462 sessionId = toVector(id); 463 } 464 err = toStatusT(status); 465 } 466 ); 467 468 if (!hResult.isOk()) { 469 err = DEAD_OBJECT; 470 } 471 472 if (err == ERROR_DRM_RESOURCE_BUSY && retry) { 473 mLock.unlock(); 474 // reclaimSession may call back to closeSession, since mLock is 475 // shared between Drm instances, we should unlock here to avoid 476 // deadlock. 477 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); 478 mLock.lock(); 479 } else { 480 retry = false; 481 } 482 } while (retry); 483 484 if (err == OK) { 485 DrmSessionManager::Instance()->addSession(getCallingPid(), 486 mDrmSessionClient, sessionId); 487 mOpenSessions.push(sessionId); 488 } 489 return err; 490} 491 492status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { 493 Mutex::Autolock autoLock(mLock); 494 495 if (mInitCheck != OK) { 496 return mInitCheck; 497 } 498 499 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId)); 500 if (status.isOk()) { 501 if (status == Status::OK) { 502 DrmSessionManager::Instance()->removeSession(sessionId); 503 for (size_t i = 0; i < mOpenSessions.size(); i++) { 504 if (mOpenSessions[i] == sessionId) { 505 mOpenSessions.removeAt(i); 506 break; 507 } 508 } 509 } 510 reportMetrics(); 511 return toStatusT(status); 512 } 513 return DEAD_OBJECT; 514} 515 516status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, 517 Vector<uint8_t> const &initData, String8 const &mimeType, 518 DrmPlugin::KeyType keyType, KeyedVector<String8, 519 String8> const &optionalParameters, Vector<uint8_t> &request, 520 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) { 521 Mutex::Autolock autoLock(mLock); 522 523 if (mInitCheck != OK) { 524 return mInitCheck; 525 } 526 527 DrmSessionManager::Instance()->useSession(sessionId); 528 529 KeyType hKeyType; 530 if (keyType == DrmPlugin::kKeyType_Streaming) { 531 hKeyType = KeyType::STREAMING; 532 } else if (keyType == DrmPlugin::kKeyType_Offline) { 533 hKeyType = KeyType::OFFLINE; 534 } else if (keyType == DrmPlugin::kKeyType_Release) { 535 hKeyType = KeyType::RELEASE; 536 } else { 537 return BAD_VALUE; 538 } 539 540 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters); 541 542 status_t err = UNKNOWN_ERROR; 543 544 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId), 545 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters, 546 [&](Status status, const hidl_vec<uint8_t>& hRequest, 547 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) { 548 549 if (status == Status::OK) { 550 request = toVector(hRequest); 551 defaultUrl = toString8(hDefaultUrl); 552 553 switch (hKeyRequestType) { 554 case KeyRequestType::INITIAL: 555 *keyRequestType = DrmPlugin::kKeyRequestType_Initial; 556 break; 557 case KeyRequestType::RENEWAL: 558 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal; 559 break; 560 case KeyRequestType::RELEASE: 561 *keyRequestType = DrmPlugin::kKeyRequestType_Release; 562 break; 563 default: 564 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown; 565 break; 566 } 567 err = toStatusT(status); 568 } 569 }); 570 571 return hResult.isOk() ? err : DEAD_OBJECT; 572} 573 574status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, 575 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { 576 Mutex::Autolock autoLock(mLock); 577 578 if (mInitCheck != OK) { 579 return mInitCheck; 580 } 581 582 DrmSessionManager::Instance()->useSession(sessionId); 583 584 status_t err = UNKNOWN_ERROR; 585 586 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId), 587 toHidlVec(response), 588 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) { 589 if (status == Status::OK) { 590 keySetId = toVector(hKeySetId); 591 } 592 err = toStatusT(status); 593 } 594 ); 595 596 return hResult.isOk() ? err : DEAD_OBJECT; 597} 598 599status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { 600 Mutex::Autolock autoLock(mLock); 601 602 if (mInitCheck != OK) { 603 return mInitCheck; 604 } 605 606 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId))); 607} 608 609status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId, 610 Vector<uint8_t> const &keySetId) { 611 Mutex::Autolock autoLock(mLock); 612 613 if (mInitCheck != OK) { 614 return mInitCheck; 615 } 616 617 DrmSessionManager::Instance()->useSession(sessionId); 618 619 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId), 620 toHidlVec(keySetId))); 621} 622 623status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId, 624 KeyedVector<String8, String8> &infoMap) const { 625 Mutex::Autolock autoLock(mLock); 626 627 if (mInitCheck != OK) { 628 return mInitCheck; 629 } 630 631 DrmSessionManager::Instance()->useSession(sessionId); 632 633 ::KeyedVector hInfoMap; 634 635 status_t err = UNKNOWN_ERROR; 636 637 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId), 638 [&](Status status, const hidl_vec<KeyValue>& map) { 639 if (status == Status::OK) { 640 infoMap = toKeyedVector(map); 641 } 642 err = toStatusT(status); 643 } 644 ); 645 646 return hResult.isOk() ? err : DEAD_OBJECT; 647} 648 649status_t DrmHal::getProvisionRequest(String8 const &certType, 650 String8 const &certAuthority, Vector<uint8_t> &request, 651 String8 &defaultUrl) { 652 Mutex::Autolock autoLock(mLock); 653 654 if (mInitCheck != OK) { 655 return mInitCheck; 656 } 657 658 status_t err = UNKNOWN_ERROR; 659 660 Return<void> hResult = mPlugin->getProvisionRequest( 661 toHidlString(certType), toHidlString(certAuthority), 662 [&](Status status, const hidl_vec<uint8_t>& hRequest, 663 const hidl_string& hDefaultUrl) { 664 if (status == Status::OK) { 665 request = toVector(hRequest); 666 defaultUrl = toString8(hDefaultUrl); 667 } 668 err = toStatusT(status); 669 } 670 ); 671 672 return hResult.isOk() ? err : DEAD_OBJECT; 673} 674 675status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, 676 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 677 Mutex::Autolock autoLock(mLock); 678 679 if (mInitCheck != OK) { 680 return mInitCheck; 681 } 682 683 status_t err = UNKNOWN_ERROR; 684 685 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response), 686 [&](Status status, const hidl_vec<uint8_t>& hCertificate, 687 const hidl_vec<uint8_t>& hWrappedKey) { 688 if (status == Status::OK) { 689 certificate = toVector(hCertificate); 690 wrappedKey = toVector(hWrappedKey); 691 } 692 err = toStatusT(status); 693 } 694 ); 695 696 return hResult.isOk() ? err : DEAD_OBJECT; 697} 698 699status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { 700 Mutex::Autolock autoLock(mLock); 701 702 if (mInitCheck != OK) { 703 return mInitCheck; 704 } 705 706 status_t err = UNKNOWN_ERROR; 707 708 Return<void> hResult = mPlugin->getSecureStops( 709 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) { 710 if (status == Status::OK) { 711 secureStops = toSecureStops(hSecureStops); 712 } 713 err = toStatusT(status); 714 } 715 ); 716 717 return hResult.isOk() ? err : DEAD_OBJECT; 718} 719 720 721status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { 722 Mutex::Autolock autoLock(mLock); 723 724 if (mInitCheck != OK) { 725 return mInitCheck; 726 } 727 728 status_t err = UNKNOWN_ERROR; 729 730 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid), 731 [&](Status status, const SecureStop& hSecureStop) { 732 if (status == Status::OK) { 733 secureStop = toVector(hSecureStop.opaqueData); 734 } 735 err = toStatusT(status); 736 } 737 ); 738 739 return hResult.isOk() ? err : DEAD_OBJECT; 740} 741 742status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) { 743 Mutex::Autolock autoLock(mLock); 744 745 if (mInitCheck != OK) { 746 return mInitCheck; 747 } 748 749 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease))); 750} 751 752status_t DrmHal::releaseAllSecureStops() { 753 Mutex::Autolock autoLock(mLock); 754 755 if (mInitCheck != OK) { 756 return mInitCheck; 757 } 758 759 return toStatusT(mPlugin->releaseAllSecureStops()); 760} 761 762status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const { 763 Mutex::Autolock autoLock(mLock); 764 return getPropertyStringInternal(name, value); 765} 766 767status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const { 768 // This function is internal to the class and should only be called while 769 // mLock is already held. 770 771 if (mInitCheck != OK) { 772 return mInitCheck; 773 } 774 775 status_t err = UNKNOWN_ERROR; 776 777 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name), 778 [&](Status status, const hidl_string& hValue) { 779 if (status == Status::OK) { 780 value = toString8(hValue); 781 } 782 err = toStatusT(status); 783 } 784 ); 785 786 return hResult.isOk() ? err : DEAD_OBJECT; 787} 788 789status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const { 790 Mutex::Autolock autoLock(mLock); 791 return getPropertyByteArrayInternal(name, value); 792} 793 794status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const { 795 // This function is internal to the class and should only be called while 796 // mLock is already held. 797 798 if (mInitCheck != OK) { 799 return mInitCheck; 800 } 801 802 status_t err = UNKNOWN_ERROR; 803 804 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name), 805 [&](Status status, const hidl_vec<uint8_t>& hValue) { 806 if (status == Status::OK) { 807 value = toVector(hValue); 808 } 809 err = toStatusT(status); 810 } 811 ); 812 813 return hResult.isOk() ? err : DEAD_OBJECT; 814} 815 816status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { 817 Mutex::Autolock autoLock(mLock); 818 819 if (mInitCheck != OK) { 820 return mInitCheck; 821 } 822 823 Status status = mPlugin->setPropertyString(toHidlString(name), 824 toHidlString(value)); 825 return toStatusT(status); 826} 827 828status_t DrmHal::setPropertyByteArray(String8 const &name, 829 Vector<uint8_t> const &value ) const { 830 Mutex::Autolock autoLock(mLock); 831 832 if (mInitCheck != OK) { 833 return mInitCheck; 834 } 835 836 Status status = mPlugin->setPropertyByteArray(toHidlString(name), 837 toHidlVec(value)); 838 return toStatusT(status); 839} 840 841 842status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId, 843 String8 const &algorithm) { 844 Mutex::Autolock autoLock(mLock); 845 846 if (mInitCheck != OK) { 847 return mInitCheck; 848 } 849 850 DrmSessionManager::Instance()->useSession(sessionId); 851 852 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId), 853 toHidlString(algorithm)); 854 return toStatusT(status); 855} 856 857status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId, 858 String8 const &algorithm) { 859 Mutex::Autolock autoLock(mLock); 860 861 if (mInitCheck != OK) { 862 return mInitCheck; 863 } 864 865 DrmSessionManager::Instance()->useSession(sessionId); 866 867 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), 868 toHidlString(algorithm)); 869 return toStatusT(status); 870} 871 872status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId, 873 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 874 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 875 Mutex::Autolock autoLock(mLock); 876 877 if (mInitCheck != OK) { 878 return mInitCheck; 879 } 880 881 DrmSessionManager::Instance()->useSession(sessionId); 882 883 status_t err = UNKNOWN_ERROR; 884 885 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId), 886 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 887 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 888 if (status == Status::OK) { 889 output = toVector(hOutput); 890 } 891 err = toStatusT(status); 892 } 893 ); 894 895 return hResult.isOk() ? err : DEAD_OBJECT; 896} 897 898status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId, 899 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 900 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 901 Mutex::Autolock autoLock(mLock); 902 903 if (mInitCheck != OK) { 904 return mInitCheck; 905 } 906 907 DrmSessionManager::Instance()->useSession(sessionId); 908 909 status_t err = UNKNOWN_ERROR; 910 911 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId), 912 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 913 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 914 if (status == Status::OK) { 915 output = toVector(hOutput); 916 } 917 err = toStatusT(status); 918 } 919 ); 920 921 return hResult.isOk() ? err : DEAD_OBJECT; 922} 923 924status_t DrmHal::sign(Vector<uint8_t> const &sessionId, 925 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 926 Vector<uint8_t> &signature) { 927 Mutex::Autolock autoLock(mLock); 928 929 if (mInitCheck != OK) { 930 return mInitCheck; 931 } 932 933 DrmSessionManager::Instance()->useSession(sessionId); 934 935 status_t err = UNKNOWN_ERROR; 936 937 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), 938 toHidlVec(keyId), toHidlVec(message), 939 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 940 if (status == Status::OK) { 941 signature = toVector(hSignature); 942 } 943 err = toStatusT(status); 944 } 945 ); 946 947 return hResult.isOk() ? err : DEAD_OBJECT; 948} 949 950status_t DrmHal::verify(Vector<uint8_t> const &sessionId, 951 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 952 Vector<uint8_t> const &signature, bool &match) { 953 Mutex::Autolock autoLock(mLock); 954 955 if (mInitCheck != OK) { 956 return mInitCheck; 957 } 958 959 DrmSessionManager::Instance()->useSession(sessionId); 960 961 status_t err = UNKNOWN_ERROR; 962 963 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId), 964 toHidlVec(message), toHidlVec(signature), 965 [&](Status status, bool hMatch) { 966 if (status == Status::OK) { 967 match = hMatch; 968 } else { 969 match = false; 970 } 971 err = toStatusT(status); 972 } 973 ); 974 975 return hResult.isOk() ? err : DEAD_OBJECT; 976} 977 978status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId, 979 String8 const &algorithm, Vector<uint8_t> const &message, 980 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 981 Mutex::Autolock autoLock(mLock); 982 983 if (mInitCheck != OK) { 984 return mInitCheck; 985 } 986 987 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) { 988 return -EPERM; 989 } 990 991 DrmSessionManager::Instance()->useSession(sessionId); 992 993 status_t err = UNKNOWN_ERROR; 994 995 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId), 996 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey), 997 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 998 if (status == Status::OK) { 999 signature = toVector(hSignature); 1000 } 1001 err = toStatusT(status); 1002 } 1003 ); 1004 1005 return hResult.isOk() ? err : DEAD_OBJECT; 1006} 1007 1008void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused) 1009{ 1010 Mutex::Autolock autoLock(mLock); 1011 closeOpenSessions(); 1012 setListener(NULL); 1013 mInitCheck = NO_INIT; 1014 1015 if (mPlugin != NULL) { 1016 if (!mPlugin->setListener(NULL).isOk()) { 1017 mInitCheck = DEAD_OBJECT; 1018 } 1019 } 1020 mPlugin.clear(); 1021} 1022 1023void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec) 1024{ 1025 if (vec.size()) { 1026 obj.writeInt32(vec.size()); 1027 obj.write(vec.data(), vec.size()); 1028 } else { 1029 obj.writeInt32(0); 1030 } 1031} 1032 1033void DrmHal::reportMetrics() const 1034{ 1035 Vector<uint8_t> metrics; 1036 String8 vendor; 1037 String8 description; 1038 if (getPropertyStringInternal(String8("vendor"), vendor) == OK && 1039 getPropertyStringInternal(String8("description"), description) == OK && 1040 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) { 1041 status_t res = android::reportDrmPluginMetrics( 1042 metrics, vendor, description); 1043 if (res != OK) { 1044 ALOGE("Metrics were retrieved but could not be reported: %i", res); 1045 } 1046 } 1047} 1048 1049} // namespace android 1050