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