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