blob: 7d045aca35270b2d1bdb879b60899f8784a305aa [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>
Kyle Zhang2567a5e2022-03-17 23:36:26 +000023#include <android/hardware/drm/1.3/IDrmFactory.h>
Kyle Zhang6605add2022-01-13 17:51:23 +000024#include <android/hidl/manager/1.2/IServiceManager.h>
25#include <hidl/ServiceManagement.h>
26#include <media/EventMetric.h>
27#include <media/MediaMetrics.h>
28#include <media/PluginMetricsReporting.h>
29#include <media/drm/DrmAPI.h>
30#include <media/stagefright/MediaErrors.h>
31#include <media/stagefright/foundation/ADebug.h>
32#include <media/stagefright/foundation/AString.h>
33#include <media/stagefright/foundation/base64.h>
34#include <media/stagefright/foundation/hexdump.h>
35#include <mediadrm/DrmHalHidl.h>
36#include <mediadrm/DrmSessionClientInterface.h>
37#include <mediadrm/DrmSessionManager.h>
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +053038#include <mediadrm/DrmStatus.h>
Kyle Zhang6605add2022-01-13 17:51:23 +000039#include <mediadrm/DrmUtils.h>
40#include <mediadrm/IDrmMetricsConsumer.h>
41#include <utils/Log.h>
42
43#include <iomanip>
44#include <vector>
45
46using ::android::sp;
47using ::android::DrmUtils::toStatusT;
48using ::android::hardware::hidl_array;
49using ::android::hardware::hidl_string;
50using ::android::hardware::hidl_vec;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
53using ::android::hardware::drm::V1_1::DrmMetricGroup;
54using ::android::os::PersistableBundle;
55using drm::V1_0::KeyedVector;
56using drm::V1_0::KeyRequestType;
57using drm::V1_0::KeyType;
58using drm::V1_0::KeyValue;
59using drm::V1_0::SecureStop;
60using drm::V1_0::SecureStopId;
61using drm::V1_0::Status;
62using drm::V1_1::HdcpLevel;
63using drm::V1_1::SecureStopRelease;
64using drm::V1_1::SecurityLevel;
65using drm::V1_2::KeySetId;
66using drm::V1_2::KeyStatusType;
67
68typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
69typedef drm::V1_2::Status Status_V1_2;
70typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
71
72namespace {
73
74// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
75// in the MediaDrm API.
76constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
77constexpr char kEqualsSign[] = "=";
78
79template <typename T>
80std::string toBase64StringNoPad(const T* data, size_t size) {
81 // Note that the base 64 conversion only works with arrays of single-byte
82 // values. If the source is empty or is not an array of single-byte values,
83 // return empty string.
84 if (size == 0 || sizeof(data[0]) != 1) {
85 return "";
86 }
87
88 android::AString outputString;
89 encodeBase64(data, size, &outputString);
90 // Remove trailing equals padding if it exists.
91 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
92 outputString.erase(outputString.size() - 1, 1);
93 }
94
95 return std::string(outputString.c_str(), outputString.size());
96}
97
98} // anonymous namespace
99
100namespace android {
101
102#define INIT_CHECK() \
103 { \
104 if (mInitCheck != OK) return mInitCheck; \
105 }
106
107static const Vector<uint8_t> toVector(const hidl_vec<uint8_t>& vec) {
108 Vector<uint8_t> vector;
109 vector.appendArray(vec.data(), vec.size());
110 return *const_cast<const Vector<uint8_t>*>(&vector);
111}
112
113static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t>& vector) {
114 hidl_vec<uint8_t> vec;
115 vec.setToExternal(const_cast<uint8_t*>(vector.array()), vector.size());
116 return vec;
117}
118
119static String8 toString8(const hidl_string& string) {
120 return String8(string.c_str());
121}
122
123static hidl_string toHidlString(const String8& string) {
124 return hidl_string(string.string());
125}
126
127static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
128 switch (level) {
129 case SecurityLevel::SW_SECURE_CRYPTO:
130 return DrmPlugin::kSecurityLevelSwSecureCrypto;
131 case SecurityLevel::SW_SECURE_DECODE:
132 return DrmPlugin::kSecurityLevelSwSecureDecode;
133 case SecurityLevel::HW_SECURE_CRYPTO:
134 return DrmPlugin::kSecurityLevelHwSecureCrypto;
135 case SecurityLevel::HW_SECURE_DECODE:
136 return DrmPlugin::kSecurityLevelHwSecureDecode;
137 case SecurityLevel::HW_SECURE_ALL:
138 return DrmPlugin::kSecurityLevelHwSecureAll;
139 default:
140 return DrmPlugin::kSecurityLevelUnknown;
141 }
142}
143
144static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
145 switch (level) {
146 case DrmPlugin::kSecurityLevelSwSecureCrypto:
147 return SecurityLevel::SW_SECURE_CRYPTO;
148 case DrmPlugin::kSecurityLevelSwSecureDecode:
149 return SecurityLevel::SW_SECURE_DECODE;
150 case DrmPlugin::kSecurityLevelHwSecureCrypto:
151 return SecurityLevel::HW_SECURE_CRYPTO;
152 case DrmPlugin::kSecurityLevelHwSecureDecode:
153 return SecurityLevel::HW_SECURE_DECODE;
154 case DrmPlugin::kSecurityLevelHwSecureAll:
155 return SecurityLevel::HW_SECURE_ALL;
156 default:
157 return SecurityLevel::UNKNOWN;
158 }
159}
160
161static DrmPlugin::OfflineLicenseState toOfflineLicenseState(OfflineLicenseState licenseState) {
162 switch (licenseState) {
163 case OfflineLicenseState::USABLE:
164 return DrmPlugin::kOfflineLicenseStateUsable;
165 case OfflineLicenseState::INACTIVE:
166 return DrmPlugin::kOfflineLicenseStateReleased;
167 default:
168 return DrmPlugin::kOfflineLicenseStateUnknown;
169 }
170}
171
172static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
173 switch (level) {
174 case HdcpLevel_V1_2::HDCP_NONE:
175 return DrmPlugin::kHdcpNone;
176 case HdcpLevel_V1_2::HDCP_V1:
177 return DrmPlugin::kHdcpV1;
178 case HdcpLevel_V1_2::HDCP_V2:
179 return DrmPlugin::kHdcpV2;
180 case HdcpLevel_V1_2::HDCP_V2_1:
181 return DrmPlugin::kHdcpV2_1;
182 case HdcpLevel_V1_2::HDCP_V2_2:
183 return DrmPlugin::kHdcpV2_2;
184 case HdcpLevel_V1_2::HDCP_V2_3:
185 return DrmPlugin::kHdcpV2_3;
186 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
187 return DrmPlugin::kHdcpNoOutput;
188 default:
189 return DrmPlugin::kHdcpLevelUnknown;
190 }
191}
192static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>& keyedVector) {
193 std::vector<KeyValue> stdKeyedVector;
194 for (size_t i = 0; i < keyedVector.size(); i++) {
195 KeyValue keyValue;
196 keyValue.key = toHidlString(keyedVector.keyAt(i));
197 keyValue.value = toHidlString(keyedVector.valueAt(i));
198 stdKeyedVector.push_back(keyValue);
199 }
200 return ::KeyedVector(stdKeyedVector);
201}
202
203static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector& hKeyedVector) {
204 KeyedVector<String8, String8> keyedVector;
205 for (size_t i = 0; i < hKeyedVector.size(); i++) {
206 keyedVector.add(toString8(hKeyedVector[i].key), toString8(hKeyedVector[i].value));
207 }
208 return keyedVector;
209}
210
211static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>& hSecureStops) {
212 List<Vector<uint8_t>> secureStops;
213 for (size_t i = 0; i < hSecureStops.size(); i++) {
214 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
215 }
216 return secureStops;
217}
218
219static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>& hSecureStopIds) {
220 List<Vector<uint8_t>> secureStopIds;
221 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
222 secureStopIds.push_back(toVector(hSecureStopIds[i]));
223 }
224 return secureStopIds;
225}
226
227static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>& hKeySetIds) {
228 List<Vector<uint8_t>> keySetIds;
229 for (size_t i = 0; i < hKeySetIds.size(); i++) {
230 keySetIds.push_back(toVector(hKeySetIds[i]));
231 }
232 return keySetIds;
233}
234
235Mutex DrmHalHidl::mLock;
236
237struct DrmHalHidl::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
238 explicit DrmSessionClient(DrmHalHidl* drm, const Vector<uint8_t>& sessionId)
239 : mSessionId(sessionId), mDrm(drm) {}
240
241 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
242 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
243
244 const Vector<uint8_t> mSessionId;
245
246 virtual ~DrmSessionClient();
247
248 private:
249 wp<DrmHalHidl> mDrm;
250
251 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
252};
253
254::ndk::ScopedAStatus DrmHalHidl::DrmSessionClient::reclaimResource(bool* _aidl_return) {
255 auto sessionId = mSessionId;
256 sp<DrmHalHidl> drm = mDrm.promote();
257 if (drm == NULL) {
258 *_aidl_return = true;
259 return ::ndk::ScopedAStatus::ok();
260 }
261 status_t err = drm->closeSession(sessionId);
262 if (err != OK) {
263 *_aidl_return = false;
264 return ::ndk::ScopedAStatus::ok();
265 }
266 drm->sendEvent(EventType::SESSION_RECLAIMED, toHidlVec(sessionId), hidl_vec<uint8_t>());
267 *_aidl_return = true;
268 return ::ndk::ScopedAStatus::ok();
269}
270
271::ndk::ScopedAStatus DrmHalHidl::DrmSessionClient::getName(::std::string* _aidl_return) {
272 String8 name;
273 sp<DrmHalHidl> drm = mDrm.promote();
274 if (drm == NULL) {
275 name.append("<deleted>");
276 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK || name.isEmpty()) {
277 name.append("<Get vendor failed or is empty>");
278 }
279 name.append("[");
280 for (size_t i = 0; i < mSessionId.size(); ++i) {
281 name.appendFormat("%02x", mSessionId[i]);
282 }
283 name.append("]");
284 *_aidl_return = name;
285 return ::ndk::ScopedAStatus::ok();
286}
287
288DrmHalHidl::DrmSessionClient::~DrmSessionClient() {
289 DrmSessionManager::Instance()->removeSession(mSessionId);
290}
291
292DrmHalHidl::DrmHalHidl()
293 : mFactories(makeDrmFactories()),
294 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}
295
296void DrmHalHidl::closeOpenSessions() {
297 Mutex::Autolock autoLock(mLock);
298 auto openSessions = mOpenSessions;
299 for (size_t i = 0; i < openSessions.size(); i++) {
300 mLock.unlock();
301 closeSession(openSessions[i]->mSessionId);
302 mLock.lock();
303 }
304 mOpenSessions.clear();
305}
306
307DrmHalHidl::~DrmHalHidl() {}
308
309void DrmHalHidl::cleanup() {
310 closeOpenSessions();
311
312 Mutex::Autolock autoLock(mLock);
313 reportFrameworkMetrics(reportPluginMetrics());
314
315 setListener(NULL);
316 mInitCheck = NO_INIT;
317 if (mPluginV1_2 != NULL) {
318 if (!mPluginV1_2->setListener(NULL).isOk()) {
319 mInitCheck = DEAD_OBJECT;
320 }
321 } else if (mPlugin != NULL) {
322 if (!mPlugin->setListener(NULL).isOk()) {
323 mInitCheck = DEAD_OBJECT;
324 }
325 }
326 mPlugin.clear();
327 mPluginV1_1.clear();
328 mPluginV1_2.clear();
329 mPluginV1_4.clear();
330}
331
332std::vector<sp<IDrmFactory>> DrmHalHidl::makeDrmFactories() {
333 static std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
334 if (factories.size() == 0) {
Kyle Zhang96af9572022-02-05 06:38:53 +0000335 DrmUtils::LOG2BI("No hidl drm factories found");
336 // could be in passthrough mode, load the default passthrough service
Kyle Zhang6605add2022-01-13 17:51:23 +0000337 auto passthrough = IDrmFactory::getService();
338 if (passthrough != NULL) {
339 DrmUtils::LOG2BI("makeDrmFactories: using default passthrough drm instance");
340 factories.push_back(passthrough);
341 } else {
Kyle Zhang96af9572022-02-05 06:38:53 +0000342 DrmUtils::LOG2BE("Failed to find passthrough drm factories");
Kyle Zhang6605add2022-01-13 17:51:23 +0000343 }
344 }
345 return factories;
346}
347
348sp<IDrmPlugin> DrmHalHidl::makeDrmPlugin(const sp<IDrmFactory>& factory, const uint8_t uuid[16],
349 const String8& appPackageName) {
350 mAppPackageName = appPackageName;
351 mMetrics.SetAppPackageName(appPackageName);
352 mMetrics.SetAppUid(AIBinder_getCallingUid());
353
354 sp<IDrmPlugin> plugin;
355 Return<void> hResult = factory->createPlugin(
356 uuid, appPackageName.string(), [&](Status status, const sp<IDrmPlugin>& hPlugin) {
357 if (status != Status::OK) {
358 DrmUtils::LOG2BE(uuid, "Failed to make drm plugin: %d", status);
359 return;
360 }
361 plugin = hPlugin;
362 });
363
364 if (!hResult.isOk()) {
365 DrmUtils::LOG2BE(uuid, "createPlugin remote call failed: %s",
366 hResult.description().c_str());
367 }
368
369 return plugin;
370}
371
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530372DrmStatus DrmHalHidl::initCheck() const {
373 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +0000374}
375
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530376DrmStatus DrmHalHidl::setListener(const sp<IDrmClient>& listener) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000377 Mutex::Autolock lock(mEventLock);
378 mListener = listener;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530379 return DrmStatus(NO_ERROR);
Kyle Zhang6605add2022-01-13 17:51:23 +0000380}
381
382Return<void> DrmHalHidl::sendEvent(EventType hEventType, const hidl_vec<uint8_t>& sessionId,
383 const hidl_vec<uint8_t>& data) {
384 mMetrics.mEventCounter.Increment((uint32_t)hEventType);
385
386 mEventLock.lock();
387 sp<IDrmClient> listener = mListener;
388 mEventLock.unlock();
389
390 if (listener != NULL) {
391 Mutex::Autolock lock(mNotifyLock);
392 DrmPlugin::EventType eventType;
393 switch (hEventType) {
394 case EventType::PROVISION_REQUIRED:
395 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
396 break;
397 case EventType::KEY_NEEDED:
398 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
399 break;
400 case EventType::KEY_EXPIRED:
401 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
402 break;
403 case EventType::VENDOR_DEFINED:
404 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
405 break;
406 case EventType::SESSION_RECLAIMED:
407 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
408 break;
409 default:
410 return Void();
411 }
412 listener->sendEvent(eventType, sessionId, data);
413 }
414 return Void();
415}
416
417Return<void> DrmHalHidl::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
418 int64_t expiryTimeInMS) {
419 mEventLock.lock();
420 sp<IDrmClient> listener = mListener;
421 mEventLock.unlock();
422
423 if (listener != NULL) {
424 Mutex::Autolock lock(mNotifyLock);
425 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
426 }
427 return Void();
428}
429
430Return<void> DrmHalHidl::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
431 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0,
432 bool hasNewUsableKey) {
433 std::vector<KeyStatus> keyStatusVec;
434 for (const auto& keyStatus_V1_0 : keyStatusList_V1_0) {
435 keyStatusVec.push_back(
436 {keyStatus_V1_0.keyId, static_cast<KeyStatusType>(keyStatus_V1_0.type)});
437 }
438 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
439 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
440}
441
442Return<void> DrmHalHidl::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
443 const hidl_vec<KeyStatus>& hKeyStatusList,
444 bool hasNewUsableKey) {
445 mEventLock.lock();
446 sp<IDrmClient> listener = mListener;
447 mEventLock.unlock();
448
449 if (listener != NULL) {
450 std::vector<DrmKeyStatus> keyStatusList;
451 size_t nKeys = hKeyStatusList.size();
452 for (size_t i = 0; i < nKeys; ++i) {
453 const KeyStatus& keyStatus = hKeyStatusList[i];
454 uint32_t type;
455 switch (keyStatus.type) {
456 case KeyStatusType::USABLE:
457 type = DrmPlugin::kKeyStatusType_Usable;
458 break;
459 case KeyStatusType::EXPIRED:
460 type = DrmPlugin::kKeyStatusType_Expired;
461 break;
462 case KeyStatusType::OUTPUTNOTALLOWED:
463 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
464 break;
465 case KeyStatusType::STATUSPENDING:
466 type = DrmPlugin::kKeyStatusType_StatusPending;
467 break;
468 case KeyStatusType::USABLEINFUTURE:
469 type = DrmPlugin::kKeyStatusType_UsableInFuture;
470 break;
471 case KeyStatusType::INTERNALERROR:
472 default:
473 type = DrmPlugin::kKeyStatusType_InternalError;
474 break;
475 }
476 keyStatusList.push_back({type, keyStatus.keyId});
477 mMetrics.mKeyStatusChangeCounter.Increment((uint32_t)keyStatus.type);
478 }
479
480 Mutex::Autolock lock(mNotifyLock);
481 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
482 } else {
483 // There's no listener. But we still want to count the key change
484 // events.
485 size_t nKeys = hKeyStatusList.size();
486 for (size_t i = 0; i < nKeys; i++) {
487 mMetrics.mKeyStatusChangeCounter.Increment((uint32_t)hKeyStatusList[i].type);
488 }
489 }
490
491 return Void();
492}
493
494Return<void> DrmHalHidl::sendSessionLostState(const hidl_vec<uint8_t>& sessionId) {
495 mEventLock.lock();
496 sp<IDrmClient> listener = mListener;
497 mEventLock.unlock();
498
499 if (listener != NULL) {
500 Mutex::Autolock lock(mNotifyLock);
501 listener->sendSessionLostState(sessionId);
502 }
503 return Void();
504}
505
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530506DrmStatus DrmHalHidl::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory>& factory,
507 const uint8_t uuid[16], const String8& mimeType,
508 DrmPlugin::SecurityLevel level,
509 bool* isSupported) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000510 *isSupported = false;
511
512 // handle default value cases
513 if (level == DrmPlugin::kSecurityLevelUnknown) {
514 if (mimeType == "") {
515 // isCryptoSchemeSupported(uuid)
516 *isSupported = true;
517 } else {
518 // isCryptoSchemeSupported(uuid, mimeType)
519 *isSupported = factory->isContentTypeSupported(mimeType.string());
520 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530521 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000522 } else if (mimeType == "") {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530523 return DrmStatus(BAD_VALUE);
Kyle Zhang6605add2022-01-13 17:51:23 +0000524 }
525
526 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
527 if (factoryV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530528 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +0000529 } else {
530 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
531 toHidlSecurityLevel(level));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530532 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000533 }
534}
535
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530536DrmStatus DrmHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
537 DrmPlugin::SecurityLevel level, bool* isSupported) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000538 Mutex::Autolock autoLock(mLock);
539 *isSupported = false;
540 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
541 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
542 return matchMimeTypeAndSecurityLevel(mFactories[i], uuid, mimeType, level, isSupported);
543 }
544 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530545 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000546}
547
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530548DrmStatus DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000549 Mutex::Autolock autoLock(mLock);
550
551 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
552 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
553 if (hResult.isOk() && hResult) {
554 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
555 if (plugin != NULL) {
556 mPlugin = plugin;
557 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
558 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
559 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
560 break;
561 }
562 }
563 }
564
565 if (mPlugin == NULL) {
566 DrmUtils::LOG2BE(uuid, "No supported hal instance found");
567 mInitCheck = ERROR_UNSUPPORTED;
568 } else {
569 mInitCheck = OK;
570 if (mPluginV1_2 != NULL) {
571 if (!mPluginV1_2->setListener(this).isOk()) {
572 mInitCheck = DEAD_OBJECT;
573 }
574 } else if (!mPlugin->setListener(this).isOk()) {
575 mInitCheck = DEAD_OBJECT;
576 }
577 if (mInitCheck != OK) {
578 mPlugin.clear();
579 mPluginV1_1.clear();
580 mPluginV1_2.clear();
581 mPluginV1_4.clear();
582 }
583 }
584
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530585 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +0000586}
587
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530588DrmStatus DrmHalHidl::destroyPlugin() {
Kyle Zhang6605add2022-01-13 17:51:23 +0000589 cleanup();
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530590 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000591}
592
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530593DrmStatus DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000594 Mutex::Autolock autoLock(mLock);
595 INIT_CHECK();
596
597 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
598 bool setSecurityLevel = true;
599
600 if (level == DrmPlugin::kSecurityLevelMax) {
601 setSecurityLevel = false;
602 } else {
603 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
604 return ERROR_DRM_CANNOT_HANDLE;
605 }
606 }
607
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530608 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000609 bool retry = true;
610 do {
611 hidl_vec<uint8_t> hSessionId;
612
613 Return<void> hResult;
614 if (mPluginV1_1 == NULL || !setSecurityLevel) {
615 hResult = mPlugin->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
616 if (status == Status::OK) {
617 sessionId = toVector(id);
618 }
619 err = toStatusT(status);
620 });
621 } else {
622 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
623 [&](Status status, const hidl_vec<uint8_t>& id) {
624 if (status == Status::OK) {
625 sessionId = toVector(id);
626 }
627 err = toStatusT(status);
628 });
629 }
630
631 if (!hResult.isOk()) {
632 err = DEAD_OBJECT;
633 }
634
635 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
636 mLock.unlock();
637 // reclaimSession may call back to closeSession, since mLock is
638 // shared between Drm instances, we should unlock here to avoid
639 // deadlock.
640 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
641 mLock.lock();
642 } else {
643 retry = false;
644 }
645 } while (retry);
646
647 if (err == OK) {
648 std::shared_ptr<DrmSessionClient> client =
649 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
650 DrmSessionManager::Instance()->addSession(
651 AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
652 sessionId);
653 mOpenSessions.push_back(client);
654 mMetrics.SetSessionStart(sessionId);
655 }
656
657 mMetrics.mOpenSessionCounter.Increment(err);
658 return err;
659}
660
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530661DrmStatus DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000662 Mutex::Autolock autoLock(mLock);
663 INIT_CHECK();
664
665 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
666 if (status.isOk()) {
667 if (status == Status::OK) {
668 DrmSessionManager::Instance()->removeSession(sessionId);
669 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
670 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
671 mOpenSessions.erase(i);
672 break;
673 }
674 }
675 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530676 DrmStatus response = toStatusT(status);
Kyle Zhang6605add2022-01-13 17:51:23 +0000677 mMetrics.SetSessionEnd(sessionId);
678 mMetrics.mCloseSessionCounter.Increment(response);
679 return response;
680 }
681 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530682 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000683}
684
685static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
686 switch (keyRequestType) {
687 case KeyRequestType::INITIAL:
688 return DrmPlugin::kKeyRequestType_Initial;
689 break;
690 case KeyRequestType::RENEWAL:
691 return DrmPlugin::kKeyRequestType_Renewal;
692 break;
693 case KeyRequestType::RELEASE:
694 return DrmPlugin::kKeyRequestType_Release;
695 break;
696 default:
697 return DrmPlugin::kKeyRequestType_Unknown;
698 break;
699 }
700}
701
702static DrmPlugin::KeyRequestType toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType) {
703 switch (keyRequestType) {
704 case KeyRequestType_V1_1::NONE:
705 return DrmPlugin::kKeyRequestType_None;
706 break;
707 case KeyRequestType_V1_1::UPDATE:
708 return DrmPlugin::kKeyRequestType_Update;
709 break;
710 default:
711 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
712 break;
713 }
714}
715
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530716DrmStatus DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
717 Vector<uint8_t> const& initData, String8 const& mimeType,
718 DrmPlugin::KeyType keyType,
719 KeyedVector<String8, String8> const& optionalParameters,
720 Vector<uint8_t>& request, String8& defaultUrl,
721 DrmPlugin::KeyRequestType* keyRequestType) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000722 Mutex::Autolock autoLock(mLock);
723 INIT_CHECK();
724 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
725
726 DrmSessionManager::Instance()->useSession(sessionId);
727
728 KeyType hKeyType;
729 if (keyType == DrmPlugin::kKeyType_Streaming) {
730 hKeyType = KeyType::STREAMING;
731 } else if (keyType == DrmPlugin::kKeyType_Offline) {
732 hKeyType = KeyType::OFFLINE;
733 } else if (keyType == DrmPlugin::kKeyType_Release) {
734 hKeyType = KeyType::RELEASE;
735 } else {
736 keyRequestTimer.SetAttribute(BAD_VALUE);
737 return BAD_VALUE;
738 }
739
740 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
741
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530742 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000743 Return<void> hResult;
744
745 if (mPluginV1_2 != NULL) {
746 hResult = mPluginV1_2->getKeyRequest_1_2(
747 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
748 hOptionalParameters,
749 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
750 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
751 if (status == Status_V1_2::OK) {
752 request = toVector(hRequest);
753 defaultUrl = toString8(hDefaultUrl);
754 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
755 }
756 err = toStatusT(status);
757 });
758 } else if (mPluginV1_1 != NULL) {
759 hResult = mPluginV1_1->getKeyRequest_1_1(
760 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
761 hOptionalParameters,
762 [&](Status status, const hidl_vec<uint8_t>& hRequest,
763 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
764 if (status == Status::OK) {
765 request = toVector(hRequest);
766 defaultUrl = toString8(hDefaultUrl);
767 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
768 }
769 err = toStatusT(status);
770 });
771 } else {
772 hResult = mPlugin->getKeyRequest(
773 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
774 hOptionalParameters,
775 [&](Status status, const hidl_vec<uint8_t>& hRequest,
776 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
777 if (status == Status::OK) {
778 request = toVector(hRequest);
779 defaultUrl = toString8(hDefaultUrl);
780 *keyRequestType = toKeyRequestType(hKeyRequestType);
781 }
782 err = toStatusT(status);
783 });
784 }
785
786 err = hResult.isOk() ? err : DEAD_OBJECT;
787 keyRequestTimer.SetAttribute(err);
788 return err;
789}
790
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530791DrmStatus DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
792 Vector<uint8_t> const& response,
793 Vector<uint8_t>& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000794 Mutex::Autolock autoLock(mLock);
795 INIT_CHECK();
796 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
797
798 DrmSessionManager::Instance()->useSession(sessionId);
799
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530800 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000801
802 Return<void> hResult =
803 mPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
804 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
805 if (status == Status::OK) {
806 keySetId = toVector(hKeySetId);
807 }
808 err = toStatusT(status);
809 });
810 err = hResult.isOk() ? err : DEAD_OBJECT;
811 keyResponseTimer.SetAttribute(err);
812 return err;
813}
814
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530815DrmStatus DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000816 Mutex::Autolock autoLock(mLock);
817 INIT_CHECK();
818
819 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530820 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000821}
822
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530823DrmStatus DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
824 Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000825 Mutex::Autolock autoLock(mLock);
826 INIT_CHECK();
827
828 DrmSessionManager::Instance()->useSession(sessionId);
829
830 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530831 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000832}
833
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530834DrmStatus DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
835 KeyedVector<String8, String8>& infoMap) const {
Kyle Zhang6605add2022-01-13 17:51:23 +0000836 Mutex::Autolock autoLock(mLock);
837 INIT_CHECK();
838
839 DrmSessionManager::Instance()->useSession(sessionId);
840
841 ::KeyedVector hInfoMap;
842
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530843 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000844
845 Return<void> hResult = mPlugin->queryKeyStatus(
846 toHidlVec(sessionId), [&](Status status, const hidl_vec<KeyValue>& map) {
847 if (status == Status::OK) {
848 infoMap = toKeyedVector(map);
849 }
850 err = toStatusT(status);
851 });
852
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530853 return hResult.isOk() ? DrmStatus(err) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000854}
855
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530856DrmStatus DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
857 Vector<uint8_t>& request, String8& defaultUrl) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000858 Mutex::Autolock autoLock(mLock);
859 INIT_CHECK();
860
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530861 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000862 Return<void> hResult;
863
864 if (mPluginV1_2 != NULL) {
865 hResult = mPluginV1_2->getProvisionRequest_1_2(
866 toHidlString(certType), toHidlString(certAuthority),
867 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
868 const hidl_string& hDefaultUrl) {
869 if (status == Status_V1_2::OK) {
870 request = toVector(hRequest);
871 defaultUrl = toString8(hDefaultUrl);
872 }
873 err = toStatusT(status);
874 });
875 } else {
876 hResult = mPlugin->getProvisionRequest(toHidlString(certType), toHidlString(certAuthority),
877 [&](Status status, const hidl_vec<uint8_t>& hRequest,
878 const hidl_string& hDefaultUrl) {
879 if (status == Status::OK) {
880 request = toVector(hRequest);
881 defaultUrl = toString8(hDefaultUrl);
882 }
883 err = toStatusT(status);
884 });
885 }
886
887 err = hResult.isOk() ? err : DEAD_OBJECT;
888 mMetrics.mGetProvisionRequestCounter.Increment(err);
889 return err;
890}
891
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530892DrmStatus DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
893 Vector<uint8_t>& certificate,
894 Vector<uint8_t>& wrappedKey) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000895 Mutex::Autolock autoLock(mLock);
896 INIT_CHECK();
897
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530898 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000899
900 Return<void> hResult = mPlugin->provideProvisionResponse(
901 toHidlVec(response), [&](Status status, const hidl_vec<uint8_t>& hCertificate,
902 const hidl_vec<uint8_t>& hWrappedKey) {
903 if (status == Status::OK) {
904 certificate = toVector(hCertificate);
905 wrappedKey = toVector(hWrappedKey);
906 }
907 err = toStatusT(status);
908 });
909
910 err = hResult.isOk() ? err : DEAD_OBJECT;
911 mMetrics.mProvideProvisionResponseCounter.Increment(err);
912 return err;
913}
914
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530915DrmStatus DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000916 Mutex::Autolock autoLock(mLock);
917 INIT_CHECK();
918
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530919 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000920
921 Return<void> hResult =
922 mPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
923 if (status == Status::OK) {
924 secureStops = toSecureStops(hSecureStops);
925 }
926 err = toStatusT(status);
927 });
928
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530929 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000930}
931
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530932DrmStatus DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000933 Mutex::Autolock autoLock(mLock);
934
935 if (mInitCheck != OK) {
936 return mInitCheck;
937 }
938
939 if (mPluginV1_1 == NULL) {
940 return ERROR_DRM_CANNOT_HANDLE;
941 }
942
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530943 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000944
945 Return<void> hResult = mPluginV1_1->getSecureStopIds(
946 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
947 if (status == Status::OK) {
948 secureStopIds = toSecureStopIds(hSecureStopIds);
949 }
950 err = toStatusT(status);
951 });
952
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530953 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000954}
955
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530956DrmStatus DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000957 Mutex::Autolock autoLock(mLock);
958 INIT_CHECK();
959
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530960 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000961
962 Return<void> hResult = mPlugin->getSecureStop(
963 toHidlVec(ssid), [&](Status status, const SecureStop& hSecureStop) {
964 if (status == Status::OK) {
965 secureStop = toVector(hSecureStop.opaqueData);
966 }
967 err = toStatusT(status);
968 });
969
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530970 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000971}
972
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530973DrmStatus DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000974 Mutex::Autolock autoLock(mLock);
975 INIT_CHECK();
976
977 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
978 if (mPluginV1_1 != NULL) {
979 SecureStopRelease secureStopRelease;
980 secureStopRelease.opaqueData = toHidlVec(ssRelease);
981 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
982 } else {
983 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
984 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530985 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000986}
987
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530988DrmStatus DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000989 Mutex::Autolock autoLock(mLock);
990
991 if (mInitCheck != OK) {
992 return mInitCheck;
993 }
994
995 if (mPluginV1_1 == NULL) {
996 return ERROR_DRM_CANNOT_HANDLE;
997 }
998
999 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301000 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001001}
1002
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301003DrmStatus DrmHalHidl::removeAllSecureStops() {
Kyle Zhang6605add2022-01-13 17:51:23 +00001004 Mutex::Autolock autoLock(mLock);
1005 INIT_CHECK();
1006
1007 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1008 if (mPluginV1_1 != NULL) {
1009 status = mPluginV1_1->removeAllSecureStops();
1010 } else {
1011 status = mPlugin->releaseAllSecureStops();
1012 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301013 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001014}
1015
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301016DrmStatus DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
1017 DrmPlugin::HdcpLevel* max) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001018 Mutex::Autolock autoLock(mLock);
1019 INIT_CHECK();
1020
1021 if (connected == NULL || max == NULL) {
1022 return BAD_VALUE;
1023 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301024 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001025
1026 *connected = DrmPlugin::kHdcpLevelUnknown;
1027 *max = DrmPlugin::kHdcpLevelUnknown;
1028
1029 Return<void> hResult;
1030 if (mPluginV1_2 != NULL) {
1031 hResult = mPluginV1_2->getHdcpLevels_1_2([&](Status_V1_2 status,
1032 const HdcpLevel_V1_2& hConnected,
1033 const HdcpLevel_V1_2& hMax) {
1034 if (status == Status_V1_2::OK) {
1035 *connected = toHdcpLevel(hConnected);
1036 *max = toHdcpLevel(hMax);
1037 }
1038 err = toStatusT(status);
1039 });
1040 } else if (mPluginV1_1 != NULL) {
1041 hResult = mPluginV1_1->getHdcpLevels(
1042 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1043 if (status == Status::OK) {
1044 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1045 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1046 }
1047 err = toStatusT(status);
1048 });
1049 } else {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301050 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001051 }
1052
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301053 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001054}
1055
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301056DrmStatus DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001057 Mutex::Autolock autoLock(mLock);
1058 INIT_CHECK();
1059
1060 if (open == NULL || max == NULL) {
1061 return BAD_VALUE;
1062 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301063 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001064
1065 *open = 0;
1066 *max = 0;
1067
1068 if (mPluginV1_1 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301069 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001070 }
1071
1072 Return<void> hResult =
1073 mPluginV1_1->getNumberOfSessions([&](Status status, uint32_t hOpen, uint32_t hMax) {
1074 if (status == Status::OK) {
1075 *open = hOpen;
1076 *max = hMax;
1077 }
1078 err = toStatusT(status);
1079 });
1080
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301081 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001082}
1083
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301084DrmStatus DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
1085 DrmPlugin::SecurityLevel* level) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001086 Mutex::Autolock autoLock(mLock);
1087 INIT_CHECK();
1088
1089 if (level == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301090 return DrmStatus(BAD_VALUE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001091 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301092 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001093
1094 if (mPluginV1_1 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301095 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001096 }
1097
1098 *level = DrmPlugin::kSecurityLevelUnknown;
1099
1100 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1101 [&](Status status, SecurityLevel hLevel) {
1102 if (status == Status::OK) {
1103 *level = toSecurityLevel(hLevel);
1104 }
1105 err = toStatusT(status);
1106 });
1107
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301108 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001109}
1110
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301111DrmStatus DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001112 Mutex::Autolock autoLock(mLock);
1113
1114 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301115 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001116 }
1117
1118 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301119 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001120 }
1121
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301122 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001123
1124 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1125 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1126 if (status == Status::OK) {
1127 keySetIds = toKeySetIds(hKeySetIds);
1128 }
1129 err = toStatusT(status);
1130 });
1131
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301132 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001133}
1134
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301135DrmStatus DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001136 Mutex::Autolock autoLock(mLock);
1137
1138 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301139 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001140 }
1141
1142 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301143 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001144 }
1145
1146 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301147 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001148}
1149
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301150DrmStatus DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
1151 DrmPlugin::OfflineLicenseState* licenseState) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001152 Mutex::Autolock autoLock(mLock);
1153
1154 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301155 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001156 }
1157
1158 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301159 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001160 }
1161 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1162
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301163 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001164
1165 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(
1166 toHidlVec(keySetId), [&](Status status, OfflineLicenseState hLicenseState) {
1167 if (status == Status::OK) {
1168 *licenseState = toOfflineLicenseState(hLicenseState);
1169 }
1170 err = toStatusT(status);
1171 });
1172
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301173 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001174}
1175
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301176DrmStatus DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001177 Mutex::Autolock autoLock(mLock);
1178 return getPropertyStringInternal(name, value);
1179}
1180
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301181DrmStatus DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001182 // This function is internal to the class and should only be called while
1183 // mLock is already held.
1184 INIT_CHECK();
1185
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301186 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001187
1188 Return<void> hResult = mPlugin->getPropertyString(
1189 toHidlString(name), [&](Status status, const hidl_string& hValue) {
1190 if (status == Status::OK) {
1191 value = toString8(hValue);
1192 }
1193 err = toStatusT(status);
1194 });
1195
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301196 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001197}
1198
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301199DrmStatus DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001200 Mutex::Autolock autoLock(mLock);
1201 return getPropertyByteArrayInternal(name, value);
1202}
1203
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301204DrmStatus DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
1205 Vector<uint8_t>& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001206 // This function is internal to the class and should only be called while
1207 // mLock is already held.
1208 INIT_CHECK();
1209
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301210 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001211
1212 Return<void> hResult = mPlugin->getPropertyByteArray(
1213 toHidlString(name), [&](Status status, const hidl_vec<uint8_t>& hValue) {
1214 if (status == Status::OK) {
1215 value = toVector(hValue);
1216 }
1217 err = toStatusT(status);
1218 });
1219
1220 err = hResult.isOk() ? err : DEAD_OBJECT;
1221 if (name == kPropertyDeviceUniqueId) {
1222 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1223 }
1224 return err;
1225}
1226
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301227DrmStatus DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001228 Mutex::Autolock autoLock(mLock);
1229 INIT_CHECK();
1230
1231 Return<Status> status = mPlugin->setPropertyString(toHidlString(name), toHidlString(value));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301232 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001233}
1234
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301235DrmStatus DrmHalHidl::setPropertyByteArray(String8 const& name,
1236 Vector<uint8_t> const& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001237 Mutex::Autolock autoLock(mLock);
1238 INIT_CHECK();
1239
1240 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), toHidlVec(value));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301241 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001242}
1243
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301244DrmStatus DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001245 if (consumer == nullptr) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301246 return DrmStatus(UNEXPECTED_NULL);
Kyle Zhang6605add2022-01-13 17:51:23 +00001247 }
1248 consumer->consumeFrameworkMetrics(mMetrics);
1249
1250 // Append vendor metrics if they are supported.
1251 if (mPluginV1_1 != NULL) {
1252 String8 vendor;
1253 String8 description;
1254 if (getPropertyStringInternal(String8("vendor"), vendor) != OK || vendor.isEmpty()) {
1255 ALOGE("Get vendor failed or is empty");
1256 vendor = "NONE";
1257 }
1258 if (getPropertyStringInternal(String8("description"), description) != OK ||
1259 description.isEmpty()) {
1260 ALOGE("Get description failed or is empty.");
1261 description = "NONE";
1262 }
1263 vendor += ".";
1264 vendor += description;
1265
1266 hidl_vec<DrmMetricGroup> pluginMetrics;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301267 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001268
1269 Return<void> status =
1270 mPluginV1_1->getMetrics([&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1271 if (status != Status::OK) {
1272 ALOGV("Error getting plugin metrics: %d", status);
1273 } else {
1274 consumer->consumeHidlMetrics(vendor, pluginMetrics);
1275 }
1276 err = toStatusT(status);
1277 });
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301278 return status.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001279 }
1280
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301281 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001282}
1283
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301284DrmStatus DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
1285 String8 const& algorithm) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001286 Mutex::Autolock autoLock(mLock);
1287 INIT_CHECK();
1288
1289 DrmSessionManager::Instance()->useSession(sessionId);
1290
1291 Return<Status> status =
1292 mPlugin->setCipherAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301293 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001294}
1295
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301296DrmStatus DrmHalHidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001297 Mutex::Autolock autoLock(mLock);
1298 INIT_CHECK();
1299
1300 DrmSessionManager::Instance()->useSession(sessionId);
1301
1302 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301303 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001304}
1305
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301306DrmStatus DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1307 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1308 Vector<uint8_t>& output) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001309 Mutex::Autolock autoLock(mLock);
1310 INIT_CHECK();
1311
1312 DrmSessionManager::Instance()->useSession(sessionId);
1313
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301314 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001315
1316 Return<void> hResult =
1317 mPlugin->encrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1318 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1319 if (status == Status::OK) {
1320 output = toVector(hOutput);
1321 }
1322 err = toStatusT(status);
1323 });
1324
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301325 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001326}
1327
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301328DrmStatus DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1329 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1330 Vector<uint8_t>& output) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001331 Mutex::Autolock autoLock(mLock);
1332 INIT_CHECK();
1333
1334 DrmSessionManager::Instance()->useSession(sessionId);
1335
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301336 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001337
1338 Return<void> hResult =
1339 mPlugin->decrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1340 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1341 if (status == Status::OK) {
1342 output = toVector(hOutput);
1343 }
1344 err = toStatusT(status);
1345 });
1346
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301347 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001348}
1349
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301350DrmStatus DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1351 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001352 Mutex::Autolock autoLock(mLock);
1353 INIT_CHECK();
1354
1355 DrmSessionManager::Instance()->useSession(sessionId);
1356
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301357 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001358
1359 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1360 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1361 if (status == Status::OK) {
1362 signature = toVector(hSignature);
1363 }
1364 err = toStatusT(status);
1365 });
1366
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301367 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001368}
1369
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301370DrmStatus DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1371 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
1372 bool& match) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001373 Mutex::Autolock autoLock(mLock);
1374 INIT_CHECK();
1375
1376 DrmSessionManager::Instance()->useSession(sessionId);
1377
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301378 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001379
1380 Return<void> hResult =
1381 mPlugin->verify(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1382 toHidlVec(signature), [&](Status status, bool hMatch) {
1383 if (status == Status::OK) {
1384 match = hMatch;
1385 } else {
1386 match = false;
1387 }
1388 err = toStatusT(status);
1389 });
1390
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301391 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001392}
1393
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301394DrmStatus DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
1395 Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
1396 Vector<uint8_t>& signature) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001397 Mutex::Autolock autoLock(mLock);
1398 INIT_CHECK();
1399
1400 DrmSessionManager::Instance()->useSession(sessionId);
1401
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301402 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001403
1404 Return<void> hResult = mPlugin->signRSA(
1405 toHidlVec(sessionId), toHidlString(algorithm), toHidlVec(message),
1406 toHidlVec(wrappedKey), [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1407 if (status == Status::OK) {
1408 signature = toVector(hSignature);
1409 }
1410 err = toStatusT(status);
1411 });
1412
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301413 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001414}
1415
1416std::string DrmHalHidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
1417 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1418 mediametrics_setUid(item, mMetrics.GetAppUid());
1419 String8 vendor;
1420 String8 description;
1421 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1422 if (result != OK) {
1423 ALOGE("Failed to get vendor from drm plugin: %d", result);
1424 } else {
1425 mediametrics_setCString(item, "vendor", vendor.c_str());
1426 }
1427 result = getPropertyStringInternal(String8("description"), description);
1428 if (result != OK) {
1429 ALOGE("Failed to get description from drm plugin: %d", result);
1430 } else {
1431 mediametrics_setCString(item, "description", description.c_str());
1432 }
1433
1434 std::string serializedMetrics;
1435 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1436 if (result != OK) {
1437 ALOGE("Failed to serialize framework metrics: %d", result);
1438 }
1439 std::string b64EncodedMetrics =
1440 toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size());
1441 if (!b64EncodedMetrics.empty()) {
1442 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
1443 }
1444 if (!pluginMetrics.empty()) {
1445 mediametrics_setCString(item, "plugin_metrics", pluginMetrics.c_str());
1446 }
1447 if (!mediametrics_selfRecord(item)) {
1448 ALOGE("Failed to self record framework metrics");
1449 }
1450 mediametrics_delete(item);
1451 return serializedMetrics;
1452}
1453
1454std::string DrmHalHidl::reportPluginMetrics() const {
1455 Vector<uint8_t> metricsVector;
1456 String8 vendor;
1457 String8 description;
1458 std::string metricsString;
1459 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1460 getPropertyStringInternal(String8("description"), description) == OK &&
1461 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1462 metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
1463 status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
1464 mMetrics.GetAppUid());
1465 if (res != OK) {
1466 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1467 }
1468 }
1469 return metricsString;
1470}
1471
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301472DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001473 Mutex::Autolock autoLock(mLock);
1474 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301475 return DrmStatus(false);
Kyle Zhang6605add2022-01-13 17:51:23 +00001476 }
1477 auto hResult = mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1478 if (!hResult.isOk()) {
1479 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301480 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001481 }
1482 if (required) {
1483 *required = hResult;
1484 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301485 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001486}
1487
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301488DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime,
1489 DrmPlugin::SecurityLevel securityLevel,
1490 bool* required) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001491 Mutex::Autolock autoLock(mLock);
1492 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301493 return DrmStatus(false);
Kyle Zhang6605add2022-01-13 17:51:23 +00001494 }
1495 auto hLevel = toHidlSecurityLevel(securityLevel);
1496 auto hResult = mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1497 if (!hResult.isOk()) {
1498 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301499 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001500 }
1501 if (required) {
1502 *required = hResult;
1503 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301504 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001505}
1506
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301507DrmStatus DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001508 Mutex::Autolock autoLock(mLock);
1509 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301510 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001511 }
1512 auto err = mPluginV1_4->setPlaybackId(toHidlVec(sessionId), hidl_string(playbackId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301513 return err.isOk() ? DrmStatus(toStatusT(err)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001514}
1515
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301516DrmStatus DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001517 Mutex::Autolock autoLock(mLock);
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301518 return DrmStatus(DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs));
Kyle Zhang6605add2022-01-13 17:51:23 +00001519}
1520
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301521DrmStatus DrmHalHidl::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
Kyle Zhang2567a5e2022-03-17 23:36:26 +00001522 Mutex::Autolock autoLock(mLock);
1523 for (auto &factory : mFactories) {
1524 sp<drm::V1_3::IDrmFactory> factoryV1_3 = drm::V1_3::IDrmFactory::castFrom(factory);
1525 if (factoryV1_3 == nullptr) {
1526 continue;
1527 }
1528
1529 factoryV1_3->getSupportedCryptoSchemes(
1530 [&](const hardware::hidl_vec<hardware::hidl_array<uint8_t, 16>>& schemes_hidl) {
1531 for (const auto &scheme : schemes_hidl) {
1532 schemes.insert(schemes.end(), scheme.data(), scheme.data() + scheme.size());
1533 }
1534 });
1535 }
1536
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301537 return DrmStatus(OK);
Kyle Zhang2567a5e2022-03-17 23:36:26 +00001538}
1539
Kyle Zhang6605add2022-01-13 17:51:23 +00001540} // namespace android