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