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