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