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