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