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