blob: 33ea5ea9fc3cbb7e80f22b15a003b020602f6e3b [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) {
Tomasz Wasilczyk09977ff2023-08-11 15:52:22 +0000124 return hidl_string(string.c_str());
Kyle Zhang6605add2022-01-13 17:51:23 +0000125}
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>");
Tomasz Wasilczykfd9ffd12023-08-14 17:56:22 +0000276 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK || name.empty()) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000277 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);
Kyle Zhangab5fc432022-06-13 17:57:39 +0000313 if (mInitCheck == OK) reportFrameworkMetrics(reportPluginMetrics());
Kyle Zhang6605add2022-01-13 17:51:23 +0000314
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 Zhang06bfbcb2024-11-13 01:15:14 +0000342 DrmUtils::LOG2BW("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(
Tomasz Wasilczyk09977ff2023-08-11 15:52:22 +0000356 uuid, appPackageName.c_str(), [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000357 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)
Tomasz Wasilczyk09977ff2023-08-11 15:52:22 +0000520 auto hResult = factory->isContentTypeSupported(mimeType.c_str());
Robert Shih149d5292023-01-09 12:07:13 -0800521 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 {
Tomasz Wasilczyk09977ff2023-08-11 15:52:22 +0000534 auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.c_str(),
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
Kyle Zhang4a7dd2c2023-03-01 21:13:29 +0000560 if (mInitCheck == ERROR_UNSUPPORTED) return mInitCheck;
Kyle Zhang6605add2022-01-13 17:51:23 +0000561 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
562 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
563 if (hResult.isOk() && hResult) {
564 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
565 if (plugin != NULL) {
566 mPlugin = plugin;
567 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
568 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
569 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
570 break;
571 }
572 }
573 }
574
575 if (mPlugin == NULL) {
576 DrmUtils::LOG2BE(uuid, "No supported hal instance found");
577 mInitCheck = ERROR_UNSUPPORTED;
578 } else {
579 mInitCheck = OK;
580 if (mPluginV1_2 != NULL) {
581 if (!mPluginV1_2->setListener(this).isOk()) {
582 mInitCheck = DEAD_OBJECT;
583 }
584 } else if (!mPlugin->setListener(this).isOk()) {
585 mInitCheck = DEAD_OBJECT;
586 }
587 if (mInitCheck != OK) {
588 mPlugin.clear();
589 mPluginV1_1.clear();
590 mPluginV1_2.clear();
591 mPluginV1_4.clear();
592 }
593 }
594
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530595 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +0000596}
597
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530598DrmStatus DrmHalHidl::destroyPlugin() {
Kyle Zhang6605add2022-01-13 17:51:23 +0000599 cleanup();
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530600 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +0000601}
602
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530603DrmStatus DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000604 Mutex::Autolock autoLock(mLock);
605 INIT_CHECK();
606
607 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
608 bool setSecurityLevel = true;
609
610 if (level == DrmPlugin::kSecurityLevelMax) {
611 setSecurityLevel = false;
612 } else {
613 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
614 return ERROR_DRM_CANNOT_HANDLE;
615 }
616 }
617
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530618 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000619 bool retry = true;
620 do {
621 hidl_vec<uint8_t> hSessionId;
622
623 Return<void> hResult;
624 if (mPluginV1_1 == NULL || !setSecurityLevel) {
625 hResult = mPlugin->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
626 if (status == Status::OK) {
627 sessionId = toVector(id);
628 }
629 err = toStatusT(status);
630 });
631 } else {
632 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
633 [&](Status status, const hidl_vec<uint8_t>& id) {
634 if (status == Status::OK) {
635 sessionId = toVector(id);
636 }
637 err = toStatusT(status);
638 });
639 }
640
641 if (!hResult.isOk()) {
642 err = DEAD_OBJECT;
643 }
644
645 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
646 mLock.unlock();
647 // reclaimSession may call back to closeSession, since mLock is
648 // shared between Drm instances, we should unlock here to avoid
649 // deadlock.
650 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
651 mLock.lock();
652 } else {
653 retry = false;
654 }
655 } while (retry);
656
657 if (err == OK) {
658 std::shared_ptr<DrmSessionClient> client =
659 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
660 DrmSessionManager::Instance()->addSession(
661 AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
662 sessionId);
663 mOpenSessions.push_back(client);
664 mMetrics.SetSessionStart(sessionId);
665 }
666
667 mMetrics.mOpenSessionCounter.Increment(err);
668 return err;
669}
670
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530671DrmStatus DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000672 Mutex::Autolock autoLock(mLock);
673 INIT_CHECK();
674
675 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
676 if (status.isOk()) {
677 if (status == Status::OK) {
678 DrmSessionManager::Instance()->removeSession(sessionId);
679 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
680 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
681 mOpenSessions.erase(i);
682 break;
683 }
684 }
685 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530686 DrmStatus response = toStatusT(status);
Kyle Zhang6605add2022-01-13 17:51:23 +0000687 mMetrics.SetSessionEnd(sessionId);
688 mMetrics.mCloseSessionCounter.Increment(response);
689 return response;
690 }
691 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530692 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000693}
694
695static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
696 switch (keyRequestType) {
697 case KeyRequestType::INITIAL:
698 return DrmPlugin::kKeyRequestType_Initial;
699 break;
700 case KeyRequestType::RENEWAL:
701 return DrmPlugin::kKeyRequestType_Renewal;
702 break;
703 case KeyRequestType::RELEASE:
704 return DrmPlugin::kKeyRequestType_Release;
705 break;
706 default:
707 return DrmPlugin::kKeyRequestType_Unknown;
708 break;
709 }
710}
711
712static DrmPlugin::KeyRequestType toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType) {
713 switch (keyRequestType) {
714 case KeyRequestType_V1_1::NONE:
715 return DrmPlugin::kKeyRequestType_None;
716 break;
717 case KeyRequestType_V1_1::UPDATE:
718 return DrmPlugin::kKeyRequestType_Update;
719 break;
720 default:
721 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
722 break;
723 }
724}
725
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530726DrmStatus DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
727 Vector<uint8_t> const& initData, String8 const& mimeType,
728 DrmPlugin::KeyType keyType,
729 KeyedVector<String8, String8> const& optionalParameters,
730 Vector<uint8_t>& request, String8& defaultUrl,
731 DrmPlugin::KeyRequestType* keyRequestType) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000732 Mutex::Autolock autoLock(mLock);
733 INIT_CHECK();
734 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
735
736 DrmSessionManager::Instance()->useSession(sessionId);
737
738 KeyType hKeyType;
739 if (keyType == DrmPlugin::kKeyType_Streaming) {
740 hKeyType = KeyType::STREAMING;
741 } else if (keyType == DrmPlugin::kKeyType_Offline) {
742 hKeyType = KeyType::OFFLINE;
743 } else if (keyType == DrmPlugin::kKeyType_Release) {
744 hKeyType = KeyType::RELEASE;
745 } else {
746 keyRequestTimer.SetAttribute(BAD_VALUE);
747 return BAD_VALUE;
748 }
749
750 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
751
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530752 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000753 Return<void> hResult;
754
755 if (mPluginV1_2 != NULL) {
756 hResult = mPluginV1_2->getKeyRequest_1_2(
757 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
758 hOptionalParameters,
759 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
760 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
761 if (status == Status_V1_2::OK) {
762 request = toVector(hRequest);
763 defaultUrl = toString8(hDefaultUrl);
764 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
765 }
766 err = toStatusT(status);
767 });
768 } else if (mPluginV1_1 != NULL) {
769 hResult = mPluginV1_1->getKeyRequest_1_1(
770 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
771 hOptionalParameters,
772 [&](Status status, const hidl_vec<uint8_t>& hRequest,
773 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
774 if (status == Status::OK) {
775 request = toVector(hRequest);
776 defaultUrl = toString8(hDefaultUrl);
777 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
778 }
779 err = toStatusT(status);
780 });
781 } else {
782 hResult = mPlugin->getKeyRequest(
783 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
784 hOptionalParameters,
785 [&](Status status, const hidl_vec<uint8_t>& hRequest,
786 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
787 if (status == Status::OK) {
788 request = toVector(hRequest);
789 defaultUrl = toString8(hDefaultUrl);
790 *keyRequestType = toKeyRequestType(hKeyRequestType);
791 }
792 err = toStatusT(status);
793 });
794 }
795
796 err = hResult.isOk() ? err : DEAD_OBJECT;
797 keyRequestTimer.SetAttribute(err);
798 return err;
799}
800
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530801DrmStatus DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
802 Vector<uint8_t> const& response,
803 Vector<uint8_t>& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000804 Mutex::Autolock autoLock(mLock);
805 INIT_CHECK();
806 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
807
808 DrmSessionManager::Instance()->useSession(sessionId);
809
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530810 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000811
812 Return<void> hResult =
813 mPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
814 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
815 if (status == Status::OK) {
816 keySetId = toVector(hKeySetId);
817 }
818 err = toStatusT(status);
819 });
820 err = hResult.isOk() ? err : DEAD_OBJECT;
821 keyResponseTimer.SetAttribute(err);
822 return err;
823}
824
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530825DrmStatus DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000826 Mutex::Autolock autoLock(mLock);
827 INIT_CHECK();
828
829 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530830 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000831}
832
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530833DrmStatus DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
834 Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000835 Mutex::Autolock autoLock(mLock);
836 INIT_CHECK();
837
838 DrmSessionManager::Instance()->useSession(sessionId);
839
840 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530841 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000842}
843
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530844DrmStatus DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
845 KeyedVector<String8, String8>& infoMap) const {
Kyle Zhang6605add2022-01-13 17:51:23 +0000846 Mutex::Autolock autoLock(mLock);
847 INIT_CHECK();
848
849 DrmSessionManager::Instance()->useSession(sessionId);
850
851 ::KeyedVector hInfoMap;
852
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530853 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000854
855 Return<void> hResult = mPlugin->queryKeyStatus(
856 toHidlVec(sessionId), [&](Status status, const hidl_vec<KeyValue>& map) {
857 if (status == Status::OK) {
858 infoMap = toKeyedVector(map);
859 }
860 err = toStatusT(status);
861 });
862
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530863 return hResult.isOk() ? DrmStatus(err) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000864}
865
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530866DrmStatus DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
867 Vector<uint8_t>& request, String8& defaultUrl) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000868 Mutex::Autolock autoLock(mLock);
869 INIT_CHECK();
870
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530871 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000872 Return<void> hResult;
873
874 if (mPluginV1_2 != NULL) {
875 hResult = mPluginV1_2->getProvisionRequest_1_2(
876 toHidlString(certType), toHidlString(certAuthority),
877 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
878 const hidl_string& hDefaultUrl) {
879 if (status == Status_V1_2::OK) {
880 request = toVector(hRequest);
881 defaultUrl = toString8(hDefaultUrl);
882 }
883 err = toStatusT(status);
884 });
885 } else {
886 hResult = mPlugin->getProvisionRequest(toHidlString(certType), toHidlString(certAuthority),
887 [&](Status status, const hidl_vec<uint8_t>& hRequest,
888 const hidl_string& hDefaultUrl) {
889 if (status == Status::OK) {
890 request = toVector(hRequest);
891 defaultUrl = toString8(hDefaultUrl);
892 }
893 err = toStatusT(status);
894 });
895 }
896
897 err = hResult.isOk() ? err : DEAD_OBJECT;
898 mMetrics.mGetProvisionRequestCounter.Increment(err);
899 return err;
900}
901
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530902DrmStatus DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
903 Vector<uint8_t>& certificate,
904 Vector<uint8_t>& wrappedKey) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000905 Mutex::Autolock autoLock(mLock);
906 INIT_CHECK();
907
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530908 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000909
910 Return<void> hResult = mPlugin->provideProvisionResponse(
911 toHidlVec(response), [&](Status status, const hidl_vec<uint8_t>& hCertificate,
912 const hidl_vec<uint8_t>& hWrappedKey) {
913 if (status == Status::OK) {
914 certificate = toVector(hCertificate);
915 wrappedKey = toVector(hWrappedKey);
916 }
917 err = toStatusT(status);
918 });
919
920 err = hResult.isOk() ? err : DEAD_OBJECT;
921 mMetrics.mProvideProvisionResponseCounter.Increment(err);
922 return err;
923}
924
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530925DrmStatus DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000926 Mutex::Autolock autoLock(mLock);
927 INIT_CHECK();
928
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530929 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000930
931 Return<void> hResult =
932 mPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
933 if (status == Status::OK) {
934 secureStops = toSecureStops(hSecureStops);
935 }
936 err = toStatusT(status);
937 });
938
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530939 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000940}
941
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530942DrmStatus DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000943 Mutex::Autolock autoLock(mLock);
944
945 if (mInitCheck != OK) {
946 return mInitCheck;
947 }
948
949 if (mPluginV1_1 == NULL) {
950 return ERROR_DRM_CANNOT_HANDLE;
951 }
952
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530953 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000954
955 Return<void> hResult = mPluginV1_1->getSecureStopIds(
956 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
957 if (status == Status::OK) {
958 secureStopIds = toSecureStopIds(hSecureStopIds);
959 }
960 err = toStatusT(status);
961 });
962
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530963 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000964}
965
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530966DrmStatus DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000967 Mutex::Autolock autoLock(mLock);
968 INIT_CHECK();
969
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530970 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +0000971
972 Return<void> hResult = mPlugin->getSecureStop(
973 toHidlVec(ssid), [&](Status status, const SecureStop& hSecureStop) {
974 if (status == Status::OK) {
975 secureStop = toVector(hSecureStop.opaqueData);
976 }
977 err = toStatusT(status);
978 });
979
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530980 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000981}
982
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530983DrmStatus DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000984 Mutex::Autolock autoLock(mLock);
985 INIT_CHECK();
986
987 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
988 if (mPluginV1_1 != NULL) {
989 SecureStopRelease secureStopRelease;
990 secureStopRelease.opaqueData = toHidlVec(ssRelease);
991 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
992 } else {
993 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
994 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530995 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +0000996}
997
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530998DrmStatus DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000999 Mutex::Autolock autoLock(mLock);
1000
1001 if (mInitCheck != OK) {
1002 return mInitCheck;
1003 }
1004
1005 if (mPluginV1_1 == NULL) {
1006 return ERROR_DRM_CANNOT_HANDLE;
1007 }
1008
1009 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301010 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001011}
1012
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301013DrmStatus DrmHalHidl::removeAllSecureStops() {
Kyle Zhang6605add2022-01-13 17:51:23 +00001014 Mutex::Autolock autoLock(mLock);
1015 INIT_CHECK();
1016
1017 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1018 if (mPluginV1_1 != NULL) {
1019 status = mPluginV1_1->removeAllSecureStops();
1020 } else {
1021 status = mPlugin->releaseAllSecureStops();
1022 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301023 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001024}
1025
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301026DrmStatus DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
1027 DrmPlugin::HdcpLevel* max) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001028 Mutex::Autolock autoLock(mLock);
1029 INIT_CHECK();
1030
1031 if (connected == NULL || max == NULL) {
1032 return BAD_VALUE;
1033 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301034 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001035
1036 *connected = DrmPlugin::kHdcpLevelUnknown;
1037 *max = DrmPlugin::kHdcpLevelUnknown;
1038
1039 Return<void> hResult;
1040 if (mPluginV1_2 != NULL) {
1041 hResult = mPluginV1_2->getHdcpLevels_1_2([&](Status_V1_2 status,
1042 const HdcpLevel_V1_2& hConnected,
1043 const HdcpLevel_V1_2& hMax) {
1044 if (status == Status_V1_2::OK) {
1045 *connected = toHdcpLevel(hConnected);
1046 *max = toHdcpLevel(hMax);
1047 }
1048 err = toStatusT(status);
1049 });
1050 } else if (mPluginV1_1 != NULL) {
1051 hResult = mPluginV1_1->getHdcpLevels(
1052 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1053 if (status == Status::OK) {
1054 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1055 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1056 }
1057 err = toStatusT(status);
1058 });
1059 } else {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301060 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001061 }
1062
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301063 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001064}
1065
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301066DrmStatus DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001067 Mutex::Autolock autoLock(mLock);
1068 INIT_CHECK();
1069
1070 if (open == NULL || max == NULL) {
1071 return BAD_VALUE;
1072 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301073 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001074
1075 *open = 0;
1076 *max = 0;
1077
1078 if (mPluginV1_1 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301079 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001080 }
1081
1082 Return<void> hResult =
1083 mPluginV1_1->getNumberOfSessions([&](Status status, uint32_t hOpen, uint32_t hMax) {
1084 if (status == Status::OK) {
1085 *open = hOpen;
1086 *max = hMax;
1087 }
1088 err = toStatusT(status);
1089 });
1090
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301091 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001092}
1093
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301094DrmStatus DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
1095 DrmPlugin::SecurityLevel* level) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001096 Mutex::Autolock autoLock(mLock);
1097 INIT_CHECK();
1098
1099 if (level == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301100 return DrmStatus(BAD_VALUE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001101 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301102 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001103
1104 if (mPluginV1_1 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301105 return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
Kyle Zhang6605add2022-01-13 17:51:23 +00001106 }
1107
1108 *level = DrmPlugin::kSecurityLevelUnknown;
1109
1110 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1111 [&](Status status, SecurityLevel hLevel) {
1112 if (status == Status::OK) {
1113 *level = toSecurityLevel(hLevel);
1114 }
1115 err = toStatusT(status);
1116 });
1117
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301118 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001119}
1120
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301121DrmStatus DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001122 Mutex::Autolock autoLock(mLock);
1123
1124 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301125 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001126 }
1127
1128 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301129 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001130 }
1131
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301132 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001133
1134 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1135 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1136 if (status == Status::OK) {
1137 keySetIds = toKeySetIds(hKeySetIds);
1138 }
1139 err = toStatusT(status);
1140 });
1141
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301142 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001143}
1144
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301145DrmStatus DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001146 Mutex::Autolock autoLock(mLock);
1147
1148 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301149 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001150 }
1151
1152 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301153 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001154 }
1155
1156 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301157 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001158}
1159
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301160DrmStatus DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
1161 DrmPlugin::OfflineLicenseState* licenseState) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001162 Mutex::Autolock autoLock(mLock);
1163
1164 if (mInitCheck != OK) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301165 return DrmStatus(mInitCheck);
Kyle Zhang6605add2022-01-13 17:51:23 +00001166 }
1167
1168 if (mPluginV1_2 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301169 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001170 }
1171 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1172
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301173 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001174
1175 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(
1176 toHidlVec(keySetId), [&](Status status, OfflineLicenseState hLicenseState) {
1177 if (status == Status::OK) {
1178 *licenseState = toOfflineLicenseState(hLicenseState);
1179 }
1180 err = toStatusT(status);
1181 });
1182
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301183 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001184}
1185
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301186DrmStatus DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001187 Mutex::Autolock autoLock(mLock);
1188 return getPropertyStringInternal(name, value);
1189}
1190
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301191DrmStatus DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001192 // This function is internal to the class and should only be called while
1193 // mLock is already held.
1194 INIT_CHECK();
1195
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301196 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001197
1198 Return<void> hResult = mPlugin->getPropertyString(
1199 toHidlString(name), [&](Status status, const hidl_string& hValue) {
1200 if (status == Status::OK) {
1201 value = toString8(hValue);
1202 }
1203 err = toStatusT(status);
1204 });
1205
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301206 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001207}
1208
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301209DrmStatus DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001210 Mutex::Autolock autoLock(mLock);
1211 return getPropertyByteArrayInternal(name, value);
1212}
1213
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301214DrmStatus DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
1215 Vector<uint8_t>& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001216 // This function is internal to the class and should only be called while
1217 // mLock is already held.
1218 INIT_CHECK();
1219
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301220 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001221
1222 Return<void> hResult = mPlugin->getPropertyByteArray(
1223 toHidlString(name), [&](Status status, const hidl_vec<uint8_t>& hValue) {
1224 if (status == Status::OK) {
1225 value = toVector(hValue);
1226 }
1227 err = toStatusT(status);
1228 });
1229
1230 err = hResult.isOk() ? err : DEAD_OBJECT;
1231 if (name == kPropertyDeviceUniqueId) {
1232 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1233 }
1234 return err;
1235}
1236
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301237DrmStatus DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001238 Mutex::Autolock autoLock(mLock);
1239 INIT_CHECK();
1240
1241 Return<Status> status = mPlugin->setPropertyString(toHidlString(name), toHidlString(value));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301242 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001243}
1244
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301245DrmStatus DrmHalHidl::setPropertyByteArray(String8 const& name,
1246 Vector<uint8_t> const& value) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001247 Mutex::Autolock autoLock(mLock);
1248 INIT_CHECK();
1249
1250 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), toHidlVec(value));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301251 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001252}
1253
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301254DrmStatus DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001255 if (consumer == nullptr) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301256 return DrmStatus(UNEXPECTED_NULL);
Kyle Zhang6605add2022-01-13 17:51:23 +00001257 }
1258 consumer->consumeFrameworkMetrics(mMetrics);
1259
1260 // Append vendor metrics if they are supported.
1261 if (mPluginV1_1 != NULL) {
1262 String8 vendor;
1263 String8 description;
Tomasz Wasilczykfd9ffd12023-08-14 17:56:22 +00001264 if (getPropertyStringInternal(String8("vendor"), vendor) != OK || vendor.empty()) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001265 ALOGE("Get vendor failed or is empty");
1266 vendor = "NONE";
1267 }
1268 if (getPropertyStringInternal(String8("description"), description) != OK ||
Tomasz Wasilczykfd9ffd12023-08-14 17:56:22 +00001269 description.empty()) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001270 ALOGE("Get description failed or is empty.");
1271 description = "NONE";
1272 }
1273 vendor += ".";
1274 vendor += description;
1275
1276 hidl_vec<DrmMetricGroup> pluginMetrics;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301277 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001278
1279 Return<void> status =
1280 mPluginV1_1->getMetrics([&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1281 if (status != Status::OK) {
1282 ALOGV("Error getting plugin metrics: %d", status);
1283 } else {
1284 consumer->consumeHidlMetrics(vendor, pluginMetrics);
1285 }
1286 err = toStatusT(status);
1287 });
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301288 return status.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001289 }
1290
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301291 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001292}
1293
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301294DrmStatus DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
1295 String8 const& algorithm) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001296 Mutex::Autolock autoLock(mLock);
1297 INIT_CHECK();
1298
1299 DrmSessionManager::Instance()->useSession(sessionId);
1300
1301 Return<Status> status =
1302 mPlugin->setCipherAlgorithm(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::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001307 Mutex::Autolock autoLock(mLock);
1308 INIT_CHECK();
1309
1310 DrmSessionManager::Instance()->useSession(sessionId);
1311
1312 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301313 return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001314}
1315
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301316DrmStatus DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1317 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1318 Vector<uint8_t>& output) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001319 Mutex::Autolock autoLock(mLock);
1320 INIT_CHECK();
1321
1322 DrmSessionManager::Instance()->useSession(sessionId);
1323
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301324 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001325
1326 Return<void> hResult =
1327 mPlugin->encrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1328 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1329 if (status == Status::OK) {
1330 output = toVector(hOutput);
1331 }
1332 err = toStatusT(status);
1333 });
1334
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301335 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001336}
1337
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301338DrmStatus DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1339 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1340 Vector<uint8_t>& output) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001341 Mutex::Autolock autoLock(mLock);
1342 INIT_CHECK();
1343
1344 DrmSessionManager::Instance()->useSession(sessionId);
1345
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301346 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001347
1348 Return<void> hResult =
1349 mPlugin->decrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1350 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1351 if (status == Status::OK) {
1352 output = toVector(hOutput);
1353 }
1354 err = toStatusT(status);
1355 });
1356
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301357 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001358}
1359
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301360DrmStatus DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1361 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001362 Mutex::Autolock autoLock(mLock);
1363 INIT_CHECK();
1364
1365 DrmSessionManager::Instance()->useSession(sessionId);
1366
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301367 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001368
1369 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1370 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1371 if (status == Status::OK) {
1372 signature = toVector(hSignature);
1373 }
1374 err = toStatusT(status);
1375 });
1376
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301377 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001378}
1379
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301380DrmStatus DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1381 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
1382 bool& match) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001383 Mutex::Autolock autoLock(mLock);
1384 INIT_CHECK();
1385
1386 DrmSessionManager::Instance()->useSession(sessionId);
1387
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301388 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001389
1390 Return<void> hResult =
1391 mPlugin->verify(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1392 toHidlVec(signature), [&](Status status, bool hMatch) {
1393 if (status == Status::OK) {
1394 match = hMatch;
1395 } else {
1396 match = false;
1397 }
1398 err = toStatusT(status);
1399 });
1400
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301401 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001402}
1403
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301404DrmStatus DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
1405 Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
1406 Vector<uint8_t>& signature) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001407 Mutex::Autolock autoLock(mLock);
1408 INIT_CHECK();
1409
1410 DrmSessionManager::Instance()->useSession(sessionId);
1411
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301412 DrmStatus err = UNKNOWN_ERROR;
Kyle Zhang6605add2022-01-13 17:51:23 +00001413
1414 Return<void> hResult = mPlugin->signRSA(
1415 toHidlVec(sessionId), toHidlString(algorithm), toHidlVec(message),
1416 toHidlVec(wrappedKey), [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1417 if (status == Status::OK) {
1418 signature = toVector(hSignature);
1419 }
1420 err = toStatusT(status);
1421 });
1422
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301423 return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001424}
1425
1426std::string DrmHalHidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
1427 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1428 mediametrics_setUid(item, mMetrics.GetAppUid());
1429 String8 vendor;
1430 String8 description;
1431 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1432 if (result != OK) {
1433 ALOGE("Failed to get vendor from drm plugin: %d", result);
1434 } else {
1435 mediametrics_setCString(item, "vendor", vendor.c_str());
1436 }
1437 result = getPropertyStringInternal(String8("description"), description);
1438 if (result != OK) {
1439 ALOGE("Failed to get description from drm plugin: %d", result);
1440 } else {
1441 mediametrics_setCString(item, "description", description.c_str());
1442 }
1443
1444 std::string serializedMetrics;
1445 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1446 if (result != OK) {
1447 ALOGE("Failed to serialize framework metrics: %d", result);
1448 }
1449 std::string b64EncodedMetrics =
1450 toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size());
1451 if (!b64EncodedMetrics.empty()) {
1452 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
1453 }
1454 if (!pluginMetrics.empty()) {
1455 mediametrics_setCString(item, "plugin_metrics", pluginMetrics.c_str());
1456 }
1457 if (!mediametrics_selfRecord(item)) {
1458 ALOGE("Failed to self record framework metrics");
1459 }
1460 mediametrics_delete(item);
1461 return serializedMetrics;
1462}
1463
1464std::string DrmHalHidl::reportPluginMetrics() const {
1465 Vector<uint8_t> metricsVector;
1466 String8 vendor;
1467 String8 description;
1468 std::string metricsString;
1469 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1470 getPropertyStringInternal(String8("description"), description) == OK &&
1471 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1472 metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
1473 status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
1474 mMetrics.GetAppUid());
1475 if (res != OK) {
1476 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1477 }
1478 }
1479 return metricsString;
1480}
1481
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301482DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001483 Mutex::Autolock autoLock(mLock);
1484 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301485 return DrmStatus(false);
Kyle Zhang6605add2022-01-13 17:51:23 +00001486 }
1487 auto hResult = mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1488 if (!hResult.isOk()) {
1489 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301490 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001491 }
1492 if (required) {
1493 *required = hResult;
1494 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301495 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001496}
1497
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301498DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime,
1499 DrmPlugin::SecurityLevel securityLevel,
1500 bool* required) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001501 Mutex::Autolock autoLock(mLock);
1502 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301503 return DrmStatus(false);
Kyle Zhang6605add2022-01-13 17:51:23 +00001504 }
1505 auto hLevel = toHidlSecurityLevel(securityLevel);
1506 auto hResult = mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1507 if (!hResult.isOk()) {
1508 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301509 return DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001510 }
1511 if (required) {
1512 *required = hResult;
1513 }
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301514 return DrmStatus(OK);
Kyle Zhang6605add2022-01-13 17:51:23 +00001515}
1516
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301517DrmStatus DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
Kyle Zhang6605add2022-01-13 17:51:23 +00001518 Mutex::Autolock autoLock(mLock);
1519 if (mPluginV1_4 == NULL) {
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301520 return DrmStatus(ERROR_UNSUPPORTED);
Kyle Zhang6605add2022-01-13 17:51:23 +00001521 }
1522 auto err = mPluginV1_4->setPlaybackId(toHidlVec(sessionId), hidl_string(playbackId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301523 return err.isOk() ? DrmStatus(toStatusT(err)) : DrmStatus(DEAD_OBJECT);
Kyle Zhang6605add2022-01-13 17:51:23 +00001524}
1525
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301526DrmStatus DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
Kyle Zhang6605add2022-01-13 17:51:23 +00001527 Mutex::Autolock autoLock(mLock);
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301528 return DrmStatus(DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs));
Kyle Zhang6605add2022-01-13 17:51:23 +00001529}
1530
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301531DrmStatus DrmHalHidl::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
Kyle Zhang2567a5e2022-03-17 23:36:26 +00001532 Mutex::Autolock autoLock(mLock);
1533 for (auto &factory : mFactories) {
1534 sp<drm::V1_3::IDrmFactory> factoryV1_3 = drm::V1_3::IDrmFactory::castFrom(factory);
1535 if (factoryV1_3 == nullptr) {
1536 continue;
1537 }
1538
1539 factoryV1_3->getSupportedCryptoSchemes(
1540 [&](const hardware::hidl_vec<hardware::hidl_array<uint8_t, 16>>& schemes_hidl) {
1541 for (const auto &scheme : schemes_hidl) {
1542 schemes.insert(schemes.end(), scheme.data(), scheme.data() + scheme.size());
1543 }
1544 });
1545 }
1546
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +05301547 return DrmStatus(OK);
Kyle Zhang2567a5e2022-03-17 23:36:26 +00001548}
1549
Kyle Zhang6605add2022-01-13 17:51:23 +00001550} // namespace android