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