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