• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "DrmHal"
19 #include <iomanip>
20 
21 #include <utils/Log.h>
22 
23 #include <binder/IPCThreadState.h>
24 #include <binder/IServiceManager.h>
25 
26 #include <android/hardware/drm/1.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 
299 Mutex DrmHal::mLock;
300 
301 struct DrmSessionClient : public DrmSessionClientInterface {
DrmSessionClientandroid::DrmSessionClient302     explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
303 
reclaimSessionandroid::DrmSessionClient304     virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
305         sp<DrmHal> drm = mDrm.promote();
306         if (drm == NULL) {
307             return true;
308         }
309         status_t err = drm->closeSession(sessionId);
310         if (err != OK) {
311             return false;
312         }
313         drm->sendEvent(EventType::SESSION_RECLAIMED,
314                 toHidlVec(sessionId), hidl_vec<uint8_t>());
315         return true;
316     }
317 
318 protected:
~DrmSessionClientandroid::DrmSessionClient319     virtual ~DrmSessionClient() {}
320 
321 private:
322     wp<DrmHal> mDrm;
323 
324     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
325 };
326 
DrmHal()327 DrmHal::DrmHal()
328    : mDrmSessionClient(new DrmSessionClient(this)),
329      mFactories(makeDrmFactories()),
330      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
331 }
332 
closeOpenSessions()333 void DrmHal::closeOpenSessions() {
334     Mutex::Autolock autoLock(mLock);
335     auto openSessions = mOpenSessions;
336     for (size_t i = 0; i < openSessions.size(); i++) {
337         mLock.unlock();
338         closeSession(openSessions[i]);
339         mLock.lock();
340     }
341     mOpenSessions.clear();
342 }
343 
~DrmHal()344 DrmHal::~DrmHal() {
345     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
346 }
347 
cleanup()348 void DrmHal::cleanup() {
349     closeOpenSessions();
350 
351     Mutex::Autolock autoLock(mLock);
352     reportPluginMetrics();
353     reportFrameworkMetrics();
354 
355     setListener(NULL);
356     mInitCheck = NO_INIT;
357     if (mPluginV1_2 != NULL) {
358         if (!mPluginV1_2->setListener(NULL).isOk()) {
359             mInitCheck = DEAD_OBJECT;
360         }
361     } else if (mPlugin != NULL) {
362         if (!mPlugin->setListener(NULL).isOk()) {
363             mInitCheck = DEAD_OBJECT;
364         }
365     }
366     mPlugin.clear();
367     mPluginV1_1.clear();
368     mPluginV1_2.clear();
369 }
370 
makeDrmFactories()371 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
372     Vector<sp<IDrmFactory>> factories;
373 
374     auto manager = hardware::defaultServiceManager1_2();
375 
376     if (manager != NULL) {
377         manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
378                 [&factories](const hidl_vec<hidl_string> &registered) {
379                     for (const auto &instance : registered) {
380                         auto factory = drm::V1_0::IDrmFactory::getService(instance);
381                         if (factory != NULL) {
382                             factories.push_back(factory);
383                         }
384                     }
385                 }
386             );
387         manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
388                 [&factories](const hidl_vec<hidl_string> &registered) {
389                     for (const auto &instance : registered) {
390                         auto factory = drm::V1_1::IDrmFactory::getService(instance);
391                         if (factory != NULL) {
392                             factories.push_back(factory);
393                         }
394                     }
395                 }
396             );
397         manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
398                 [&factories](const hidl_vec<hidl_string> &registered) {
399                     for (const auto &instance : registered) {
400                         auto factory = drm::V1_2::IDrmFactory::getService(instance);
401                         if (factory != NULL) {
402                             factories.push_back(factory);
403                         }
404                     }
405                 }
406             );
407     }
408 
409     if (factories.size() == 0) {
410         // must be in passthrough mode, load the default passthrough service
411         auto passthrough = IDrmFactory::getService();
412         if (passthrough != NULL) {
413             ALOGI("makeDrmFactories: using default passthrough drm instance");
414             factories.push_back(passthrough);
415         } else {
416             ALOGE("Failed to find any drm factories");
417         }
418     }
419     return factories;
420 }
421 
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)422 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
423         const uint8_t uuid[16], const String8& appPackageName) {
424     mAppPackageName = appPackageName;
425     mMetrics.SetAppPackageName(appPackageName);
426 
427     sp<IDrmPlugin> plugin;
428     Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
429             [&](Status status, const sp<IDrmPlugin>& hPlugin) {
430                 if (status != Status::OK) {
431                     ALOGE("Failed to make drm plugin");
432                     return;
433                 }
434                 plugin = hPlugin;
435             }
436         );
437 
438     if (!hResult.isOk()) {
439         ALOGE("createPlugin remote call failed");
440     }
441 
442     return plugin;
443 }
444 
initCheck() const445 status_t DrmHal::initCheck() const {
446     return mInitCheck;
447 }
448 
setListener(const sp<IDrmClient> & listener)449 status_t DrmHal::setListener(const sp<IDrmClient>& listener)
450 {
451     Mutex::Autolock lock(mEventLock);
452     if (mListener != NULL){
453         IInterface::asBinder(mListener)->unlinkToDeath(this);
454     }
455     if (listener != NULL) {
456         IInterface::asBinder(listener)->linkToDeath(this);
457     }
458     mListener = listener;
459     return NO_ERROR;
460 }
461 
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)462 Return<void> DrmHal::sendEvent(EventType hEventType,
463         const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
464     mMetrics.mEventCounter.Increment(hEventType);
465 
466     mEventLock.lock();
467     sp<IDrmClient> listener = mListener;
468     mEventLock.unlock();
469 
470     if (listener != NULL) {
471         Parcel obj;
472         writeByteArray(obj, sessionId);
473         writeByteArray(obj, data);
474 
475         Mutex::Autolock lock(mNotifyLock);
476         DrmPlugin::EventType eventType;
477         switch(hEventType) {
478         case EventType::PROVISION_REQUIRED:
479             eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
480             break;
481         case EventType::KEY_NEEDED:
482             eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
483             break;
484         case EventType::KEY_EXPIRED:
485             eventType = DrmPlugin::kDrmPluginEventKeyExpired;
486             break;
487         case EventType::VENDOR_DEFINED:
488             eventType = DrmPlugin::kDrmPluginEventVendorDefined;
489             break;
490         case EventType::SESSION_RECLAIMED:
491             eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
492             break;
493         default:
494             return Void();
495         }
496         listener->notify(eventType, 0, &obj);
497     }
498     return Void();
499 }
500 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)501 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
502         int64_t expiryTimeInMS) {
503 
504     mEventLock.lock();
505     sp<IDrmClient> listener = mListener;
506     mEventLock.unlock();
507 
508     if (listener != NULL) {
509         Parcel obj;
510         writeByteArray(obj, sessionId);
511         obj.writeInt64(expiryTimeInMS);
512 
513         Mutex::Autolock lock(mNotifyLock);
514         listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
515     }
516     return Void();
517 }
518 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus_V1_0> & keyStatusList_V1_0,bool hasNewUsableKey)519 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
520         const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
521     std::vector<KeyStatus> keyStatusVec;
522     for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
523         keyStatusVec.push_back({keyStatus_V1_0.keyId,
524                 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
525     }
526     hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
527     return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
528 }
529 
sendKeysChange_1_2(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)530 Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
531         const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
532 
533     mEventLock.lock();
534     sp<IDrmClient> listener = mListener;
535     mEventLock.unlock();
536 
537     if (listener != NULL) {
538         Parcel obj;
539         writeByteArray(obj, sessionId);
540 
541         size_t nKeys = keyStatusList.size();
542         obj.writeInt32(nKeys);
543         for (size_t i = 0; i < nKeys; ++i) {
544             const KeyStatus &keyStatus = keyStatusList[i];
545             writeByteArray(obj, keyStatus.keyId);
546             uint32_t type;
547             switch(keyStatus.type) {
548             case KeyStatusType::USABLE:
549                 type = DrmPlugin::kKeyStatusType_Usable;
550                 break;
551             case KeyStatusType::EXPIRED:
552                 type = DrmPlugin::kKeyStatusType_Expired;
553                 break;
554             case KeyStatusType::OUTPUTNOTALLOWED:
555                 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
556                 break;
557             case KeyStatusType::STATUSPENDING:
558                 type = DrmPlugin::kKeyStatusType_StatusPending;
559                 break;
560             case KeyStatusType::USABLEINFUTURE:
561                 type = DrmPlugin::kKeyStatusType_UsableInFuture;
562                 break;
563             case KeyStatusType::INTERNALERROR:
564             default:
565                 type = DrmPlugin::kKeyStatusType_InternalError;
566                 break;
567             }
568             obj.writeInt32(type);
569             mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
570         }
571         obj.writeInt32(hasNewUsableKey);
572 
573         Mutex::Autolock lock(mNotifyLock);
574         listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
575     } else {
576         // There's no listener. But we still want to count the key change
577         // events.
578         size_t nKeys = keyStatusList.size();
579         for (size_t i = 0; i < nKeys; i++) {
580             mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
581         }
582     }
583 
584     return Void();
585 }
586 
sendSessionLostState(const hidl_vec<uint8_t> & sessionId)587 Return<void> DrmHal::sendSessionLostState(
588         const hidl_vec<uint8_t>& sessionId) {
589 
590     mEventLock.lock();
591     sp<IDrmClient> listener = mListener;
592     mEventLock.unlock();
593 
594     if (listener != NULL) {
595         Parcel obj;
596         writeByteArray(obj, sessionId);
597         Mutex::Autolock lock(mNotifyLock);
598         listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
599     }
600     return Void();
601 }
602 
matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)603 status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
604                                                const uint8_t uuid[16],
605                                                const String8 &mimeType,
606                                                DrmPlugin::SecurityLevel level,
607                                                bool *isSupported) {
608     *isSupported = false;
609 
610     // handle default value cases
611     if (level == DrmPlugin::kSecurityLevelUnknown) {
612         if (mimeType == "") {
613             // isCryptoSchemeSupported(uuid)
614             *isSupported = true;
615         } else {
616             // isCryptoSchemeSupported(uuid, mimeType)
617             *isSupported = factory->isContentTypeSupported(mimeType.string());
618         }
619         return OK;
620     } else if (mimeType == "") {
621         return BAD_VALUE;
622     }
623 
624     sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
625     if (factoryV1_2 == NULL) {
626         return ERROR_UNSUPPORTED;
627     } else {
628         *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
629                 mimeType.string(), toHidlSecurityLevel(level));
630         return OK;
631     }
632 }
633 
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)634 status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
635                                          const String8 &mimeType,
636                                          DrmPlugin::SecurityLevel level,
637                                          bool *isSupported) {
638     Mutex::Autolock autoLock(mLock);
639     *isSupported = false;
640     for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
641         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
642             return matchMimeTypeAndSecurityLevel(mFactories[i],
643                     uuid, mimeType, level, isSupported);
644         }
645     }
646     return OK;
647 }
648 
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)649 status_t DrmHal::createPlugin(const uint8_t uuid[16],
650         const String8& appPackageName) {
651     Mutex::Autolock autoLock(mLock);
652 
653     for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
654         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
655             auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
656             if (plugin != NULL) {
657                 mPlugin = plugin;
658                 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
659                 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
660                 break;
661             }
662         }
663     }
664 
665     if (mPlugin == NULL) {
666         mInitCheck = ERROR_UNSUPPORTED;
667     } else {
668         mInitCheck = OK;
669         if (mPluginV1_2 != NULL) {
670             if (!mPluginV1_2->setListener(this).isOk()) {
671                 mInitCheck = DEAD_OBJECT;
672             }
673         } else if (!mPlugin->setListener(this).isOk()) {
674             mInitCheck = DEAD_OBJECT;
675         }
676         if (mInitCheck != OK) {
677             mPlugin.clear();
678             mPluginV1_1.clear();
679             mPluginV1_2.clear();
680         }
681     }
682 
683 
684     return mInitCheck;
685 }
686 
destroyPlugin()687 status_t DrmHal::destroyPlugin() {
688     cleanup();
689     return OK;
690 }
691 
openSession(DrmPlugin::SecurityLevel level,Vector<uint8_t> & sessionId)692 status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
693         Vector<uint8_t> &sessionId) {
694     Mutex::Autolock autoLock(mLock);
695     INIT_CHECK();
696 
697     SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
698     bool setSecurityLevel = true;
699 
700     if (level == DrmPlugin::kSecurityLevelMax) {
701         setSecurityLevel = false;
702     } else {
703         if (hSecurityLevel == SecurityLevel::UNKNOWN) {
704             return ERROR_DRM_CANNOT_HANDLE;
705         }
706     }
707 
708     status_t  err = UNKNOWN_ERROR;
709     bool retry = true;
710     do {
711         hidl_vec<uint8_t> hSessionId;
712 
713         Return<void> hResult;
714         if (mPluginV1_1 == NULL || !setSecurityLevel) {
715             hResult = mPlugin->openSession(
716                     [&](Status status,const hidl_vec<uint8_t>& id) {
717                         if (status == Status::OK) {
718                             sessionId = toVector(id);
719                         }
720                         err = toStatusT(status);
721                     }
722                 );
723         } else {
724             hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
725                     [&](Status status, const hidl_vec<uint8_t>& id) {
726                         if (status == Status::OK) {
727                             sessionId = toVector(id);
728                         }
729                         err = toStatusT(status);
730                     }
731                 );
732         }
733 
734         if (!hResult.isOk()) {
735             err = DEAD_OBJECT;
736         }
737 
738         if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
739             mLock.unlock();
740             // reclaimSession may call back to closeSession, since mLock is
741             // shared between Drm instances, we should unlock here to avoid
742             // deadlock.
743             retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
744             mLock.lock();
745         } else {
746             retry = false;
747         }
748     } while (retry);
749 
750     if (err == OK) {
751         DrmSessionManager::Instance()->addSession(getCallingPid(),
752                 mDrmSessionClient, sessionId);
753         mOpenSessions.push(sessionId);
754         mMetrics.SetSessionStart(sessionId);
755     }
756 
757     mMetrics.mOpenSessionCounter.Increment(err);
758     return err;
759 }
760 
closeSession(Vector<uint8_t> const & sessionId)761 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
762     Mutex::Autolock autoLock(mLock);
763     INIT_CHECK();
764 
765     Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
766     if (status.isOk()) {
767         if (status == Status::OK) {
768             DrmSessionManager::Instance()->removeSession(sessionId);
769             for (size_t i = 0; i < mOpenSessions.size(); i++) {
770                 if (mOpenSessions[i] == sessionId) {
771                     mOpenSessions.removeAt(i);
772                     break;
773                 }
774             }
775         }
776         status_t response = toStatusT(status);
777         mMetrics.SetSessionEnd(sessionId);
778         mMetrics.mCloseSessionCounter.Increment(response);
779         return response;
780     }
781     mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
782     return DEAD_OBJECT;
783 }
784 
toKeyRequestType(KeyRequestType keyRequestType)785 static DrmPlugin::KeyRequestType toKeyRequestType(
786         KeyRequestType keyRequestType) {
787     switch (keyRequestType) {
788         case KeyRequestType::INITIAL:
789             return DrmPlugin::kKeyRequestType_Initial;
790             break;
791         case KeyRequestType::RENEWAL:
792             return DrmPlugin::kKeyRequestType_Renewal;
793             break;
794         case KeyRequestType::RELEASE:
795             return DrmPlugin::kKeyRequestType_Release;
796             break;
797         default:
798             return DrmPlugin::kKeyRequestType_Unknown;
799             break;
800     }
801 }
802 
toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType)803 static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
804         KeyRequestType_V1_1 keyRequestType) {
805     switch (keyRequestType) {
806         case KeyRequestType_V1_1::NONE:
807             return DrmPlugin::kKeyRequestType_None;
808             break;
809         case KeyRequestType_V1_1::UPDATE:
810             return DrmPlugin::kKeyRequestType_Update;
811             break;
812         default:
813             return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
814             break;
815     }
816 }
817 
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)818 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
819         Vector<uint8_t> const &initData, String8 const &mimeType,
820         DrmPlugin::KeyType keyType, KeyedVector<String8,
821         String8> const &optionalParameters, Vector<uint8_t> &request,
822         String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
823     Mutex::Autolock autoLock(mLock);
824     INIT_CHECK();
825     EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
826 
827     DrmSessionManager::Instance()->useSession(sessionId);
828 
829     KeyType hKeyType;
830     if (keyType == DrmPlugin::kKeyType_Streaming) {
831         hKeyType = KeyType::STREAMING;
832     } else if (keyType == DrmPlugin::kKeyType_Offline) {
833         hKeyType = KeyType::OFFLINE;
834     } else if (keyType == DrmPlugin::kKeyType_Release) {
835         hKeyType = KeyType::RELEASE;
836     } else {
837         keyRequestTimer.SetAttribute(BAD_VALUE);
838         return BAD_VALUE;
839     }
840 
841     ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
842 
843     status_t err = UNKNOWN_ERROR;
844     Return<void> hResult;
845 
846     if (mPluginV1_2 != NULL) {
847         hResult = mPluginV1_2->getKeyRequest_1_2(
848                 toHidlVec(sessionId), toHidlVec(initData),
849                 toHidlString(mimeType), hKeyType, hOptionalParameters,
850                 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
851                         KeyRequestType_V1_1 hKeyRequestType,
852                         const hidl_string& hDefaultUrl) {
853                     if (status == Status_V1_2::OK) {
854                         request = toVector(hRequest);
855                         defaultUrl = toString8(hDefaultUrl);
856                         *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
857                     }
858                     err = toStatusT_1_2(status);
859                 });
860     } else if (mPluginV1_1 != NULL) {
861         hResult = mPluginV1_1->getKeyRequest_1_1(
862                 toHidlVec(sessionId), toHidlVec(initData),
863                 toHidlString(mimeType), hKeyType, hOptionalParameters,
864                 [&](Status status, const hidl_vec<uint8_t>& hRequest,
865                         KeyRequestType_V1_1 hKeyRequestType,
866                         const hidl_string& hDefaultUrl) {
867                     if (status == Status::OK) {
868                         request = toVector(hRequest);
869                         defaultUrl = toString8(hDefaultUrl);
870                         *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
871                     }
872                     err = toStatusT(status);
873                 });
874     } else {
875         hResult = mPlugin->getKeyRequest(
876                 toHidlVec(sessionId), toHidlVec(initData),
877                 toHidlString(mimeType), hKeyType, hOptionalParameters,
878                 [&](Status status, const hidl_vec<uint8_t>& hRequest,
879                         KeyRequestType hKeyRequestType,
880                         const hidl_string& hDefaultUrl) {
881                     if (status == Status::OK) {
882                         request = toVector(hRequest);
883                         defaultUrl = toString8(hDefaultUrl);
884                         *keyRequestType = toKeyRequestType(hKeyRequestType);
885                     }
886                     err = toStatusT(status);
887                 });
888     }
889 
890     err = hResult.isOk() ? err : DEAD_OBJECT;
891     keyRequestTimer.SetAttribute(err);
892     return err;
893 }
894 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)895 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
896         Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
897     Mutex::Autolock autoLock(mLock);
898     EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
899 
900     INIT_CHECK();
901 
902     DrmSessionManager::Instance()->useSession(sessionId);
903 
904     status_t err = UNKNOWN_ERROR;
905 
906     Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
907             toHidlVec(response),
908             [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
909                 if (status == Status::OK) {
910                     keySetId = toVector(hKeySetId);
911                 }
912                 err = toStatusT(status);
913             }
914         );
915     err = hResult.isOk() ? err : DEAD_OBJECT;
916     keyResponseTimer.SetAttribute(err);
917     return err;
918 }
919 
removeKeys(Vector<uint8_t> const & keySetId)920 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
921     Mutex::Autolock autoLock(mLock);
922     INIT_CHECK();
923 
924     Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
925     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
926 }
927 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)928 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
929         Vector<uint8_t> const &keySetId) {
930     Mutex::Autolock autoLock(mLock);
931     INIT_CHECK();
932 
933     DrmSessionManager::Instance()->useSession(sessionId);
934 
935     Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
936             toHidlVec(keySetId));
937     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
938 }
939 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const940 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
941         KeyedVector<String8, String8> &infoMap) const {
942     Mutex::Autolock autoLock(mLock);
943     INIT_CHECK();
944 
945     DrmSessionManager::Instance()->useSession(sessionId);
946 
947     ::KeyedVector hInfoMap;
948 
949     status_t err = UNKNOWN_ERROR;
950 
951     Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
952             [&](Status status, const hidl_vec<KeyValue>& map) {
953                 if (status == Status::OK) {
954                     infoMap = toKeyedVector(map);
955                 }
956                 err = toStatusT(status);
957             }
958         );
959 
960     return hResult.isOk() ? err : DEAD_OBJECT;
961 }
962 
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)963 status_t DrmHal::getProvisionRequest(String8 const &certType,
964         String8 const &certAuthority, Vector<uint8_t> &request,
965         String8 &defaultUrl) {
966     Mutex::Autolock autoLock(mLock);
967     INIT_CHECK();
968 
969     status_t err = UNKNOWN_ERROR;
970     Return<void> hResult;
971 
972     if (mPluginV1_2 != NULL) {
973         Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
974                 toHidlString(certType), toHidlString(certAuthority),
975                 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
976                         const hidl_string& hDefaultUrl) {
977                     if (status == Status_V1_2::OK) {
978                         request = toVector(hRequest);
979                         defaultUrl = toString8(hDefaultUrl);
980                     }
981                     err = toStatusT_1_2(status);
982                 }
983             );
984     } else {
985         Return<void> hResult = mPlugin->getProvisionRequest(
986                 toHidlString(certType), toHidlString(certAuthority),
987                 [&](Status status, const hidl_vec<uint8_t>& hRequest,
988                         const hidl_string& hDefaultUrl) {
989                     if (status == Status::OK) {
990                         request = toVector(hRequest);
991                         defaultUrl = toString8(hDefaultUrl);
992                     }
993                     err = toStatusT(status);
994                 }
995             );
996     }
997 
998     err = hResult.isOk() ? err : DEAD_OBJECT;
999     mMetrics.mGetProvisionRequestCounter.Increment(err);
1000     return err;
1001 }
1002 
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)1003 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
1004         Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
1005     Mutex::Autolock autoLock(mLock);
1006     INIT_CHECK();
1007 
1008     status_t err = UNKNOWN_ERROR;
1009 
1010     Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1011             [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1012                     const hidl_vec<uint8_t>& hWrappedKey) {
1013                 if (status == Status::OK) {
1014                     certificate = toVector(hCertificate);
1015                     wrappedKey = toVector(hWrappedKey);
1016                 }
1017                 err = toStatusT(status);
1018             }
1019         );
1020 
1021     err = hResult.isOk() ? err : DEAD_OBJECT;
1022     mMetrics.mProvideProvisionResponseCounter.Increment(err);
1023     return err;
1024 }
1025 
getSecureStops(List<Vector<uint8_t>> & secureStops)1026 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
1027     Mutex::Autolock autoLock(mLock);
1028     INIT_CHECK();
1029 
1030     status_t err = UNKNOWN_ERROR;
1031 
1032     Return<void> hResult = mPlugin->getSecureStops(
1033             [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1034                 if (status == Status::OK) {
1035                     secureStops = toSecureStops(hSecureStops);
1036                 }
1037                 err = toStatusT(status);
1038             }
1039     );
1040 
1041     return hResult.isOk() ? err : DEAD_OBJECT;
1042 }
1043 
1044 
getSecureStopIds(List<Vector<uint8_t>> & secureStopIds)1045 status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1046     Mutex::Autolock autoLock(mLock);
1047 
1048     if (mInitCheck != OK) {
1049         return mInitCheck;
1050     }
1051 
1052     if (mPluginV1_1 == NULL) {
1053         return ERROR_DRM_CANNOT_HANDLE;
1054     }
1055 
1056     status_t err = UNKNOWN_ERROR;
1057 
1058     Return<void> hResult = mPluginV1_1->getSecureStopIds(
1059             [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1060                 if (status == Status::OK) {
1061                     secureStopIds = toSecureStopIds(hSecureStopIds);
1062                 }
1063                 err = toStatusT(status);
1064             }
1065     );
1066 
1067     return hResult.isOk() ? err : DEAD_OBJECT;
1068 }
1069 
1070 
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)1071 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1072     Mutex::Autolock autoLock(mLock);
1073     INIT_CHECK();
1074 
1075     status_t err = UNKNOWN_ERROR;
1076 
1077     Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1078             [&](Status status, const SecureStop& hSecureStop) {
1079                 if (status == Status::OK) {
1080                     secureStop = toVector(hSecureStop.opaqueData);
1081                 }
1082                 err = toStatusT(status);
1083             }
1084     );
1085 
1086     return hResult.isOk() ? err : DEAD_OBJECT;
1087 }
1088 
releaseSecureStops(Vector<uint8_t> const & ssRelease)1089 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1090     Mutex::Autolock autoLock(mLock);
1091     INIT_CHECK();
1092 
1093     Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1094     if (mPluginV1_1 != NULL) {
1095         SecureStopRelease secureStopRelease;
1096         secureStopRelease.opaqueData = toHidlVec(ssRelease);
1097         status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1098     } else {
1099         status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
1100     }
1101     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1102 }
1103 
removeSecureStop(Vector<uint8_t> const & ssid)1104 status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1105     Mutex::Autolock autoLock(mLock);
1106 
1107     if (mInitCheck != OK) {
1108         return mInitCheck;
1109     }
1110 
1111     if (mPluginV1_1 == NULL) {
1112         return ERROR_DRM_CANNOT_HANDLE;
1113     }
1114 
1115     Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1116     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1117 }
1118 
removeAllSecureStops()1119 status_t DrmHal::removeAllSecureStops() {
1120     Mutex::Autolock autoLock(mLock);
1121     INIT_CHECK();
1122 
1123     Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1124     if (mPluginV1_1 != NULL) {
1125         status = mPluginV1_1->removeAllSecureStops();
1126     } else {
1127         status = mPlugin->releaseAllSecureStops();
1128     }
1129     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1130 }
1131 
getHdcpLevels(DrmPlugin::HdcpLevel * connected,DrmPlugin::HdcpLevel * max) const1132 status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1133             DrmPlugin::HdcpLevel *max) const {
1134     Mutex::Autolock autoLock(mLock);
1135     INIT_CHECK();
1136 
1137     if (connected == NULL || max == NULL) {
1138         return BAD_VALUE;
1139     }
1140     status_t err = UNKNOWN_ERROR;
1141 
1142     *connected = DrmPlugin::kHdcpLevelUnknown;
1143     *max = DrmPlugin::kHdcpLevelUnknown;
1144 
1145     Return<void> hResult;
1146     if (mPluginV1_2 != NULL) {
1147         hResult = mPluginV1_2->getHdcpLevels_1_2(
1148                 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1149                     if (status == Status_V1_2::OK) {
1150                         *connected = toHdcpLevel(hConnected);
1151                         *max = toHdcpLevel(hMax);
1152                     }
1153                     err = toStatusT_1_2(status);
1154                 });
1155     } else if (mPluginV1_1 != NULL) {
1156         hResult = mPluginV1_1->getHdcpLevels(
1157                 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1158                     if (status == Status::OK) {
1159                         *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1160                         *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1161                     }
1162                     err = toStatusT(status);
1163                 });
1164     } else {
1165         return ERROR_DRM_CANNOT_HANDLE;
1166     }
1167 
1168     return hResult.isOk() ? err : DEAD_OBJECT;
1169 }
1170 
getNumberOfSessions(uint32_t * open,uint32_t * max) const1171 status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1172     Mutex::Autolock autoLock(mLock);
1173     INIT_CHECK();
1174 
1175     if (open == NULL || max == NULL) {
1176         return BAD_VALUE;
1177     }
1178     status_t err = UNKNOWN_ERROR;
1179 
1180     *open = 0;
1181     *max = 0;
1182 
1183     if (mPluginV1_1 == NULL) {
1184         return ERROR_DRM_CANNOT_HANDLE;
1185     }
1186 
1187     Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1188             [&](Status status, uint32_t hOpen, uint32_t hMax) {
1189                 if (status == Status::OK) {
1190                     *open = hOpen;
1191                     *max = hMax;
1192                 }
1193                 err = toStatusT(status);
1194             }
1195     );
1196 
1197     return hResult.isOk() ? err : DEAD_OBJECT;
1198 }
1199 
getSecurityLevel(Vector<uint8_t> const & sessionId,DrmPlugin::SecurityLevel * level) const1200 status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1201         DrmPlugin::SecurityLevel *level) const {
1202     Mutex::Autolock autoLock(mLock);
1203     INIT_CHECK();
1204 
1205     if (level == NULL) {
1206         return BAD_VALUE;
1207     }
1208     status_t err = UNKNOWN_ERROR;
1209 
1210     if (mPluginV1_1 == NULL) {
1211         return ERROR_DRM_CANNOT_HANDLE;
1212     }
1213 
1214     *level = DrmPlugin::kSecurityLevelUnknown;
1215 
1216     Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1217             [&](Status status, SecurityLevel hLevel) {
1218                 if (status == Status::OK) {
1219                     *level = toSecurityLevel(hLevel);
1220                 }
1221                 err = toStatusT(status);
1222             }
1223     );
1224 
1225     return hResult.isOk() ? err : DEAD_OBJECT;
1226 }
1227 
getOfflineLicenseKeySetIds(List<Vector<uint8_t>> & keySetIds) const1228 status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1229     Mutex::Autolock autoLock(mLock);
1230 
1231     if (mInitCheck != OK) {
1232         return mInitCheck;
1233     }
1234 
1235     if (mPluginV1_2 == NULL) {
1236         return ERROR_UNSUPPORTED;
1237     }
1238 
1239     status_t err = UNKNOWN_ERROR;
1240 
1241     Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1242             [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1243                 if (status == Status::OK) {
1244                     keySetIds = toKeySetIds(hKeySetIds);
1245                 }
1246                 err = toStatusT(status);
1247             }
1248     );
1249 
1250     return hResult.isOk() ? err : DEAD_OBJECT;
1251 }
1252 
removeOfflineLicense(Vector<uint8_t> const & keySetId)1253 status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1254     Mutex::Autolock autoLock(mLock);
1255 
1256     if (mInitCheck != OK) {
1257         return mInitCheck;
1258     }
1259 
1260     if (mPluginV1_2 == NULL) {
1261         return ERROR_UNSUPPORTED;
1262     }
1263 
1264     Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1265     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1266 }
1267 
getOfflineLicenseState(Vector<uint8_t> const & keySetId,DrmPlugin::OfflineLicenseState * licenseState) const1268 status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1269         DrmPlugin::OfflineLicenseState *licenseState) const {
1270     Mutex::Autolock autoLock(mLock);
1271 
1272     if (mInitCheck != OK) {
1273         return mInitCheck;
1274     }
1275 
1276     if (mPluginV1_2 == NULL) {
1277         return ERROR_UNSUPPORTED;
1278     }
1279     *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1280 
1281     status_t err = UNKNOWN_ERROR;
1282 
1283     Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1284             [&](Status status, OfflineLicenseState hLicenseState) {
1285                 if (status == Status::OK) {
1286                     *licenseState = toOfflineLicenseState(hLicenseState);
1287                 }
1288                 err = toStatusT(status);
1289             }
1290     );
1291 
1292     return hResult.isOk() ? err : DEAD_OBJECT;
1293 }
1294 
getPropertyString(String8 const & name,String8 & value) const1295 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1296     Mutex::Autolock autoLock(mLock);
1297     return getPropertyStringInternal(name, value);
1298 }
1299 
getPropertyStringInternal(String8 const & name,String8 & value) const1300 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1301     // This function is internal to the class and should only be called while
1302     // mLock is already held.
1303     INIT_CHECK();
1304 
1305     status_t err = UNKNOWN_ERROR;
1306 
1307     Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1308             [&](Status status, const hidl_string& hValue) {
1309                 if (status == Status::OK) {
1310                     value = toString8(hValue);
1311                 }
1312                 err = toStatusT(status);
1313             }
1314     );
1315 
1316     return hResult.isOk() ? err : DEAD_OBJECT;
1317 }
1318 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const1319 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1320     Mutex::Autolock autoLock(mLock);
1321     return getPropertyByteArrayInternal(name, value);
1322 }
1323 
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const1324 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1325     // This function is internal to the class and should only be called while
1326     // mLock is already held.
1327     INIT_CHECK();
1328 
1329     status_t err = UNKNOWN_ERROR;
1330 
1331     Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1332             [&](Status status, const hidl_vec<uint8_t>& hValue) {
1333                 if (status == Status::OK) {
1334                     value = toVector(hValue);
1335                 }
1336                 err = toStatusT(status);
1337             }
1338     );
1339 
1340     err = hResult.isOk() ? err : DEAD_OBJECT;
1341     if (name == kPropertyDeviceUniqueId) {
1342         mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1343     }
1344     return err;
1345 }
1346 
setPropertyString(String8 const & name,String8 const & value) const1347 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1348     Mutex::Autolock autoLock(mLock);
1349     INIT_CHECK();
1350 
1351     Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
1352             toHidlString(value));
1353     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1354 }
1355 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const1356 status_t DrmHal::setPropertyByteArray(String8 const &name,
1357                                    Vector<uint8_t> const &value ) const {
1358     Mutex::Autolock autoLock(mLock);
1359     INIT_CHECK();
1360 
1361     Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
1362             toHidlVec(value));
1363     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1364 }
1365 
getMetrics(PersistableBundle * metrics)1366 status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1367     if (metrics == nullptr) {
1368         return UNEXPECTED_NULL;
1369     }
1370     mMetrics.Export(metrics);
1371 
1372     // Append vendor metrics if they are supported.
1373     if (mPluginV1_1 != NULL) {
1374         String8 vendor;
1375         String8 description;
1376         if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1377             || vendor.isEmpty()) {
1378           ALOGE("Get vendor failed or is empty");
1379           vendor = "NONE";
1380         }
1381         if (getPropertyStringInternal(String8("description"), description) != OK
1382             || description.isEmpty()) {
1383           ALOGE("Get description failed or is empty.");
1384           description = "NONE";
1385         }
1386         vendor += ".";
1387         vendor += description;
1388 
1389         hidl_vec<DrmMetricGroup> pluginMetrics;
1390         status_t err = UNKNOWN_ERROR;
1391 
1392         Return<void> status = mPluginV1_1->getMetrics(
1393                 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1394                     if (status != Status::OK) {
1395                       ALOGV("Error getting plugin metrics: %d", status);
1396                     } else {
1397                         PersistableBundle pluginBundle;
1398                         if (MediaDrmMetrics::HidlMetricsToBundle(
1399                                 pluginMetrics, &pluginBundle) == OK) {
1400                             metrics->putPersistableBundle(String16(vendor), pluginBundle);
1401                         }
1402                     }
1403                     err = toStatusT(status);
1404                 });
1405         return status.isOk() ? err : DEAD_OBJECT;
1406     }
1407 
1408     return OK;
1409 }
1410 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1411 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1412                                  String8 const &algorithm) {
1413     Mutex::Autolock autoLock(mLock);
1414     INIT_CHECK();
1415 
1416     DrmSessionManager::Instance()->useSession(sessionId);
1417 
1418     Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1419             toHidlString(algorithm));
1420     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1421 }
1422 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1423 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1424                               String8 const &algorithm) {
1425     Mutex::Autolock autoLock(mLock);
1426     INIT_CHECK();
1427 
1428     DrmSessionManager::Instance()->useSession(sessionId);
1429 
1430     Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1431             toHidlString(algorithm));
1432     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1433 }
1434 
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)1435 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
1436         Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1437         Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1438     Mutex::Autolock autoLock(mLock);
1439     INIT_CHECK();
1440 
1441     DrmSessionManager::Instance()->useSession(sessionId);
1442 
1443     status_t err = UNKNOWN_ERROR;
1444 
1445     Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1446             toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1447             [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1448                 if (status == Status::OK) {
1449                     output = toVector(hOutput);
1450                 }
1451                 err = toStatusT(status);
1452             }
1453     );
1454 
1455     return hResult.isOk() ? err : DEAD_OBJECT;
1456 }
1457 
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)1458 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
1459         Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1460         Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1461     Mutex::Autolock autoLock(mLock);
1462     INIT_CHECK();
1463 
1464     DrmSessionManager::Instance()->useSession(sessionId);
1465 
1466     status_t  err = UNKNOWN_ERROR;
1467 
1468     Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1469             toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1470             [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1471                 if (status == Status::OK) {
1472                     output = toVector(hOutput);
1473                 }
1474                 err = toStatusT(status);
1475             }
1476     );
1477 
1478     return hResult.isOk() ? err : DEAD_OBJECT;
1479 }
1480 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)1481 status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
1482         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1483         Vector<uint8_t> &signature) {
1484     Mutex::Autolock autoLock(mLock);
1485     INIT_CHECK();
1486 
1487     DrmSessionManager::Instance()->useSession(sessionId);
1488 
1489     status_t err = UNKNOWN_ERROR;
1490 
1491     Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1492             toHidlVec(keyId), toHidlVec(message),
1493             [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
1494                 if (status == Status::OK) {
1495                     signature = toVector(hSignature);
1496                 }
1497                 err = toStatusT(status);
1498             }
1499     );
1500 
1501     return hResult.isOk() ? err : DEAD_OBJECT;
1502 }
1503 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)1504 status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
1505         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1506         Vector<uint8_t> const &signature, bool &match) {
1507     Mutex::Autolock autoLock(mLock);
1508     INIT_CHECK();
1509 
1510     DrmSessionManager::Instance()->useSession(sessionId);
1511 
1512     status_t err = UNKNOWN_ERROR;
1513 
1514     Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1515             toHidlVec(message), toHidlVec(signature),
1516             [&](Status status, bool hMatch) {
1517                 if (status == Status::OK) {
1518                     match = hMatch;
1519                 } else {
1520                     match = false;
1521                 }
1522                 err = toStatusT(status);
1523             }
1524     );
1525 
1526     return hResult.isOk() ? err : DEAD_OBJECT;
1527 }
1528 
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)1529 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
1530         String8 const &algorithm, Vector<uint8_t> const &message,
1531         Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
1532     Mutex::Autolock autoLock(mLock);
1533     INIT_CHECK();
1534 
1535     if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1536         return -EPERM;
1537     }
1538 
1539     DrmSessionManager::Instance()->useSession(sessionId);
1540 
1541     status_t err = UNKNOWN_ERROR;
1542 
1543     Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1544             toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1545             [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1546                 if (status == Status::OK) {
1547                     signature = toVector(hSignature);
1548                 }
1549                 err = toStatusT(status);
1550             }
1551         );
1552 
1553     return hResult.isOk() ? err : DEAD_OBJECT;
1554 }
1555 
binderDied(const wp<IBinder> & the_late_who __unused)1556 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1557 {
1558     cleanup();
1559 }
1560 
writeByteArray(Parcel & obj,hidl_vec<uint8_t> const & vec)1561 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1562 {
1563     if (vec.size()) {
1564         obj.writeInt32(vec.size());
1565         obj.write(vec.data(), vec.size());
1566     } else {
1567         obj.writeInt32(0);
1568     }
1569 }
1570 
reportFrameworkMetrics() const1571 void DrmHal::reportFrameworkMetrics() const
1572 {
1573     std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1574     item->generateSessionID();
1575     item->setPkgName(mMetrics.GetAppPackageName().c_str());
1576     String8 vendor;
1577     String8 description;
1578     status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1579     if (result != OK) {
1580         ALOGE("Failed to get vendor from drm plugin: %d", result);
1581     } else {
1582         item->setCString("vendor", vendor.c_str());
1583     }
1584     result = getPropertyStringInternal(String8("description"), description);
1585     if (result != OK) {
1586         ALOGE("Failed to get description from drm plugin: %d", result);
1587     } else {
1588         item->setCString("description", description.c_str());
1589     }
1590 
1591     std::string serializedMetrics;
1592     result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1593     if (result != OK) {
1594         ALOGE("Failed to serialize framework metrics: %d", result);
1595     }
1596     std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1597                                                         serializedMetrics.size());
1598     if (!b64EncodedMetrics.empty()) {
1599         item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
1600     }
1601     if (!item->selfrecord()) {
1602         ALOGE("Failed to self record framework metrics");
1603     }
1604 }
1605 
reportPluginMetrics() const1606 void DrmHal::reportPluginMetrics() const
1607 {
1608     Vector<uint8_t> metricsVector;
1609     String8 vendor;
1610     String8 description;
1611     if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1612             getPropertyStringInternal(String8("description"), description) == OK &&
1613             getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1614         std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1615                                                         metricsVector.size());
1616         status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1617                                                        description, mAppPackageName);
1618         if (res != OK) {
1619             ALOGE("Metrics were retrieved but could not be reported: %d", res);
1620         }
1621     }
1622 }
1623 
1624 }  // namespace android
1625