• 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 <utils/Log.h>
20 
21 #include <binder/IPCThreadState.h>
22 #include <binder/IServiceManager.h>
23 
24 #include <android/hardware/drm/1.0/IDrmFactory.h>
25 #include <android/hardware/drm/1.0/IDrmPlugin.h>
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/DrmHal.h>
31 #include <media/DrmSessionClientInterface.h>
32 #include <media/DrmSessionManager.h>
33 #include <media/PluginMetricsReporting.h>
34 #include <media/drm/DrmAPI.h>
35 #include <media/stagefright/foundation/ADebug.h>
36 #include <media/stagefright/foundation/AString.h>
37 #include <media/stagefright/foundation/hexdump.h>
38 #include <media/stagefright/MediaErrors.h>
39 
40 using ::android::hardware::drm::V1_0::EventType;
41 using ::android::hardware::drm::V1_0::IDrmFactory;
42 using ::android::hardware::drm::V1_0::IDrmPlugin;
43 using ::android::hardware::drm::V1_0::KeyedVector;
44 using ::android::hardware::drm::V1_0::KeyRequestType;
45 using ::android::hardware::drm::V1_0::KeyStatus;
46 using ::android::hardware::drm::V1_0::KeyStatusType;
47 using ::android::hardware::drm::V1_0::KeyType;
48 using ::android::hardware::drm::V1_0::KeyValue;
49 using ::android::hardware::drm::V1_0::SecureStop;
50 using ::android::hardware::drm::V1_0::Status;
51 using ::android::hardware::hidl_array;
52 using ::android::hardware::hidl_string;
53 using ::android::hardware::hidl_vec;
54 using ::android::hardware::Return;
55 using ::android::hardware::Void;
56 using ::android::hidl::manager::V1_0::IServiceManager;
57 using ::android::sp;
58 
59 namespace android {
60 
getCallingPid()61 static inline int getCallingPid() {
62     return IPCThreadState::self()->getCallingPid();
63 }
64 
checkPermission(const char * permissionString)65 static bool checkPermission(const char* permissionString) {
66     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
67     bool ok = checkCallingPermission(String16(permissionString));
68     if (!ok) ALOGE("Request requires %s", permissionString);
69     return ok;
70 }
71 
toVector(const hidl_vec<uint8_t> & vec)72 static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
73     Vector<uint8_t> vector;
74     vector.appendArray(vec.data(), vec.size());
75     return *const_cast<const Vector<uint8_t> *>(&vector);
76 }
77 
toHidlVec(const Vector<uint8_t> & vector)78 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
79     hidl_vec<uint8_t> vec;
80     vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
81     return vec;
82 }
83 
toString8(const hidl_string & string)84 static String8 toString8(const hidl_string &string) {
85     return String8(string.c_str());
86 }
87 
toHidlString(const String8 & string)88 static hidl_string toHidlString(const String8& string) {
89     return hidl_string(string.string());
90 }
91 
92 
toHidlKeyedVector(const KeyedVector<String8,String8> & keyedVector)93 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
94         keyedVector) {
95     std::vector<KeyValue> stdKeyedVector;
96     for (size_t i = 0; i < keyedVector.size(); i++) {
97         KeyValue keyValue;
98         keyValue.key = toHidlString(keyedVector.keyAt(i));
99         keyValue.value = toHidlString(keyedVector.valueAt(i));
100         stdKeyedVector.push_back(keyValue);
101     }
102     return ::KeyedVector(stdKeyedVector);
103 }
104 
toKeyedVector(const::KeyedVector & hKeyedVector)105 static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
106         hKeyedVector) {
107     KeyedVector<String8, String8> keyedVector;
108     for (size_t i = 0; i < hKeyedVector.size(); i++) {
109         keyedVector.add(toString8(hKeyedVector[i].key),
110                 toString8(hKeyedVector[i].value));
111     }
112     return keyedVector;
113 }
114 
toSecureStops(const hidl_vec<SecureStop> & hSecureStops)115 static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
116         hSecureStops) {
117     List<Vector<uint8_t>> secureStops;
118     for (size_t i = 0; i < hSecureStops.size(); i++) {
119         secureStops.push_back(toVector(hSecureStops[i].opaqueData));
120     }
121     return secureStops;
122 }
123 
toStatusT(Status status)124 static status_t toStatusT(Status status) {
125     switch (status) {
126     case Status::OK:
127         return OK;
128         break;
129     case Status::ERROR_DRM_NO_LICENSE:
130         return ERROR_DRM_NO_LICENSE;
131         break;
132     case Status::ERROR_DRM_LICENSE_EXPIRED:
133         return ERROR_DRM_LICENSE_EXPIRED;
134         break;
135     case Status::ERROR_DRM_SESSION_NOT_OPENED:
136         return ERROR_DRM_SESSION_NOT_OPENED;
137         break;
138     case Status::ERROR_DRM_CANNOT_HANDLE:
139         return ERROR_DRM_CANNOT_HANDLE;
140         break;
141     case Status::ERROR_DRM_INVALID_STATE:
142         return ERROR_DRM_TAMPER_DETECTED;
143         break;
144     case Status::BAD_VALUE:
145         return BAD_VALUE;
146         break;
147     case Status::ERROR_DRM_NOT_PROVISIONED:
148         return ERROR_DRM_NOT_PROVISIONED;
149         break;
150     case Status::ERROR_DRM_RESOURCE_BUSY:
151         return ERROR_DRM_RESOURCE_BUSY;
152         break;
153     case Status::ERROR_DRM_DEVICE_REVOKED:
154         return ERROR_DRM_DEVICE_REVOKED;
155         break;
156     case Status::ERROR_DRM_UNKNOWN:
157     default:
158         return ERROR_DRM_UNKNOWN;
159         break;
160     }
161 }
162 
163 
164 Mutex DrmHal::mLock;
165 
166 struct DrmSessionClient : public DrmSessionClientInterface {
DrmSessionClientandroid::DrmSessionClient167     explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
168 
reclaimSessionandroid::DrmSessionClient169     virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
170         sp<DrmHal> drm = mDrm.promote();
171         if (drm == NULL) {
172             return true;
173         }
174         status_t err = drm->closeSession(sessionId);
175         if (err != OK) {
176             return false;
177         }
178         drm->sendEvent(EventType::SESSION_RECLAIMED,
179                 toHidlVec(sessionId), hidl_vec<uint8_t>());
180         return true;
181     }
182 
183 protected:
~DrmSessionClientandroid::DrmSessionClient184     virtual ~DrmSessionClient() {}
185 
186 private:
187     wp<DrmHal> mDrm;
188 
189     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
190 };
191 
DrmHal()192 DrmHal::DrmHal()
193    : mDrmSessionClient(new DrmSessionClient(this)),
194      mFactories(makeDrmFactories()),
195      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
196 }
197 
closeOpenSessions()198 void DrmHal::closeOpenSessions() {
199     if (mPlugin != NULL) {
200         for (size_t i = 0; i < mOpenSessions.size(); i++) {
201             mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
202             DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
203         }
204     }
205     mOpenSessions.clear();
206 }
207 
~DrmHal()208 DrmHal::~DrmHal() {
209     closeOpenSessions();
210     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
211 }
212 
makeDrmFactories()213 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
214     Vector<sp<IDrmFactory>> factories;
215 
216     auto manager = hardware::defaultServiceManager();
217 
218     if (manager != NULL) {
219         manager->listByInterface(IDrmFactory::descriptor,
220                 [&factories](const hidl_vec<hidl_string> &registered) {
221                     for (const auto &instance : registered) {
222                         auto factory = IDrmFactory::getService(instance);
223                         if (factory != NULL) {
224                             factories.push_back(factory);
225                             ALOGI("makeDrmFactories: factory instance %s is %s",
226                                     instance.c_str(),
227                                     factory->isRemote() ? "Remote" : "Not Remote");
228                         }
229                     }
230                 }
231             );
232     }
233 
234     if (factories.size() == 0) {
235         // must be in passthrough mode, load the default passthrough service
236         auto passthrough = IDrmFactory::getService();
237         if (passthrough != NULL) {
238             ALOGI("makeDrmFactories: using default drm instance");
239             factories.push_back(passthrough);
240         } else {
241             ALOGE("Failed to find any drm factories");
242         }
243     }
244     return factories;
245 }
246 
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)247 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
248         const uint8_t uuid[16], const String8& appPackageName) {
249 
250     sp<IDrmPlugin> plugin;
251     Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
252             [&](Status status, const sp<IDrmPlugin>& hPlugin) {
253                 if (status != Status::OK) {
254                     ALOGE("Failed to make drm plugin");
255                     return;
256                 }
257                 plugin = hPlugin;
258             }
259         );
260 
261     if (!hResult.isOk()) {
262         ALOGE("createPlugin remote call failed");
263     }
264 
265     return plugin;
266 }
267 
initCheck() const268 status_t DrmHal::initCheck() const {
269     return mInitCheck;
270 }
271 
setListener(const sp<IDrmClient> & listener)272 status_t DrmHal::setListener(const sp<IDrmClient>& listener)
273 {
274     Mutex::Autolock lock(mEventLock);
275     if (mListener != NULL){
276         IInterface::asBinder(mListener)->unlinkToDeath(this);
277     }
278     if (listener != NULL) {
279         IInterface::asBinder(listener)->linkToDeath(this);
280     }
281     mListener = listener;
282     return NO_ERROR;
283 }
284 
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)285 Return<void> DrmHal::sendEvent(EventType hEventType,
286         const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
287 
288     mEventLock.lock();
289     sp<IDrmClient> listener = mListener;
290     mEventLock.unlock();
291 
292     if (listener != NULL) {
293         Parcel obj;
294         writeByteArray(obj, sessionId);
295         writeByteArray(obj, data);
296 
297         Mutex::Autolock lock(mNotifyLock);
298         DrmPlugin::EventType eventType;
299         switch(hEventType) {
300         case EventType::PROVISION_REQUIRED:
301             eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
302             break;
303         case EventType::KEY_NEEDED:
304             eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
305             break;
306         case EventType::KEY_EXPIRED:
307             eventType = DrmPlugin::kDrmPluginEventKeyExpired;
308             break;
309         case EventType::VENDOR_DEFINED:
310             eventType = DrmPlugin::kDrmPluginEventVendorDefined;
311             break;
312         case EventType::SESSION_RECLAIMED:
313             eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
314             break;
315         default:
316             return Void();
317         }
318         listener->notify(eventType, 0, &obj);
319     }
320     return Void();
321 }
322 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)323 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
324         int64_t expiryTimeInMS) {
325 
326     mEventLock.lock();
327     sp<IDrmClient> listener = mListener;
328     mEventLock.unlock();
329 
330     if (listener != NULL) {
331         Parcel obj;
332         writeByteArray(obj, sessionId);
333         obj.writeInt64(expiryTimeInMS);
334 
335         Mutex::Autolock lock(mNotifyLock);
336         listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
337     }
338     return Void();
339 }
340 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)341 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
342         const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
343 
344     mEventLock.lock();
345     sp<IDrmClient> listener = mListener;
346     mEventLock.unlock();
347 
348     if (listener != NULL) {
349         Parcel obj;
350         writeByteArray(obj, sessionId);
351 
352         size_t nKeys = keyStatusList.size();
353         obj.writeInt32(nKeys);
354         for (size_t i = 0; i < nKeys; ++i) {
355             const KeyStatus &keyStatus = keyStatusList[i];
356             writeByteArray(obj, keyStatus.keyId);
357             uint32_t type;
358             switch(keyStatus.type) {
359             case KeyStatusType::USABLE:
360                 type = DrmPlugin::kKeyStatusType_Usable;
361                 break;
362             case KeyStatusType::EXPIRED:
363                 type = DrmPlugin::kKeyStatusType_Expired;
364                 break;
365             case KeyStatusType::OUTPUTNOTALLOWED:
366                 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
367                 break;
368             case KeyStatusType::STATUSPENDING:
369                 type = DrmPlugin::kKeyStatusType_StatusPending;
370                 break;
371             case KeyStatusType::INTERNALERROR:
372             default:
373                 type = DrmPlugin::kKeyStatusType_InternalError;
374                 break;
375             }
376             obj.writeInt32(type);
377         }
378         obj.writeInt32(hasNewUsableKey);
379 
380         Mutex::Autolock lock(mNotifyLock);
381         listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
382     }
383     return Void();
384 }
385 
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType)386 bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
387     Mutex::Autolock autoLock(mLock);
388 
389     for (size_t i = 0; i < mFactories.size(); i++) {
390         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
391             if (mimeType != "") {
392                 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
393                     return true;
394                 }
395             } else {
396                 return true;
397             }
398         }
399     }
400     return false;
401 }
402 
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)403 status_t DrmHal::createPlugin(const uint8_t uuid[16],
404         const String8& appPackageName) {
405     Mutex::Autolock autoLock(mLock);
406 
407     for (size_t i = 0; i < mFactories.size(); i++) {
408         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
409             mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
410         }
411     }
412 
413     if (mPlugin == NULL) {
414         mInitCheck = ERROR_UNSUPPORTED;
415     } else {
416         if (!mPlugin->setListener(this).isOk()) {
417             mInitCheck = DEAD_OBJECT;
418         } else {
419             mInitCheck = OK;
420         }
421     }
422 
423     return mInitCheck;
424 }
425 
destroyPlugin()426 status_t DrmHal::destroyPlugin() {
427     Mutex::Autolock autoLock(mLock);
428     if (mInitCheck != OK) {
429         return mInitCheck;
430     }
431 
432     closeOpenSessions();
433     reportMetrics();
434     setListener(NULL);
435     mInitCheck = NO_INIT;
436 
437     if (mPlugin != NULL) {
438         if (!mPlugin->setListener(NULL).isOk()) {
439             mInitCheck = DEAD_OBJECT;
440         }
441     }
442     mPlugin.clear();
443     return OK;
444 }
445 
openSession(Vector<uint8_t> & sessionId)446 status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
447     Mutex::Autolock autoLock(mLock);
448 
449     if (mInitCheck != OK) {
450         return mInitCheck;
451     }
452 
453     status_t  err = UNKNOWN_ERROR;
454 
455     bool retry = true;
456     do {
457         hidl_vec<uint8_t> hSessionId;
458 
459         Return<void> hResult = mPlugin->openSession(
460                 [&](Status status, const hidl_vec<uint8_t>& id) {
461                     if (status == Status::OK) {
462                         sessionId = toVector(id);
463                     }
464                     err = toStatusT(status);
465                 }
466             );
467 
468         if (!hResult.isOk()) {
469             err = DEAD_OBJECT;
470         }
471 
472         if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
473             mLock.unlock();
474             // reclaimSession may call back to closeSession, since mLock is
475             // shared between Drm instances, we should unlock here to avoid
476             // deadlock.
477             retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
478             mLock.lock();
479         } else {
480             retry = false;
481         }
482     } while (retry);
483 
484     if (err == OK) {
485         DrmSessionManager::Instance()->addSession(getCallingPid(),
486                 mDrmSessionClient, sessionId);
487         mOpenSessions.push(sessionId);
488     }
489     return err;
490 }
491 
closeSession(Vector<uint8_t> const & sessionId)492 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
493     Mutex::Autolock autoLock(mLock);
494 
495     if (mInitCheck != OK) {
496         return mInitCheck;
497     }
498 
499     Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
500     if (status.isOk()) {
501         if (status == Status::OK) {
502             DrmSessionManager::Instance()->removeSession(sessionId);
503             for (size_t i = 0; i < mOpenSessions.size(); i++) {
504                 if (mOpenSessions[i] == sessionId) {
505                     mOpenSessions.removeAt(i);
506                     break;
507                 }
508             }
509         }
510         reportMetrics();
511         return toStatusT(status);
512     }
513     return DEAD_OBJECT;
514 }
515 
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)516 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
517         Vector<uint8_t> const &initData, String8 const &mimeType,
518         DrmPlugin::KeyType keyType, KeyedVector<String8,
519         String8> const &optionalParameters, Vector<uint8_t> &request,
520         String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
521     Mutex::Autolock autoLock(mLock);
522 
523     if (mInitCheck != OK) {
524         return mInitCheck;
525     }
526 
527     DrmSessionManager::Instance()->useSession(sessionId);
528 
529     KeyType hKeyType;
530     if (keyType == DrmPlugin::kKeyType_Streaming) {
531         hKeyType = KeyType::STREAMING;
532     } else if (keyType == DrmPlugin::kKeyType_Offline) {
533         hKeyType = KeyType::OFFLINE;
534     } else if (keyType == DrmPlugin::kKeyType_Release) {
535         hKeyType = KeyType::RELEASE;
536     } else {
537         return BAD_VALUE;
538     }
539 
540     ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
541 
542     status_t err = UNKNOWN_ERROR;
543 
544     Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
545             toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
546             [&](Status status, const hidl_vec<uint8_t>& hRequest,
547                     KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
548 
549                 if (status == Status::OK) {
550                     request = toVector(hRequest);
551                     defaultUrl = toString8(hDefaultUrl);
552 
553                     switch (hKeyRequestType) {
554                     case KeyRequestType::INITIAL:
555                         *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
556                         break;
557                     case KeyRequestType::RENEWAL:
558                         *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
559                         break;
560                     case KeyRequestType::RELEASE:
561                         *keyRequestType = DrmPlugin::kKeyRequestType_Release;
562                         break;
563                     default:
564                         *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
565                         break;
566                     }
567                     err = toStatusT(status);
568                 }
569             });
570 
571     return hResult.isOk() ? err : DEAD_OBJECT;
572 }
573 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)574 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
575         Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
576     Mutex::Autolock autoLock(mLock);
577 
578     if (mInitCheck != OK) {
579         return mInitCheck;
580     }
581 
582     DrmSessionManager::Instance()->useSession(sessionId);
583 
584     status_t err = UNKNOWN_ERROR;
585 
586     Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
587             toHidlVec(response),
588             [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
589                 if (status == Status::OK) {
590                     keySetId = toVector(hKeySetId);
591                 }
592                 err = toStatusT(status);
593             }
594         );
595 
596     return hResult.isOk() ? err : DEAD_OBJECT;
597 }
598 
removeKeys(Vector<uint8_t> const & keySetId)599 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
600     Mutex::Autolock autoLock(mLock);
601 
602     if (mInitCheck != OK) {
603         return mInitCheck;
604     }
605 
606     return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
607 }
608 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)609 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
610         Vector<uint8_t> const &keySetId) {
611     Mutex::Autolock autoLock(mLock);
612 
613     if (mInitCheck != OK) {
614         return mInitCheck;
615     }
616 
617     DrmSessionManager::Instance()->useSession(sessionId);
618 
619     return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
620                     toHidlVec(keySetId)));
621 }
622 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const623 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
624         KeyedVector<String8, String8> &infoMap) const {
625     Mutex::Autolock autoLock(mLock);
626 
627     if (mInitCheck != OK) {
628         return mInitCheck;
629     }
630 
631     DrmSessionManager::Instance()->useSession(sessionId);
632 
633     ::KeyedVector hInfoMap;
634 
635     status_t err = UNKNOWN_ERROR;
636 
637     Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
638             [&](Status status, const hidl_vec<KeyValue>& map) {
639                 if (status == Status::OK) {
640                     infoMap = toKeyedVector(map);
641                 }
642                 err = toStatusT(status);
643             }
644         );
645 
646     return hResult.isOk() ? err : DEAD_OBJECT;
647 }
648 
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)649 status_t DrmHal::getProvisionRequest(String8 const &certType,
650         String8 const &certAuthority, Vector<uint8_t> &request,
651         String8 &defaultUrl) {
652     Mutex::Autolock autoLock(mLock);
653 
654     if (mInitCheck != OK) {
655         return mInitCheck;
656     }
657 
658     status_t err = UNKNOWN_ERROR;
659 
660     Return<void> hResult = mPlugin->getProvisionRequest(
661             toHidlString(certType), toHidlString(certAuthority),
662             [&](Status status, const hidl_vec<uint8_t>& hRequest,
663                     const hidl_string& hDefaultUrl) {
664                 if (status == Status::OK) {
665                     request = toVector(hRequest);
666                     defaultUrl = toString8(hDefaultUrl);
667                 }
668                 err = toStatusT(status);
669             }
670         );
671 
672     return hResult.isOk() ? err : DEAD_OBJECT;
673 }
674 
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)675 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
676         Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
677     Mutex::Autolock autoLock(mLock);
678 
679     if (mInitCheck != OK) {
680         return mInitCheck;
681     }
682 
683     status_t err = UNKNOWN_ERROR;
684 
685     Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
686             [&](Status status, const hidl_vec<uint8_t>& hCertificate,
687                     const hidl_vec<uint8_t>& hWrappedKey) {
688                 if (status == Status::OK) {
689                     certificate = toVector(hCertificate);
690                     wrappedKey = toVector(hWrappedKey);
691                 }
692                 err = toStatusT(status);
693             }
694         );
695 
696     return hResult.isOk() ? err : DEAD_OBJECT;
697 }
698 
getSecureStops(List<Vector<uint8_t>> & secureStops)699 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
700     Mutex::Autolock autoLock(mLock);
701 
702     if (mInitCheck != OK) {
703         return mInitCheck;
704     }
705 
706     status_t err = UNKNOWN_ERROR;
707 
708     Return<void> hResult = mPlugin->getSecureStops(
709             [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
710                 if (status == Status::OK) {
711                     secureStops = toSecureStops(hSecureStops);
712                 }
713                 err = toStatusT(status);
714             }
715     );
716 
717     return hResult.isOk() ? err : DEAD_OBJECT;
718 }
719 
720 
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)721 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
722     Mutex::Autolock autoLock(mLock);
723 
724     if (mInitCheck != OK) {
725         return mInitCheck;
726     }
727 
728     status_t err = UNKNOWN_ERROR;
729 
730     Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
731             [&](Status status, const SecureStop& hSecureStop) {
732                 if (status == Status::OK) {
733                     secureStop = toVector(hSecureStop.opaqueData);
734                 }
735                 err = toStatusT(status);
736             }
737     );
738 
739     return hResult.isOk() ? err : DEAD_OBJECT;
740 }
741 
releaseSecureStops(Vector<uint8_t> const & ssRelease)742 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
743     Mutex::Autolock autoLock(mLock);
744 
745     if (mInitCheck != OK) {
746         return mInitCheck;
747     }
748 
749     return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
750 }
751 
releaseAllSecureStops()752 status_t DrmHal::releaseAllSecureStops() {
753     Mutex::Autolock autoLock(mLock);
754 
755     if (mInitCheck != OK) {
756         return mInitCheck;
757     }
758 
759     return toStatusT(mPlugin->releaseAllSecureStops());
760 }
761 
getPropertyString(String8 const & name,String8 & value) const762 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
763     Mutex::Autolock autoLock(mLock);
764     return getPropertyStringInternal(name, value);
765 }
766 
getPropertyStringInternal(String8 const & name,String8 & value) const767 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
768     // This function is internal to the class and should only be called while
769     // mLock is already held.
770 
771     if (mInitCheck != OK) {
772         return mInitCheck;
773     }
774 
775     status_t err = UNKNOWN_ERROR;
776 
777     Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
778             [&](Status status, const hidl_string& hValue) {
779                 if (status == Status::OK) {
780                     value = toString8(hValue);
781                 }
782                 err = toStatusT(status);
783             }
784     );
785 
786     return hResult.isOk() ? err : DEAD_OBJECT;
787 }
788 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const789 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
790     Mutex::Autolock autoLock(mLock);
791     return getPropertyByteArrayInternal(name, value);
792 }
793 
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const794 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
795     // This function is internal to the class and should only be called while
796     // mLock is already held.
797 
798     if (mInitCheck != OK) {
799         return mInitCheck;
800     }
801 
802     status_t err = UNKNOWN_ERROR;
803 
804     Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
805             [&](Status status, const hidl_vec<uint8_t>& hValue) {
806                 if (status == Status::OK) {
807                     value = toVector(hValue);
808                 }
809                 err = toStatusT(status);
810             }
811     );
812 
813     return hResult.isOk() ? err : DEAD_OBJECT;
814 }
815 
setPropertyString(String8 const & name,String8 const & value) const816 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
817     Mutex::Autolock autoLock(mLock);
818 
819     if (mInitCheck != OK) {
820         return mInitCheck;
821     }
822 
823     Status status =  mPlugin->setPropertyString(toHidlString(name),
824             toHidlString(value));
825     return toStatusT(status);
826 }
827 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const828 status_t DrmHal::setPropertyByteArray(String8 const &name,
829                                    Vector<uint8_t> const &value ) const {
830     Mutex::Autolock autoLock(mLock);
831 
832     if (mInitCheck != OK) {
833         return mInitCheck;
834     }
835 
836     Status status = mPlugin->setPropertyByteArray(toHidlString(name),
837             toHidlVec(value));
838     return toStatusT(status);
839 }
840 
841 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)842 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
843                                  String8 const &algorithm) {
844     Mutex::Autolock autoLock(mLock);
845 
846     if (mInitCheck != OK) {
847         return mInitCheck;
848     }
849 
850     DrmSessionManager::Instance()->useSession(sessionId);
851 
852     Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
853             toHidlString(algorithm));
854     return toStatusT(status);
855 }
856 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)857 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
858                               String8 const &algorithm) {
859     Mutex::Autolock autoLock(mLock);
860 
861     if (mInitCheck != OK) {
862         return mInitCheck;
863     }
864 
865     DrmSessionManager::Instance()->useSession(sessionId);
866 
867     Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
868             toHidlString(algorithm));
869     return toStatusT(status);
870 }
871 
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)872 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
873         Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
874         Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
875     Mutex::Autolock autoLock(mLock);
876 
877     if (mInitCheck != OK) {
878         return mInitCheck;
879     }
880 
881     DrmSessionManager::Instance()->useSession(sessionId);
882 
883     status_t err = UNKNOWN_ERROR;
884 
885     Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
886             toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
887             [&](Status status, const hidl_vec<uint8_t>& hOutput) {
888                 if (status == Status::OK) {
889                     output = toVector(hOutput);
890                 }
891                 err = toStatusT(status);
892             }
893     );
894 
895     return hResult.isOk() ? err : DEAD_OBJECT;
896 }
897 
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)898 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
899         Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
900         Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
901     Mutex::Autolock autoLock(mLock);
902 
903     if (mInitCheck != OK) {
904         return mInitCheck;
905     }
906 
907     DrmSessionManager::Instance()->useSession(sessionId);
908 
909     status_t  err = UNKNOWN_ERROR;
910 
911     Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
912             toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
913             [&](Status status, const hidl_vec<uint8_t>& hOutput) {
914                 if (status == Status::OK) {
915                     output = toVector(hOutput);
916                 }
917                 err = toStatusT(status);
918             }
919     );
920 
921     return hResult.isOk() ? err : DEAD_OBJECT;
922 }
923 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)924 status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
925         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
926         Vector<uint8_t> &signature) {
927     Mutex::Autolock autoLock(mLock);
928 
929     if (mInitCheck != OK) {
930         return mInitCheck;
931     }
932 
933     DrmSessionManager::Instance()->useSession(sessionId);
934 
935     status_t err = UNKNOWN_ERROR;
936 
937     Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
938             toHidlVec(keyId), toHidlVec(message),
939             [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
940                 if (status == Status::OK) {
941                     signature = toVector(hSignature);
942                 }
943                 err = toStatusT(status);
944             }
945     );
946 
947     return hResult.isOk() ? err : DEAD_OBJECT;
948 }
949 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)950 status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
951         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
952         Vector<uint8_t> const &signature, bool &match) {
953     Mutex::Autolock autoLock(mLock);
954 
955     if (mInitCheck != OK) {
956         return mInitCheck;
957     }
958 
959     DrmSessionManager::Instance()->useSession(sessionId);
960 
961     status_t err = UNKNOWN_ERROR;
962 
963     Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
964             toHidlVec(message), toHidlVec(signature),
965             [&](Status status, bool hMatch) {
966                 if (status == Status::OK) {
967                     match = hMatch;
968                 } else {
969                     match = false;
970                 }
971                 err = toStatusT(status);
972             }
973     );
974 
975     return hResult.isOk() ? err : DEAD_OBJECT;
976 }
977 
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)978 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
979         String8 const &algorithm, Vector<uint8_t> const &message,
980         Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
981     Mutex::Autolock autoLock(mLock);
982 
983     if (mInitCheck != OK) {
984         return mInitCheck;
985     }
986 
987     if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
988         return -EPERM;
989     }
990 
991     DrmSessionManager::Instance()->useSession(sessionId);
992 
993     status_t err = UNKNOWN_ERROR;
994 
995     Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
996             toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
997             [&](Status status, const hidl_vec<uint8_t>& hSignature) {
998                 if (status == Status::OK) {
999                     signature = toVector(hSignature);
1000                 }
1001                 err = toStatusT(status);
1002             }
1003         );
1004 
1005     return hResult.isOk() ? err : DEAD_OBJECT;
1006 }
1007 
binderDied(const wp<IBinder> & the_late_who __unused)1008 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1009 {
1010     Mutex::Autolock autoLock(mLock);
1011     closeOpenSessions();
1012     setListener(NULL);
1013     mInitCheck = NO_INIT;
1014 
1015     if (mPlugin != NULL) {
1016         if (!mPlugin->setListener(NULL).isOk()) {
1017             mInitCheck = DEAD_OBJECT;
1018         }
1019     }
1020     mPlugin.clear();
1021 }
1022 
writeByteArray(Parcel & obj,hidl_vec<uint8_t> const & vec)1023 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1024 {
1025     if (vec.size()) {
1026         obj.writeInt32(vec.size());
1027         obj.write(vec.data(), vec.size());
1028     } else {
1029         obj.writeInt32(0);
1030     }
1031 }
1032 
reportMetrics() const1033 void DrmHal::reportMetrics() const
1034 {
1035     Vector<uint8_t> metrics;
1036     String8 vendor;
1037     String8 description;
1038     if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1039             getPropertyStringInternal(String8("description"), description) == OK &&
1040             getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1041         status_t res = android::reportDrmPluginMetrics(
1042                 metrics, vendor, description);
1043         if (res != OK) {
1044             ALOGE("Metrics were retrieved but could not be reported: %i", res);
1045         }
1046     }
1047 }
1048 
1049 }  // namespace android
1050