blob: 6010739dbfb5fd116c0791718725a7d45e2d2179 [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;
Robert Shih149d5292023-01-09 12:07:13 -0800517 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000518 }
Robert Shih149d5292023-01-09 12:07:13 -0800519 // isCryptoSchemeSupported(uuid, mimeType)
520 auto hResult = factory->isContentTypeSupported(mimeType.string());
521 if (!hResult.isOk()) {
522 return DrmStatus(DEAD_OBJECT);
523 }
524 *isSupported = hResult;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530525 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000526 } else if (mimeType == "") {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530527 return DrmStatus(BAD_VALUE);
Kyle Zhang6605add2022-01-13 17:51:23 +0000528 }
529
530 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
531 if (factoryV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530532 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +0000533 } else {
Robert Shih149d5292023-01-09 12:07:13 -0800534 auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
Kyle Zhang6605add2022-01-13 17:51:23 +0000535 toHidlSecurityLevel(level));
Robert Shih149d5292023-01-09 12:07:13 -0800536 if (!hResult.isOk()) {
537 return DrmStatus(DEAD_OBJECT);
538 }
539 *isSupported = hResult;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530540 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000541 }
542}
543
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530544DrmStatus DrmHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
545 DrmPlugin::SecurityLevel level, bool* isSupported) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000546 Mutex::Autolock autoLock(mLock);
547 *isSupported = false;
548 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Robert Shih149d5292023-01-09 12:07:13 -0800549 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
550 if (hResult.isOk() && hResult) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000551 return matchMimeTypeAndSecurityLevel(mFactories[i], uuid, mimeType, level, isSupported);
552 }
553 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530554 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000555}
556
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530557DrmStatus DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000558 Mutex::Autolock autoLock(mLock);
559
560 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
561 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
562 if (hResult.isOk() && hResult) {
563 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
564 if (plugin != NULL) {
565 mPlugin = plugin;
566 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
567 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
568 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
569 break;
570 }
571 }
572 }
573
574 if (mPlugin == NULL) {
575 DrmUtils::LOG2BE(uuid, "No supported hal instance found");
576 mInitCheck = ERROR_UNSUPPORTED;
577 } else {
578 mInitCheck = OK;
579 if (mPluginV1_2 != NULL) {
580 if (!mPluginV1_2->setListener(this).isOk()) {
581 mInitCheck = DEAD_OBJECT;
582 }
583 } else if (!mPlugin->setListener(this).isOk()) {
584 mInitCheck = DEAD_OBJECT;
585 }
586 if (mInitCheck != OK) {
587 mPlugin.clear();
588 mPluginV1_1.clear();
589 mPluginV1_2.clear();
590 mPluginV1_4.clear();
591 }
592 }
593
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530594 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +0000595}
596
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530597DrmStatus DrmHalHidl::destroyPlugin() {
Kyle Zhang6605add2022-01-13 17:51:23 +0000598 cleanup();
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530599 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000600}
601
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530602DrmStatus DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000603 Mutex::Autolock autoLock(mLock);
604 INIT_CHECK();
605
606 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
607 bool setSecurityLevel = true;
608
609 if (level == DrmPlugin::kSecurityLevelMax) {
610 setSecurityLevel = false;
611 } else {
612 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
613 return ERROR_DRM_CANNOT_HANDLE;
614 }
615 }
616
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530617 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000618 bool retry = true;
619 do {
620 hidl_vec<uint8_t> hSessionId;
621
622 Return<void> hResult;
623 if (mPluginV1_1 == NULL || !setSecurityLevel) {
624 hResult = mPlugin->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
625 if (status == Status::OK) {
626 sessionId = toVector(id);
627 }
628 err = toStatusT(status);
629 });
630 } else {
631 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
632 [&](Status status, const hidl_vec<uint8_t>& id) {
633 if (status == Status::OK) {
634 sessionId = toVector(id);
635 }
636 err = toStatusT(status);
637 });
638 }
639
640 if (!hResult.isOk()) {
641 err = DEAD_OBJECT;
642 }
643
644 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
645 mLock.unlock();
646 // reclaimSession may call back to closeSession, since mLock is
647 // shared between Drm instances, we should unlock here to avoid
648 // deadlock.
649 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
650 mLock.lock();
651 } else {
652 retry = false;
653 }
654 } while (retry);
655
656 if (err == OK) {
657 std::shared_ptr<DrmSessionClient> client =
658 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
659 DrmSessionManager::Instance()->addSession(
660 AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
661 sessionId);
662 mOpenSessions.push_back(client);
663 mMetrics.SetSessionStart(sessionId);
664 }
665
666 mMetrics.mOpenSessionCounter.Increment(err);
667 return err;
668}
669
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530670DrmStatus DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000671 Mutex::Autolock autoLock(mLock);
672 INIT_CHECK();
673
674 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
675 if (status.isOk()) {
676 if (status == Status::OK) {
677 DrmSessionManager::Instance()->removeSession(sessionId);
678 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
679 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
680 mOpenSessions.erase(i);
681 break;
682 }
683 }
684 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530685 DrmStatus response = toStatusT(status);
Kyle Zhang6605add2022-01-13 17:51:23 +0000686 mMetrics.SetSessionEnd(sessionId);
687 mMetrics.mCloseSessionCounter.Increment(response);
688 return response;
689 }
690 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530691 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000692}
693
694static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
695 switch (keyRequestType) {
696 case KeyRequestType::INITIAL:
697 return DrmPlugin::kKeyRequestType_Initial;
698 break;
699 case KeyRequestType::RENEWAL:
700 return DrmPlugin::kKeyRequestType_Renewal;
701 break;
702 case KeyRequestType::RELEASE:
703 return DrmPlugin::kKeyRequestType_Release;
704 break;
705 default:
706 return DrmPlugin::kKeyRequestType_Unknown;
707 break;
708 }
709}
710
711static DrmPlugin::KeyRequestType toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType) {
712 switch (keyRequestType) {
713 case KeyRequestType_V1_1::NONE:
714 return DrmPlugin::kKeyRequestType_None;
715 break;
716 case KeyRequestType_V1_1::UPDATE:
717 return DrmPlugin::kKeyRequestType_Update;
718 break;
719 default:
720 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
721 break;
722 }
723}
724
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530725DrmStatus DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
726 Vector<uint8_t> const& initData, String8 const& mimeType,
727 DrmPlugin::KeyType keyType,
728 KeyedVector<String8, String8> const& optionalParameters,
729 Vector<uint8_t>& request, String8& defaultUrl,
730 DrmPlugin::KeyRequestType* keyRequestType) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000731 Mutex::Autolock autoLock(mLock);
732 INIT_CHECK();
733 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
734
735 DrmSessionManager::Instance()->useSession(sessionId);
736
737 KeyType hKeyType;
738 if (keyType == DrmPlugin::kKeyType_Streaming) {
739 hKeyType = KeyType::STREAMING;
740 } else if (keyType == DrmPlugin::kKeyType_Offline) {
741 hKeyType = KeyType::OFFLINE;
742 } else if (keyType == DrmPlugin::kKeyType_Release) {
743 hKeyType = KeyType::RELEASE;
744 } else {
745 keyRequestTimer.SetAttribute(BAD_VALUE);
746 return BAD_VALUE;
747 }
748
749 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
750
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530751 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000752 Return<void> hResult;
753
754 if (mPluginV1_2 != NULL) {
755 hResult = mPluginV1_2->getKeyRequest_1_2(
756 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
757 hOptionalParameters,
758 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
759 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
760 if (status == Status_V1_2::OK) {
761 request = toVector(hRequest);
762 defaultUrl = toString8(hDefaultUrl);
763 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
764 }
765 err = toStatusT(status);
766 });
767 } else if (mPluginV1_1 != NULL) {
768 hResult = mPluginV1_1->getKeyRequest_1_1(
769 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
770 hOptionalParameters,
771 [&](Status status, const hidl_vec<uint8_t>& hRequest,
772 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
773 if (status == Status::OK) {
774 request = toVector(hRequest);
775 defaultUrl = toString8(hDefaultUrl);
776 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
777 }
778 err = toStatusT(status);
779 });
780 } else {
781 hResult = mPlugin->getKeyRequest(
782 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
783 hOptionalParameters,
784 [&](Status status, const hidl_vec<uint8_t>& hRequest,
785 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
786 if (status == Status::OK) {
787 request = toVector(hRequest);
788 defaultUrl = toString8(hDefaultUrl);
789 *keyRequestType = toKeyRequestType(hKeyRequestType);
790 }
791 err = toStatusT(status);
792 });
793 }
794
795 err = hResult.isOk() ? err : DEAD_OBJECT;
796 keyRequestTimer.SetAttribute(err);
797 return err;
798}
799
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530800DrmStatus DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
801 Vector<uint8_t> const& response,
802 Vector<uint8_t>& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000803 Mutex::Autolock autoLock(mLock);
804 INIT_CHECK();
805 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
806
807 DrmSessionManager::Instance()->useSession(sessionId);
808
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530809 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000810
811 Return<void> hResult =
812 mPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
813 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
814 if (status == Status::OK) {
815 keySetId = toVector(hKeySetId);
816 }
817 err = toStatusT(status);
818 });
819 err = hResult.isOk() ? err : DEAD_OBJECT;
820 keyResponseTimer.SetAttribute(err);
821 return err;
822}
823
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530824DrmStatus DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000825 Mutex::Autolock autoLock(mLock);
826 INIT_CHECK();
827
828 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530829 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000830}
831
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530832DrmStatus DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
833 Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000834 Mutex::Autolock autoLock(mLock);
835 INIT_CHECK();
836
837 DrmSessionManager::Instance()->useSession(sessionId);
838
839 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530840 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000841}
842
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530843DrmStatus DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
844 KeyedVector<String8, String8>& infoMap) const {
Kyle Zhang6605add2022-01-13 17:51:23 +0000845 Mutex::Autolock autoLock(mLock);
846 INIT_CHECK();
847
848 DrmSessionManager::Instance()->useSession(sessionId);
849
850 ::KeyedVector hInfoMap;
851
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530852 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000853
854 Return<void> hResult = mPlugin->queryKeyStatus(
855 toHidlVec(sessionId), [&](Status status, const hidl_vec<KeyValue>& map) {
856 if (status == Status::OK) {
857 infoMap = toKeyedVector(map);
858 }
859 err = toStatusT(status);
860 });
861
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530862 return hResult.isOk() ? DrmStatus(err) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000863}
864
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530865DrmStatus DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
866 Vector<uint8_t>& request, String8& defaultUrl) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000867 Mutex::Autolock autoLock(mLock);
868 INIT_CHECK();
869
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530870 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000871 Return<void> hResult;
872
873 if (mPluginV1_2 != NULL) {
874 hResult = mPluginV1_2->getProvisionRequest_1_2(
875 toHidlString(certType), toHidlString(certAuthority),
876 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
877 const hidl_string& hDefaultUrl) {
878 if (status == Status_V1_2::OK) {
879 request = toVector(hRequest);
880 defaultUrl = toString8(hDefaultUrl);
881 }
882 err = toStatusT(status);
883 });
884 } else {
885 hResult = mPlugin->getProvisionRequest(toHidlString(certType), toHidlString(certAuthority),
886 [&](Status status, const hidl_vec<uint8_t>& hRequest,
887 const hidl_string& hDefaultUrl) {
888 if (status == Status::OK) {
889 request = toVector(hRequest);
890 defaultUrl = toString8(hDefaultUrl);
891 }
892 err = toStatusT(status);
893 });
894 }
895
896 err = hResult.isOk() ? err : DEAD_OBJECT;
897 mMetrics.mGetProvisionRequestCounter.Increment(err);
898 return err;
899}
900
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530901DrmStatus DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
902 Vector<uint8_t>& certificate,
903 Vector<uint8_t>& wrappedKey) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000904 Mutex::Autolock autoLock(mLock);
905 INIT_CHECK();
906
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530907 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000908
909 Return<void> hResult = mPlugin->provideProvisionResponse(
910 toHidlVec(response), [&](Status status, const hidl_vec<uint8_t>& hCertificate,
911 const hidl_vec<uint8_t>& hWrappedKey) {
912 if (status == Status::OK) {
913 certificate = toVector(hCertificate);
914 wrappedKey = toVector(hWrappedKey);
915 }
916 err = toStatusT(status);
917 });
918
919 err = hResult.isOk() ? err : DEAD_OBJECT;
920 mMetrics.mProvideProvisionResponseCounter.Increment(err);
921 return err;
922}
923
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530924DrmStatus DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000925 Mutex::Autolock autoLock(mLock);
926 INIT_CHECK();
927
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530928 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000929
930 Return<void> hResult =
931 mPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
932 if (status == Status::OK) {
933 secureStops = toSecureStops(hSecureStops);
934 }
935 err = toStatusT(status);
936 });
937
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530938 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000939}
940
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530941DrmStatus DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000942 Mutex::Autolock autoLock(mLock);
943
944 if (mInitCheck != OK) {
945 return mInitCheck;
946 }
947
948 if (mPluginV1_1 == NULL) {
949 return ERROR_DRM_CANNOT_HANDLE;
950 }
951
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530952 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000953
954 Return<void> hResult = mPluginV1_1->getSecureStopIds(
955 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
956 if (status == Status::OK) {
957 secureStopIds = toSecureStopIds(hSecureStopIds);
958 }
959 err = toStatusT(status);
960 });
961
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530962 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000963}
964
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530965DrmStatus DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000966 Mutex::Autolock autoLock(mLock);
967 INIT_CHECK();
968
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530969 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000970
971 Return<void> hResult = mPlugin->getSecureStop(
972 toHidlVec(ssid), [&](Status status, const SecureStop& hSecureStop) {
973 if (status == Status::OK) {
974 secureStop = toVector(hSecureStop.opaqueData);
975 }
976 err = toStatusT(status);
977 });
978
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530979 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000980}
981
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530982DrmStatus DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000983 Mutex::Autolock autoLock(mLock);
984 INIT_CHECK();
985
986 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
987 if (mPluginV1_1 != NULL) {
988 SecureStopRelease secureStopRelease;
989 secureStopRelease.opaqueData = toHidlVec(ssRelease);
990 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
991 } else {
992 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
993 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530994 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000995}
996
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530997DrmStatus DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000998 Mutex::Autolock autoLock(mLock);
999
1000 if (mInitCheck != OK) {
1001 return mInitCheck;
1002 }
1003
1004 if (mPluginV1_1 == NULL) {
1005 return ERROR_DRM_CANNOT_HANDLE;
1006 }
1007
1008 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301009 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001010}
1011
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301012DrmStatus DrmHalHidl::removeAllSecureStops() {
Kyle Zhang6605add2022-01-13 17:51:23 +00001013 Mutex::Autolock autoLock(mLock);
1014 INIT_CHECK();
1015
1016 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1017 if (mPluginV1_1 != NULL) {
1018 status = mPluginV1_1->removeAllSecureStops();
1019 } else {
1020 status = mPlugin->releaseAllSecureStops();
1021 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301022 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001023}
1024
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301025DrmStatus DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
1026 DrmPlugin::HdcpLevel* max) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001027 Mutex::Autolock autoLock(mLock);
1028 INIT_CHECK();
1029
1030 if (connected == NULL || max == NULL) {
1031 return BAD_VALUE;
1032 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301033 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001034
1035 *connected = DrmPlugin::kHdcpLevelUnknown;
1036 *max = DrmPlugin::kHdcpLevelUnknown;
1037
1038 Return<void> hResult;
1039 if (mPluginV1_2 != NULL) {
1040 hResult = mPluginV1_2->getHdcpLevels_1_2([&](Status_V1_2 status,
1041 const HdcpLevel_V1_2& hConnected,
1042 const HdcpLevel_V1_2& hMax) {
1043 if (status == Status_V1_2::OK) {
1044 *connected = toHdcpLevel(hConnected);
1045 *max = toHdcpLevel(hMax);
1046 }
1047 err = toStatusT(status);
1048 });
1049 } else if (mPluginV1_1 != NULL) {
1050 hResult = mPluginV1_1->getHdcpLevels(
1051 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1052 if (status == Status::OK) {
1053 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1054 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1055 }
1056 err = toStatusT(status);
1057 });
1058 } else {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301059 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001060 }
1061
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301062 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001063}
1064
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301065DrmStatus DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001066 Mutex::Autolock autoLock(mLock);
1067 INIT_CHECK();
1068
1069 if (open == NULL || max == NULL) {
1070 return BAD_VALUE;
1071 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301072 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001073
1074 *open = 0;
1075 *max = 0;
1076
1077 if (mPluginV1_1 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301078 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001079 }
1080
1081 Return<void> hResult =
1082 mPluginV1_1->getNumberOfSessions([&](Status status, uint32_t hOpen, uint32_t hMax) {
1083 if (status == Status::OK) {
1084 *open = hOpen;
1085 *max = hMax;
1086 }
1087 err = toStatusT(status);
1088 });
1089
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301090 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001091}
1092
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301093DrmStatus DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
1094 DrmPlugin::SecurityLevel* level) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001095 Mutex::Autolock autoLock(mLock);
1096 INIT_CHECK();
1097
1098 if (level == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301099 return DrmStatus(BAD_VALUE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001100 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301101 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001102
1103 if (mPluginV1_1 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301104 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001105 }
1106
1107 *level = DrmPlugin::kSecurityLevelUnknown;
1108
1109 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1110 [&](Status status, SecurityLevel hLevel) {
1111 if (status == Status::OK) {
1112 *level = toSecurityLevel(hLevel);
1113 }
1114 err = toStatusT(status);
1115 });
1116
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301117 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001118}
1119
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301120DrmStatus DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001121 Mutex::Autolock autoLock(mLock);
1122
1123 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301124 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001125 }
1126
1127 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301128 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001129 }
1130
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301131 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001132
1133 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1134 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1135 if (status == Status::OK) {
1136 keySetIds = toKeySetIds(hKeySetIds);
1137 }
1138 err = toStatusT(status);
1139 });
1140
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301141 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001142}
1143
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301144DrmStatus DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001145 Mutex::Autolock autoLock(mLock);
1146
1147 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301148 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001149 }
1150
1151 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301152 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001153 }
1154
1155 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301156 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001157}
1158
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301159DrmStatus DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
1160 DrmPlugin::OfflineLicenseState* licenseState) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001161 Mutex::Autolock autoLock(mLock);
1162
1163 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301164 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001165 }
1166
1167 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301168 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001169 }
1170 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1171
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301172 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001173
1174 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(
1175 toHidlVec(keySetId), [&](Status status, OfflineLicenseState hLicenseState) {
1176 if (status == Status::OK) {
1177 *licenseState = toOfflineLicenseState(hLicenseState);
1178 }
1179 err = toStatusT(status);
1180 });
1181
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301182 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001183}
1184
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301185DrmStatus DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001186 Mutex::Autolock autoLock(mLock);
1187 return getPropertyStringInternal(name, value);
1188}
1189
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301190DrmStatus DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001191 // This function is internal to the class and should only be called while
1192 // mLock is already held.
1193 INIT_CHECK();
1194
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301195 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001196
1197 Return<void> hResult = mPlugin->getPropertyString(
1198 toHidlString(name), [&](Status status, const hidl_string& hValue) {
1199 if (status == Status::OK) {
1200 value = toString8(hValue);
1201 }
1202 err = toStatusT(status);
1203 });
1204
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301205 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001206}
1207
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301208DrmStatus DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001209 Mutex::Autolock autoLock(mLock);
1210 return getPropertyByteArrayInternal(name, value);
1211}
1212
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301213DrmStatus DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
1214 Vector<uint8_t>& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001215 // This function is internal to the class and should only be called while
1216 // mLock is already held.
1217 INIT_CHECK();
1218
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301219 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001220
1221 Return<void> hResult = mPlugin->getPropertyByteArray(
1222 toHidlString(name), [&](Status status, const hidl_vec<uint8_t>& hValue) {
1223 if (status == Status::OK) {
1224 value = toVector(hValue);
1225 }
1226 err = toStatusT(status);
1227 });
1228
1229 err = hResult.isOk() ? err : DEAD_OBJECT;
1230 if (name == kPropertyDeviceUniqueId) {
1231 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1232 }
1233 return err;
1234}
1235
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301236DrmStatus DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001237 Mutex::Autolock autoLock(mLock);
1238 INIT_CHECK();
1239
1240 Return<Status> status = mPlugin->setPropertyString(toHidlString(name), toHidlString(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::setPropertyByteArray(String8 const& name,
1245 Vector<uint8_t> const& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001246 Mutex::Autolock autoLock(mLock);
1247 INIT_CHECK();
1248
1249 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), toHidlVec(value));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301250 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001251}
1252
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301253DrmStatus DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001254 if (consumer == nullptr) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301255 return DrmStatus(UNEXPECTED_NULL);
Kyle Zhang6605add2022-01-13 17:51:23 +00001256 }
1257 consumer->consumeFrameworkMetrics(mMetrics);
1258
1259 // Append vendor metrics if they are supported.
1260 if (mPluginV1_1 != NULL) {
1261 String8 vendor;
1262 String8 description;
1263 if (getPropertyStringInternal(String8("vendor"), vendor) != OK || vendor.isEmpty()) {
1264 ALOGE("Get vendor failed or is empty");
1265 vendor = "NONE";
1266 }
1267 if (getPropertyStringInternal(String8("description"), description) != OK ||
1268 description.isEmpty()) {
1269 ALOGE("Get description failed or is empty.");
1270 description = "NONE";
1271 }
1272 vendor += ".";
1273 vendor += description;
1274
1275 hidl_vec<DrmMetricGroup> pluginMetrics;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301276 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001277
1278 Return<void> status =
1279 mPluginV1_1->getMetrics([&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1280 if (status != Status::OK) {
1281 ALOGV("Error getting plugin metrics: %d", status);
1282 } else {
1283 consumer->consumeHidlMetrics(vendor, pluginMetrics);
1284 }
1285 err = toStatusT(status);
1286 });
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301287 return status.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001288 }
1289
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301290 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001291}
1292
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301293DrmStatus DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
1294 String8 const& algorithm) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001295 Mutex::Autolock autoLock(mLock);
1296 INIT_CHECK();
1297
1298 DrmSessionManager::Instance()->useSession(sessionId);
1299
1300 Return<Status> status =
1301 mPlugin->setCipherAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301302 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001303}
1304
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301305DrmStatus DrmHalHidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001306 Mutex::Autolock autoLock(mLock);
1307 INIT_CHECK();
1308
1309 DrmSessionManager::Instance()->useSession(sessionId);
1310
1311 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301312 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001313}
1314
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301315DrmStatus DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1316 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1317 Vector<uint8_t>& output) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001318 Mutex::Autolock autoLock(mLock);
1319 INIT_CHECK();
1320
1321 DrmSessionManager::Instance()->useSession(sessionId);
1322
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301323 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001324
1325 Return<void> hResult =
1326 mPlugin->encrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1327 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1328 if (status == Status::OK) {
1329 output = toVector(hOutput);
1330 }
1331 err = toStatusT(status);
1332 });
1333
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301334 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001335}
1336
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301337DrmStatus DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1338 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1339 Vector<uint8_t>& output) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001340 Mutex::Autolock autoLock(mLock);
1341 INIT_CHECK();
1342
1343 DrmSessionManager::Instance()->useSession(sessionId);
1344
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301345 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001346
1347 Return<void> hResult =
1348 mPlugin->decrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1349 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1350 if (status == Status::OK) {
1351 output = toVector(hOutput);
1352 }
1353 err = toStatusT(status);
1354 });
1355
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301356 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001357}
1358
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301359DrmStatus DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1360 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001361 Mutex::Autolock autoLock(mLock);
1362 INIT_CHECK();
1363
1364 DrmSessionManager::Instance()->useSession(sessionId);
1365
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301366 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001367
1368 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1369 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1370 if (status == Status::OK) {
1371 signature = toVector(hSignature);
1372 }
1373 err = toStatusT(status);
1374 });
1375
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301376 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001377}
1378
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301379DrmStatus DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1380 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
1381 bool& match) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001382 Mutex::Autolock autoLock(mLock);
1383 INIT_CHECK();
1384
1385 DrmSessionManager::Instance()->useSession(sessionId);
1386
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301387 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001388
1389 Return<void> hResult =
1390 mPlugin->verify(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1391 toHidlVec(signature), [&](Status status, bool hMatch) {
1392 if (status == Status::OK) {
1393 match = hMatch;
1394 } else {
1395 match = false;
1396 }
1397 err = toStatusT(status);
1398 });
1399
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301400 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001401}
1402
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301403DrmStatus DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
1404 Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
1405 Vector<uint8_t>& signature) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001406 Mutex::Autolock autoLock(mLock);
1407 INIT_CHECK();
1408
1409 DrmSessionManager::Instance()->useSession(sessionId);
1410
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301411 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001412
1413 Return<void> hResult = mPlugin->signRSA(
1414 toHidlVec(sessionId), toHidlString(algorithm), toHidlVec(message),
1415 toHidlVec(wrappedKey), [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1416 if (status == Status::OK) {
1417 signature = toVector(hSignature);
1418 }
1419 err = toStatusT(status);
1420 });
1421
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301422 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001423}
1424
1425std::string DrmHalHidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
1426 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1427 mediametrics_setUid(item, mMetrics.GetAppUid());
1428 String8 vendor;
1429 String8 description;
1430 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1431 if (result != OK) {
1432 ALOGE("Failed to get vendor from drm plugin: %d", result);
1433 } else {
1434 mediametrics_setCString(item, "vendor", vendor.c_str());
1435 }
1436 result = getPropertyStringInternal(String8("description"), description);
1437 if (result != OK) {
1438 ALOGE("Failed to get description from drm plugin: %d", result);
1439 } else {
1440 mediametrics_setCString(item, "description", description.c_str());
1441 }
1442
1443 std::string serializedMetrics;
1444 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1445 if (result != OK) {
1446 ALOGE("Failed to serialize framework metrics: %d", result);
1447 }
1448 std::string b64EncodedMetrics =
1449 toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size());
1450 if (!b64EncodedMetrics.empty()) {
1451 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
1452 }
1453 if (!pluginMetrics.empty()) {
1454 mediametrics_setCString(item, "plugin_metrics", pluginMetrics.c_str());
1455 }
1456 if (!mediametrics_selfRecord(item)) {
1457 ALOGE("Failed to self record framework metrics");
1458 }
1459 mediametrics_delete(item);
1460 return serializedMetrics;
1461}
1462
1463std::string DrmHalHidl::reportPluginMetrics() const {
1464 Vector<uint8_t> metricsVector;
1465 String8 vendor;
1466 String8 description;
1467 std::string metricsString;
1468 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1469 getPropertyStringInternal(String8("description"), description) == OK &&
1470 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1471 metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
1472 status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
1473 mMetrics.GetAppUid());
1474 if (res != OK) {
1475 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1476 }
1477 }
1478 return metricsString;
1479}
1480
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301481DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001482 Mutex::Autolock autoLock(mLock);
1483 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301484 return DrmStatus(false);
Kyle Zhang6605add2022-01-13 17:51:23 +00001485 }
1486 auto hResult = mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1487 if (!hResult.isOk()) {
1488 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301489 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001490 }
1491 if (required) {
1492 *required = hResult;
1493 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301494 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001495}
1496
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301497DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime,
1498 DrmPlugin::SecurityLevel securityLevel,
1499 bool* required) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001500 Mutex::Autolock autoLock(mLock);
1501 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301502 return DrmStatus(false);
Kyle Zhang6605add2022-01-13 17:51:23 +00001503 }
1504 auto hLevel = toHidlSecurityLevel(securityLevel);
1505 auto hResult = mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1506 if (!hResult.isOk()) {
1507 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301508 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001509 }
1510 if (required) {
1511 *required = hResult;
1512 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301513 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001514}
1515
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301516DrmStatus DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001517 Mutex::Autolock autoLock(mLock);
1518 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301519 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001520 }
1521 auto err = mPluginV1_4->setPlaybackId(toHidlVec(sessionId), hidl_string(playbackId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301522 return err.isOk() ? DrmStatus(toStatusT(err)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001523}
1524
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301525DrmStatus DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001526 Mutex::Autolock autoLock(mLock);
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301527 return DrmStatus(DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs));
Kyle Zhang6605add2022-01-13 17:51:23 +00001528}
1529
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301530DrmStatus DrmHalHidl::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
Kyle Zhang2567a5e2022-03-17 23:36:26 +00001531 Mutex::Autolock autoLock(mLock);
1532 for (auto &factory : mFactories) {
1533 sp<drm::V1_3::IDrmFactory> factoryV1_3 = drm::V1_3::IDrmFactory::castFrom(factory);
1534 if (factoryV1_3 == nullptr) {
1535 continue;
1536 }
1537
1538 factoryV1_3->getSupportedCryptoSchemes(
1539 [&](const hardware::hidl_vec<hardware::hidl_array<uint8_t, 16>>& schemes_hidl) {
1540 for (const auto &scheme : schemes_hidl) {
1541 schemes.insert(schemes.end(), scheme.data(), scheme.data() + scheme.size());
1542 }
1543 });
1544 }
1545
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301546 return DrmStatus(OK);
Kyle Zhang2567a5e2022-03-17 23:36:26 +00001547}
1548
Kyle Zhang6605add2022-01-13 17:51:23 +00001549} // namespace android