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