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