1 /*
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/hardware/drm/1.3/IDrmFactory.h>
24 #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
45 using ::android::sp;
46 using ::android::DrmUtils::toStatusT;
47 using ::android::hardware::hidl_array;
48 using ::android::hardware::hidl_string;
49 using ::android::hardware::hidl_vec;
50 using ::android::hardware::Return;
51 using ::android::hardware::Void;
52 using ::android::hardware::drm::V1_1::DrmMetricGroup;
53 using ::android::os::PersistableBundle;
54 using drm::V1_0::KeyedVector;
55 using drm::V1_0::KeyRequestType;
56 using drm::V1_0::KeyType;
57 using drm::V1_0::KeyValue;
58 using drm::V1_0::SecureStop;
59 using drm::V1_0::SecureStopId;
60 using drm::V1_0::Status;
61 using drm::V1_1::HdcpLevel;
62 using drm::V1_1::SecureStopRelease;
63 using drm::V1_1::SecurityLevel;
64 using drm::V1_2::KeySetId;
65 using drm::V1_2::KeyStatusType;
66
67 typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
68 typedef drm::V1_2::Status Status_V1_2;
69 typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
70
71 namespace {
72
73 // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
74 // in the MediaDrm API.
75 constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
76 constexpr char kEqualsSign[] = "=";
77
78 template <typename T>
toBase64StringNoPad(const T * data,size_t size)79 std::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
99 namespace android {
100
101 #define INIT_CHECK() \
102 { \
103 if (mInitCheck != OK) return mInitCheck; \
104 }
105
toVector(const hidl_vec<uint8_t> & vec)106 static 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
toHidlVec(const Vector<uint8_t> & vector)112 static 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
toString8(const hidl_string & string)118 static String8 toString8(const hidl_string& string) {
119 return String8(string.c_str());
120 }
121
toHidlString(const String8 & string)122 static hidl_string toHidlString(const String8& string) {
123 return hidl_string(string.string());
124 }
125
toSecurityLevel(SecurityLevel level)126 static 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
toHidlSecurityLevel(DrmPlugin::SecurityLevel level)143 static 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
toOfflineLicenseState(OfflineLicenseState licenseState)160 static 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
toHdcpLevel(HdcpLevel_V1_2 level)171 static 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 }
toHidlKeyedVector(const KeyedVector<String8,String8> & keyedVector)191 static ::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
toKeyedVector(const::KeyedVector & hKeyedVector)202 static 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
toSecureStops(const hidl_vec<SecureStop> & hSecureStops)210 static 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
toSecureStopIds(const hidl_vec<SecureStopId> & hSecureStopIds)218 static 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
toKeySetIds(const hidl_vec<KeySetId> & hKeySetIds)226 static 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
234 Mutex DrmHalHidl::mLock;
235
236 struct DrmHalHidl::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
DrmSessionClientandroid::DrmHalHidl::DrmSessionClient237 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
reclaimResource(bool * _aidl_return)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
getName(::std::string * _aidl_return)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
~DrmSessionClient()287 DrmHalHidl::DrmSessionClient::~DrmSessionClient() {
288 DrmSessionManager::Instance()->removeSession(mSessionId);
289 }
290
DrmHalHidl()291 DrmHalHidl::DrmHalHidl()
292 : mFactories(makeDrmFactories()),
293 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}
294
closeOpenSessions()295 void 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
~DrmHalHidl()306 DrmHalHidl::~DrmHalHidl() {}
307
cleanup()308 void DrmHalHidl::cleanup() {
309 closeOpenSessions();
310
311 Mutex::Autolock autoLock(mLock);
312 reportFrameworkMetrics(reportPluginMetrics());
313
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
makeDrmFactories()331 std::vector<sp<IDrmFactory>> DrmHalHidl::makeDrmFactories() {
332 static std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
333 if (factories.size() == 0) {
334 DrmUtils::LOG2BI("No hidl drm factories found");
335 // could be in passthrough mode, load the default passthrough service
336 auto passthrough = IDrmFactory::getService();
337 if (passthrough != NULL) {
338 DrmUtils::LOG2BI("makeDrmFactories: using default passthrough drm instance");
339 factories.push_back(passthrough);
340 } else {
341 DrmUtils::LOG2BE("Failed to find passthrough drm factories");
342 }
343 }
344 return factories;
345 }
346
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)347 sp<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
initCheck() const371 status_t DrmHalHidl::initCheck() const {
372 return mInitCheck;
373 }
374
setListener(const sp<IDrmClient> & listener)375 status_t DrmHalHidl::setListener(const sp<IDrmClient>& listener) {
376 Mutex::Autolock lock(mEventLock);
377 mListener = listener;
378 return NO_ERROR;
379 }
380
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)381 Return<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
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)416 Return<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
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus_V1_0> & keyStatusList_V1_0,bool hasNewUsableKey)429 Return<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
sendKeysChange_1_2(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & hKeyStatusList,bool hasNewUsableKey)441 Return<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
sendSessionLostState(const hidl_vec<uint8_t> & sessionId)493 Return<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
matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)505 status_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 return OK;
517 }
518 // isCryptoSchemeSupported(uuid, mimeType)
519 auto hResult = factory->isContentTypeSupported(mimeType.string());
520 if (!hResult.isOk()) {
521 return DEAD_OBJECT;
522 }
523 *isSupported = hResult;
524 return OK;
525 } else if (mimeType == "") {
526 return BAD_VALUE;
527 }
528
529 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
530 if (factoryV1_2 == NULL) {
531 return ERROR_UNSUPPORTED;
532 } else {
533 auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
534 toHidlSecurityLevel(level));
535 if (!hResult.isOk()) {
536 return DEAD_OBJECT;
537 }
538 *isSupported = hResult;
539 return OK;
540 }
541 }
542
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)543 status_t DrmHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
544 DrmPlugin::SecurityLevel level, bool* isSupported) {
545 Mutex::Autolock autoLock(mLock);
546 *isSupported = false;
547 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
548 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
549 if (hResult.isOk() && hResult) {
550 return matchMimeTypeAndSecurityLevel(mFactories[i], uuid, mimeType, level, isSupported);
551 }
552 }
553 return OK;
554 }
555
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)556 status_t DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
557 Mutex::Autolock autoLock(mLock);
558
559 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
560 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
561 if (hResult.isOk() && hResult) {
562 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
563 if (plugin != NULL) {
564 mPlugin = plugin;
565 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
566 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
567 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
568 break;
569 }
570 }
571 }
572
573 if (mPlugin == NULL) {
574 DrmUtils::LOG2BE(uuid, "No supported hal instance found");
575 mInitCheck = ERROR_UNSUPPORTED;
576 } else {
577 mInitCheck = OK;
578 if (mPluginV1_2 != NULL) {
579 if (!mPluginV1_2->setListener(this).isOk()) {
580 mInitCheck = DEAD_OBJECT;
581 }
582 } else if (!mPlugin->setListener(this).isOk()) {
583 mInitCheck = DEAD_OBJECT;
584 }
585 if (mInitCheck != OK) {
586 mPlugin.clear();
587 mPluginV1_1.clear();
588 mPluginV1_2.clear();
589 mPluginV1_4.clear();
590 }
591 }
592
593 return mInitCheck;
594 }
595
destroyPlugin()596 status_t DrmHalHidl::destroyPlugin() {
597 cleanup();
598 return OK;
599 }
600
openSession(DrmPlugin::SecurityLevel level,Vector<uint8_t> & sessionId)601 status_t DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
602 Mutex::Autolock autoLock(mLock);
603 INIT_CHECK();
604
605 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
606 bool setSecurityLevel = true;
607
608 if (level == DrmPlugin::kSecurityLevelMax) {
609 setSecurityLevel = false;
610 } else {
611 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
612 return ERROR_DRM_CANNOT_HANDLE;
613 }
614 }
615
616 status_t err = UNKNOWN_ERROR;
617 bool retry = true;
618 do {
619 hidl_vec<uint8_t> hSessionId;
620
621 Return<void> hResult;
622 if (mPluginV1_1 == NULL || !setSecurityLevel) {
623 hResult = mPlugin->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
624 if (status == Status::OK) {
625 sessionId = toVector(id);
626 }
627 err = toStatusT(status);
628 });
629 } else {
630 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
631 [&](Status status, const hidl_vec<uint8_t>& id) {
632 if (status == Status::OK) {
633 sessionId = toVector(id);
634 }
635 err = toStatusT(status);
636 });
637 }
638
639 if (!hResult.isOk()) {
640 err = DEAD_OBJECT;
641 }
642
643 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
644 mLock.unlock();
645 // reclaimSession may call back to closeSession, since mLock is
646 // shared between Drm instances, we should unlock here to avoid
647 // deadlock.
648 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
649 mLock.lock();
650 } else {
651 retry = false;
652 }
653 } while (retry);
654
655 if (err == OK) {
656 std::shared_ptr<DrmSessionClient> client =
657 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
658 DrmSessionManager::Instance()->addSession(
659 AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
660 sessionId);
661 mOpenSessions.push_back(client);
662 mMetrics.SetSessionStart(sessionId);
663 }
664
665 mMetrics.mOpenSessionCounter.Increment(err);
666 return err;
667 }
668
closeSession(Vector<uint8_t> const & sessionId)669 status_t DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
670 Mutex::Autolock autoLock(mLock);
671 INIT_CHECK();
672
673 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
674 if (status.isOk()) {
675 if (status == Status::OK) {
676 DrmSessionManager::Instance()->removeSession(sessionId);
677 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
678 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
679 mOpenSessions.erase(i);
680 break;
681 }
682 }
683 }
684 status_t response = toStatusT(status);
685 mMetrics.SetSessionEnd(sessionId);
686 mMetrics.mCloseSessionCounter.Increment(response);
687 return response;
688 }
689 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
690 return DEAD_OBJECT;
691 }
692
toKeyRequestType(KeyRequestType keyRequestType)693 static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
694 switch (keyRequestType) {
695 case KeyRequestType::INITIAL:
696 return DrmPlugin::kKeyRequestType_Initial;
697 break;
698 case KeyRequestType::RENEWAL:
699 return DrmPlugin::kKeyRequestType_Renewal;
700 break;
701 case KeyRequestType::RELEASE:
702 return DrmPlugin::kKeyRequestType_Release;
703 break;
704 default:
705 return DrmPlugin::kKeyRequestType_Unknown;
706 break;
707 }
708 }
709
toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType)710 static DrmPlugin::KeyRequestType toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType) {
711 switch (keyRequestType) {
712 case KeyRequestType_V1_1::NONE:
713 return DrmPlugin::kKeyRequestType_None;
714 break;
715 case KeyRequestType_V1_1::UPDATE:
716 return DrmPlugin::kKeyRequestType_Update;
717 break;
718 default:
719 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
720 break;
721 }
722 }
723
getKeyRequest(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & initData,String8 const & mimeType,DrmPlugin::KeyType keyType,KeyedVector<String8,String8> const & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl,DrmPlugin::KeyRequestType * keyRequestType)724 status_t DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
725 Vector<uint8_t> const& initData, String8 const& mimeType,
726 DrmPlugin::KeyType keyType,
727 KeyedVector<String8, String8> const& optionalParameters,
728 Vector<uint8_t>& request, String8& defaultUrl,
729 DrmPlugin::KeyRequestType* keyRequestType) {
730 Mutex::Autolock autoLock(mLock);
731 INIT_CHECK();
732 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
733
734 DrmSessionManager::Instance()->useSession(sessionId);
735
736 KeyType hKeyType;
737 if (keyType == DrmPlugin::kKeyType_Streaming) {
738 hKeyType = KeyType::STREAMING;
739 } else if (keyType == DrmPlugin::kKeyType_Offline) {
740 hKeyType = KeyType::OFFLINE;
741 } else if (keyType == DrmPlugin::kKeyType_Release) {
742 hKeyType = KeyType::RELEASE;
743 } else {
744 keyRequestTimer.SetAttribute(BAD_VALUE);
745 return BAD_VALUE;
746 }
747
748 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
749
750 status_t err = UNKNOWN_ERROR;
751 Return<void> hResult;
752
753 if (mPluginV1_2 != NULL) {
754 hResult = mPluginV1_2->getKeyRequest_1_2(
755 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
756 hOptionalParameters,
757 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
758 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
759 if (status == Status_V1_2::OK) {
760 request = toVector(hRequest);
761 defaultUrl = toString8(hDefaultUrl);
762 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
763 }
764 err = toStatusT(status);
765 });
766 } else if (mPluginV1_1 != NULL) {
767 hResult = mPluginV1_1->getKeyRequest_1_1(
768 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
769 hOptionalParameters,
770 [&](Status status, const hidl_vec<uint8_t>& hRequest,
771 KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
772 if (status == Status::OK) {
773 request = toVector(hRequest);
774 defaultUrl = toString8(hDefaultUrl);
775 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
776 }
777 err = toStatusT(status);
778 });
779 } else {
780 hResult = mPlugin->getKeyRequest(
781 toHidlVec(sessionId), toHidlVec(initData), toHidlString(mimeType), hKeyType,
782 hOptionalParameters,
783 [&](Status status, const hidl_vec<uint8_t>& hRequest,
784 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
785 if (status == Status::OK) {
786 request = toVector(hRequest);
787 defaultUrl = toString8(hDefaultUrl);
788 *keyRequestType = toKeyRequestType(hKeyRequestType);
789 }
790 err = toStatusT(status);
791 });
792 }
793
794 err = hResult.isOk() ? err : DEAD_OBJECT;
795 keyRequestTimer.SetAttribute(err);
796 return err;
797 }
798
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)799 status_t DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
800 Vector<uint8_t> const& response,
801 Vector<uint8_t>& keySetId) {
802 Mutex::Autolock autoLock(mLock);
803 INIT_CHECK();
804 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
805
806 DrmSessionManager::Instance()->useSession(sessionId);
807
808 status_t err = UNKNOWN_ERROR;
809
810 Return<void> hResult =
811 mPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
812 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
813 if (status == Status::OK) {
814 keySetId = toVector(hKeySetId);
815 }
816 err = toStatusT(status);
817 });
818 err = hResult.isOk() ? err : DEAD_OBJECT;
819 keyResponseTimer.SetAttribute(err);
820 return err;
821 }
822
removeKeys(Vector<uint8_t> const & keySetId)823 status_t DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
824 Mutex::Autolock autoLock(mLock);
825 INIT_CHECK();
826
827 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
828 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
829 }
830
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)831 status_t DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
832 Vector<uint8_t> const& keySetId) {
833 Mutex::Autolock autoLock(mLock);
834 INIT_CHECK();
835
836 DrmSessionManager::Instance()->useSession(sessionId);
837
838 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
839 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
840 }
841
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const842 status_t DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
843 KeyedVector<String8, String8>& infoMap) const {
844 Mutex::Autolock autoLock(mLock);
845 INIT_CHECK();
846
847 DrmSessionManager::Instance()->useSession(sessionId);
848
849 ::KeyedVector hInfoMap;
850
851 status_t err = UNKNOWN_ERROR;
852
853 Return<void> hResult = mPlugin->queryKeyStatus(
854 toHidlVec(sessionId), [&](Status status, const hidl_vec<KeyValue>& map) {
855 if (status == Status::OK) {
856 infoMap = toKeyedVector(map);
857 }
858 err = toStatusT(status);
859 });
860
861 return hResult.isOk() ? err : DEAD_OBJECT;
862 }
863
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)864 status_t DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
865 Vector<uint8_t>& request, String8& defaultUrl) {
866 Mutex::Autolock autoLock(mLock);
867 INIT_CHECK();
868
869 status_t err = UNKNOWN_ERROR;
870 Return<void> hResult;
871
872 if (mPluginV1_2 != NULL) {
873 hResult = mPluginV1_2->getProvisionRequest_1_2(
874 toHidlString(certType), toHidlString(certAuthority),
875 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
876 const hidl_string& hDefaultUrl) {
877 if (status == Status_V1_2::OK) {
878 request = toVector(hRequest);
879 defaultUrl = toString8(hDefaultUrl);
880 }
881 err = toStatusT(status);
882 });
883 } else {
884 hResult = mPlugin->getProvisionRequest(toHidlString(certType), toHidlString(certAuthority),
885 [&](Status status, const hidl_vec<uint8_t>& hRequest,
886 const hidl_string& hDefaultUrl) {
887 if (status == Status::OK) {
888 request = toVector(hRequest);
889 defaultUrl = toString8(hDefaultUrl);
890 }
891 err = toStatusT(status);
892 });
893 }
894
895 err = hResult.isOk() ? err : DEAD_OBJECT;
896 mMetrics.mGetProvisionRequestCounter.Increment(err);
897 return err;
898 }
899
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)900 status_t DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
901 Vector<uint8_t>& certificate,
902 Vector<uint8_t>& wrappedKey) {
903 Mutex::Autolock autoLock(mLock);
904 INIT_CHECK();
905
906 status_t err = UNKNOWN_ERROR;
907
908 Return<void> hResult = mPlugin->provideProvisionResponse(
909 toHidlVec(response), [&](Status status, const hidl_vec<uint8_t>& hCertificate,
910 const hidl_vec<uint8_t>& hWrappedKey) {
911 if (status == Status::OK) {
912 certificate = toVector(hCertificate);
913 wrappedKey = toVector(hWrappedKey);
914 }
915 err = toStatusT(status);
916 });
917
918 err = hResult.isOk() ? err : DEAD_OBJECT;
919 mMetrics.mProvideProvisionResponseCounter.Increment(err);
920 return err;
921 }
922
getSecureStops(List<Vector<uint8_t>> & secureStops)923 status_t DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
924 Mutex::Autolock autoLock(mLock);
925 INIT_CHECK();
926
927 status_t err = UNKNOWN_ERROR;
928
929 Return<void> hResult =
930 mPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
931 if (status == Status::OK) {
932 secureStops = toSecureStops(hSecureStops);
933 }
934 err = toStatusT(status);
935 });
936
937 return hResult.isOk() ? err : DEAD_OBJECT;
938 }
939
getSecureStopIds(List<Vector<uint8_t>> & secureStopIds)940 status_t DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
941 Mutex::Autolock autoLock(mLock);
942
943 if (mInitCheck != OK) {
944 return mInitCheck;
945 }
946
947 if (mPluginV1_1 == NULL) {
948 return ERROR_DRM_CANNOT_HANDLE;
949 }
950
951 status_t err = UNKNOWN_ERROR;
952
953 Return<void> hResult = mPluginV1_1->getSecureStopIds(
954 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
955 if (status == Status::OK) {
956 secureStopIds = toSecureStopIds(hSecureStopIds);
957 }
958 err = toStatusT(status);
959 });
960
961 return hResult.isOk() ? err : DEAD_OBJECT;
962 }
963
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)964 status_t DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
965 Mutex::Autolock autoLock(mLock);
966 INIT_CHECK();
967
968 status_t err = UNKNOWN_ERROR;
969
970 Return<void> hResult = mPlugin->getSecureStop(
971 toHidlVec(ssid), [&](Status status, const SecureStop& hSecureStop) {
972 if (status == Status::OK) {
973 secureStop = toVector(hSecureStop.opaqueData);
974 }
975 err = toStatusT(status);
976 });
977
978 return hResult.isOk() ? err : DEAD_OBJECT;
979 }
980
releaseSecureStops(Vector<uint8_t> const & ssRelease)981 status_t DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
982 Mutex::Autolock autoLock(mLock);
983 INIT_CHECK();
984
985 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
986 if (mPluginV1_1 != NULL) {
987 SecureStopRelease secureStopRelease;
988 secureStopRelease.opaqueData = toHidlVec(ssRelease);
989 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
990 } else {
991 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
992 }
993 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
994 }
995
removeSecureStop(Vector<uint8_t> const & ssid)996 status_t DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
997 Mutex::Autolock autoLock(mLock);
998
999 if (mInitCheck != OK) {
1000 return mInitCheck;
1001 }
1002
1003 if (mPluginV1_1 == NULL) {
1004 return ERROR_DRM_CANNOT_HANDLE;
1005 }
1006
1007 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1008 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1009 }
1010
removeAllSecureStops()1011 status_t DrmHalHidl::removeAllSecureStops() {
1012 Mutex::Autolock autoLock(mLock);
1013 INIT_CHECK();
1014
1015 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1016 if (mPluginV1_1 != NULL) {
1017 status = mPluginV1_1->removeAllSecureStops();
1018 } else {
1019 status = mPlugin->releaseAllSecureStops();
1020 }
1021 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1022 }
1023
getHdcpLevels(DrmPlugin::HdcpLevel * connected,DrmPlugin::HdcpLevel * max) const1024 status_t DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
1025 DrmPlugin::HdcpLevel* max) const {
1026 Mutex::Autolock autoLock(mLock);
1027 INIT_CHECK();
1028
1029 if (connected == NULL || max == NULL) {
1030 return BAD_VALUE;
1031 }
1032 status_t err = UNKNOWN_ERROR;
1033
1034 *connected = DrmPlugin::kHdcpLevelUnknown;
1035 *max = DrmPlugin::kHdcpLevelUnknown;
1036
1037 Return<void> hResult;
1038 if (mPluginV1_2 != NULL) {
1039 hResult = mPluginV1_2->getHdcpLevels_1_2([&](Status_V1_2 status,
1040 const HdcpLevel_V1_2& hConnected,
1041 const HdcpLevel_V1_2& hMax) {
1042 if (status == Status_V1_2::OK) {
1043 *connected = toHdcpLevel(hConnected);
1044 *max = toHdcpLevel(hMax);
1045 }
1046 err = toStatusT(status);
1047 });
1048 } else if (mPluginV1_1 != NULL) {
1049 hResult = mPluginV1_1->getHdcpLevels(
1050 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1051 if (status == Status::OK) {
1052 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1053 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1054 }
1055 err = toStatusT(status);
1056 });
1057 } else {
1058 return ERROR_DRM_CANNOT_HANDLE;
1059 }
1060
1061 return hResult.isOk() ? err : DEAD_OBJECT;
1062 }
1063
getNumberOfSessions(uint32_t * open,uint32_t * max) const1064 status_t DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
1065 Mutex::Autolock autoLock(mLock);
1066 INIT_CHECK();
1067
1068 if (open == NULL || max == NULL) {
1069 return BAD_VALUE;
1070 }
1071 status_t err = UNKNOWN_ERROR;
1072
1073 *open = 0;
1074 *max = 0;
1075
1076 if (mPluginV1_1 == NULL) {
1077 return ERROR_DRM_CANNOT_HANDLE;
1078 }
1079
1080 Return<void> hResult =
1081 mPluginV1_1->getNumberOfSessions([&](Status status, uint32_t hOpen, uint32_t hMax) {
1082 if (status == Status::OK) {
1083 *open = hOpen;
1084 *max = hMax;
1085 }
1086 err = toStatusT(status);
1087 });
1088
1089 return hResult.isOk() ? err : DEAD_OBJECT;
1090 }
1091
getSecurityLevel(Vector<uint8_t> const & sessionId,DrmPlugin::SecurityLevel * level) const1092 status_t DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
1093 DrmPlugin::SecurityLevel* level) const {
1094 Mutex::Autolock autoLock(mLock);
1095 INIT_CHECK();
1096
1097 if (level == NULL) {
1098 return BAD_VALUE;
1099 }
1100 status_t err = UNKNOWN_ERROR;
1101
1102 if (mPluginV1_1 == NULL) {
1103 return ERROR_DRM_CANNOT_HANDLE;
1104 }
1105
1106 *level = DrmPlugin::kSecurityLevelUnknown;
1107
1108 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1109 [&](Status status, SecurityLevel hLevel) {
1110 if (status == Status::OK) {
1111 *level = toSecurityLevel(hLevel);
1112 }
1113 err = toStatusT(status);
1114 });
1115
1116 return hResult.isOk() ? err : DEAD_OBJECT;
1117 }
1118
getOfflineLicenseKeySetIds(List<Vector<uint8_t>> & keySetIds) const1119 status_t DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
1120 Mutex::Autolock autoLock(mLock);
1121
1122 if (mInitCheck != OK) {
1123 return mInitCheck;
1124 }
1125
1126 if (mPluginV1_2 == NULL) {
1127 return ERROR_UNSUPPORTED;
1128 }
1129
1130 status_t err = UNKNOWN_ERROR;
1131
1132 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1133 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1134 if (status == Status::OK) {
1135 keySetIds = toKeySetIds(hKeySetIds);
1136 }
1137 err = toStatusT(status);
1138 });
1139
1140 return hResult.isOk() ? err : DEAD_OBJECT;
1141 }
1142
removeOfflineLicense(Vector<uint8_t> const & keySetId)1143 status_t DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
1144 Mutex::Autolock autoLock(mLock);
1145
1146 if (mInitCheck != OK) {
1147 return mInitCheck;
1148 }
1149
1150 if (mPluginV1_2 == NULL) {
1151 return ERROR_UNSUPPORTED;
1152 }
1153
1154 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1155 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1156 }
1157
getOfflineLicenseState(Vector<uint8_t> const & keySetId,DrmPlugin::OfflineLicenseState * licenseState) const1158 status_t DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
1159 DrmPlugin::OfflineLicenseState* licenseState) const {
1160 Mutex::Autolock autoLock(mLock);
1161
1162 if (mInitCheck != OK) {
1163 return mInitCheck;
1164 }
1165
1166 if (mPluginV1_2 == NULL) {
1167 return ERROR_UNSUPPORTED;
1168 }
1169 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1170
1171 status_t err = UNKNOWN_ERROR;
1172
1173 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(
1174 toHidlVec(keySetId), [&](Status status, OfflineLicenseState hLicenseState) {
1175 if (status == Status::OK) {
1176 *licenseState = toOfflineLicenseState(hLicenseState);
1177 }
1178 err = toStatusT(status);
1179 });
1180
1181 return hResult.isOk() ? err : DEAD_OBJECT;
1182 }
1183
getPropertyString(String8 const & name,String8 & value) const1184 status_t DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
1185 Mutex::Autolock autoLock(mLock);
1186 return getPropertyStringInternal(name, value);
1187 }
1188
getPropertyStringInternal(String8 const & name,String8 & value) const1189 status_t DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
1190 // This function is internal to the class and should only be called while
1191 // mLock is already held.
1192 INIT_CHECK();
1193
1194 status_t err = UNKNOWN_ERROR;
1195
1196 Return<void> hResult = mPlugin->getPropertyString(
1197 toHidlString(name), [&](Status status, const hidl_string& hValue) {
1198 if (status == Status::OK) {
1199 value = toString8(hValue);
1200 }
1201 err = toStatusT(status);
1202 });
1203
1204 return hResult.isOk() ? err : DEAD_OBJECT;
1205 }
1206
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const1207 status_t DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
1208 Mutex::Autolock autoLock(mLock);
1209 return getPropertyByteArrayInternal(name, value);
1210 }
1211
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const1212 status_t DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
1213 Vector<uint8_t>& value) const {
1214 // This function is internal to the class and should only be called while
1215 // mLock is already held.
1216 INIT_CHECK();
1217
1218 status_t err = UNKNOWN_ERROR;
1219
1220 Return<void> hResult = mPlugin->getPropertyByteArray(
1221 toHidlString(name), [&](Status status, const hidl_vec<uint8_t>& hValue) {
1222 if (status == Status::OK) {
1223 value = toVector(hValue);
1224 }
1225 err = toStatusT(status);
1226 });
1227
1228 err = hResult.isOk() ? err : DEAD_OBJECT;
1229 if (name == kPropertyDeviceUniqueId) {
1230 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1231 }
1232 return err;
1233 }
1234
setPropertyString(String8 const & name,String8 const & value) const1235 status_t DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
1236 Mutex::Autolock autoLock(mLock);
1237 INIT_CHECK();
1238
1239 Return<Status> status = mPlugin->setPropertyString(toHidlString(name), toHidlString(value));
1240 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1241 }
1242
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const1243 status_t DrmHalHidl::setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const {
1244 Mutex::Autolock autoLock(mLock);
1245 INIT_CHECK();
1246
1247 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), toHidlVec(value));
1248 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1249 }
1250
getMetrics(const sp<IDrmMetricsConsumer> & consumer)1251 status_t DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
1252 if (consumer == nullptr) {
1253 return UNEXPECTED_NULL;
1254 }
1255 consumer->consumeFrameworkMetrics(mMetrics);
1256
1257 // Append vendor metrics if they are supported.
1258 if (mPluginV1_1 != NULL) {
1259 String8 vendor;
1260 String8 description;
1261 if (getPropertyStringInternal(String8("vendor"), vendor) != OK || vendor.isEmpty()) {
1262 ALOGE("Get vendor failed or is empty");
1263 vendor = "NONE";
1264 }
1265 if (getPropertyStringInternal(String8("description"), description) != OK ||
1266 description.isEmpty()) {
1267 ALOGE("Get description failed or is empty.");
1268 description = "NONE";
1269 }
1270 vendor += ".";
1271 vendor += description;
1272
1273 hidl_vec<DrmMetricGroup> pluginMetrics;
1274 status_t err = UNKNOWN_ERROR;
1275
1276 Return<void> status =
1277 mPluginV1_1->getMetrics([&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1278 if (status != Status::OK) {
1279 ALOGV("Error getting plugin metrics: %d", status);
1280 } else {
1281 consumer->consumeHidlMetrics(vendor, pluginMetrics);
1282 }
1283 err = toStatusT(status);
1284 });
1285 return status.isOk() ? err : DEAD_OBJECT;
1286 }
1287
1288 return OK;
1289 }
1290
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1291 status_t DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
1292 String8 const& algorithm) {
1293 Mutex::Autolock autoLock(mLock);
1294 INIT_CHECK();
1295
1296 DrmSessionManager::Instance()->useSession(sessionId);
1297
1298 Return<Status> status =
1299 mPlugin->setCipherAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
1300 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1301 }
1302
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1303 status_t DrmHalHidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
1304 Mutex::Autolock autoLock(mLock);
1305 INIT_CHECK();
1306
1307 DrmSessionManager::Instance()->useSession(sessionId);
1308
1309 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
1310 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1311 }
1312
encrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)1313 status_t DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1314 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1315 Vector<uint8_t>& output) {
1316 Mutex::Autolock autoLock(mLock);
1317 INIT_CHECK();
1318
1319 DrmSessionManager::Instance()->useSession(sessionId);
1320
1321 status_t err = UNKNOWN_ERROR;
1322
1323 Return<void> hResult =
1324 mPlugin->encrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1325 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1326 if (status == Status::OK) {
1327 output = toVector(hOutput);
1328 }
1329 err = toStatusT(status);
1330 });
1331
1332 return hResult.isOk() ? err : DEAD_OBJECT;
1333 }
1334
decrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)1335 status_t DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1336 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1337 Vector<uint8_t>& output) {
1338 Mutex::Autolock autoLock(mLock);
1339 INIT_CHECK();
1340
1341 DrmSessionManager::Instance()->useSession(sessionId);
1342
1343 status_t err = UNKNOWN_ERROR;
1344
1345 Return<void> hResult =
1346 mPlugin->decrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
1347 toHidlVec(iv), [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1348 if (status == Status::OK) {
1349 output = toVector(hOutput);
1350 }
1351 err = toStatusT(status);
1352 });
1353
1354 return hResult.isOk() ? err : DEAD_OBJECT;
1355 }
1356
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)1357 status_t DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1358 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
1359 Mutex::Autolock autoLock(mLock);
1360 INIT_CHECK();
1361
1362 DrmSessionManager::Instance()->useSession(sessionId);
1363
1364 status_t err = UNKNOWN_ERROR;
1365
1366 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1367 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1368 if (status == Status::OK) {
1369 signature = toVector(hSignature);
1370 }
1371 err = toStatusT(status);
1372 });
1373
1374 return hResult.isOk() ? err : DEAD_OBJECT;
1375 }
1376
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)1377 status_t DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1378 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
1379 bool& match) {
1380 Mutex::Autolock autoLock(mLock);
1381 INIT_CHECK();
1382
1383 DrmSessionManager::Instance()->useSession(sessionId);
1384
1385 status_t err = UNKNOWN_ERROR;
1386
1387 Return<void> hResult =
1388 mPlugin->verify(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
1389 toHidlVec(signature), [&](Status status, bool hMatch) {
1390 if (status == Status::OK) {
1391 match = hMatch;
1392 } else {
1393 match = false;
1394 }
1395 err = toStatusT(status);
1396 });
1397
1398 return hResult.isOk() ? err : DEAD_OBJECT;
1399 }
1400
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)1401 status_t DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
1402 Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
1403 Vector<uint8_t>& signature) {
1404 Mutex::Autolock autoLock(mLock);
1405 INIT_CHECK();
1406
1407 DrmSessionManager::Instance()->useSession(sessionId);
1408
1409 status_t err = UNKNOWN_ERROR;
1410
1411 Return<void> hResult = mPlugin->signRSA(
1412 toHidlVec(sessionId), toHidlString(algorithm), toHidlVec(message),
1413 toHidlVec(wrappedKey), [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1414 if (status == Status::OK) {
1415 signature = toVector(hSignature);
1416 }
1417 err = toStatusT(status);
1418 });
1419
1420 return hResult.isOk() ? err : DEAD_OBJECT;
1421 }
1422
reportFrameworkMetrics(const std::string & pluginMetrics) const1423 std::string DrmHalHidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
1424 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1425 mediametrics_setUid(item, mMetrics.GetAppUid());
1426 String8 vendor;
1427 String8 description;
1428 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1429 if (result != OK) {
1430 ALOGE("Failed to get vendor from drm plugin: %d", result);
1431 } else {
1432 mediametrics_setCString(item, "vendor", vendor.c_str());
1433 }
1434 result = getPropertyStringInternal(String8("description"), description);
1435 if (result != OK) {
1436 ALOGE("Failed to get description from drm plugin: %d", result);
1437 } else {
1438 mediametrics_setCString(item, "description", description.c_str());
1439 }
1440
1441 std::string serializedMetrics;
1442 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1443 if (result != OK) {
1444 ALOGE("Failed to serialize framework metrics: %d", result);
1445 }
1446 std::string b64EncodedMetrics =
1447 toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size());
1448 if (!b64EncodedMetrics.empty()) {
1449 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
1450 }
1451 if (!pluginMetrics.empty()) {
1452 mediametrics_setCString(item, "plugin_metrics", pluginMetrics.c_str());
1453 }
1454 if (!mediametrics_selfRecord(item)) {
1455 ALOGE("Failed to self record framework metrics");
1456 }
1457 mediametrics_delete(item);
1458 return serializedMetrics;
1459 }
1460
reportPluginMetrics() const1461 std::string DrmHalHidl::reportPluginMetrics() const {
1462 Vector<uint8_t> metricsVector;
1463 String8 vendor;
1464 String8 description;
1465 std::string metricsString;
1466 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1467 getPropertyStringInternal(String8("description"), description) == OK &&
1468 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1469 metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
1470 status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
1471 mMetrics.GetAppUid());
1472 if (res != OK) {
1473 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1474 }
1475 }
1476 return metricsString;
1477 }
1478
requiresSecureDecoder(const char * mime,bool * required) const1479 status_t DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
1480 Mutex::Autolock autoLock(mLock);
1481 if (mPluginV1_4 == NULL) {
1482 return false;
1483 }
1484 auto hResult = mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1485 if (!hResult.isOk()) {
1486 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
1487 return DEAD_OBJECT;
1488 }
1489 if (required) {
1490 *required = hResult;
1491 }
1492 return OK;
1493 }
1494
requiresSecureDecoder(const char * mime,DrmPlugin::SecurityLevel securityLevel,bool * required) const1495 status_t DrmHalHidl::requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
1496 bool* required) const {
1497 Mutex::Autolock autoLock(mLock);
1498 if (mPluginV1_4 == NULL) {
1499 return false;
1500 }
1501 auto hLevel = toHidlSecurityLevel(securityLevel);
1502 auto hResult = mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1503 if (!hResult.isOk()) {
1504 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
1505 return DEAD_OBJECT;
1506 }
1507 if (required) {
1508 *required = hResult;
1509 }
1510 return OK;
1511 }
1512
setPlaybackId(Vector<uint8_t> const & sessionId,const char * playbackId)1513 status_t DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
1514 Mutex::Autolock autoLock(mLock);
1515 if (mPluginV1_4 == NULL) {
1516 return ERROR_UNSUPPORTED;
1517 }
1518 auto err = mPluginV1_4->setPlaybackId(toHidlVec(sessionId), hidl_string(playbackId));
1519 return err.isOk() ? toStatusT(err) : DEAD_OBJECT;
1520 }
1521
getLogMessages(Vector<drm::V1_4::LogMessage> & logs) const1522 status_t DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
1523 Mutex::Autolock autoLock(mLock);
1524 return DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs);
1525 }
1526
getSupportedSchemes(std::vector<uint8_t> & schemes) const1527 status_t DrmHalHidl::getSupportedSchemes(std::vector<uint8_t> &schemes) const {
1528 Mutex::Autolock autoLock(mLock);
1529 for (auto &factory : mFactories) {
1530 sp<drm::V1_3::IDrmFactory> factoryV1_3 = drm::V1_3::IDrmFactory::castFrom(factory);
1531 if (factoryV1_3 == nullptr) {
1532 continue;
1533 }
1534
1535 factoryV1_3->getSupportedCryptoSchemes(
1536 [&](const hardware::hidl_vec<hardware::hidl_array<uint8_t, 16>>& schemes_hidl) {
1537 for (const auto &scheme : schemes_hidl) {
1538 schemes.insert(schemes.end(), scheme.data(), scheme.data() + scheme.size());
1539 }
1540 });
1541 }
1542
1543 return OK;
1544 }
1545
1546 } // namespace android
1547