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