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