Home | History | Annotate | Download | only in libmediadrm
      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>
     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 
    100 static inline int getCallingPid() {
    101     return IPCThreadState::self()->getCallingPid();
    102 }
    103 
    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 
    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 
    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 
    123 static String8 toString8(const hidl_string &string) {
    124     return String8(string.c_str());
    125 }
    126 
    127 static hidl_string toHidlString(const String8& string) {
    128     return hidl_string(string.string());
    129 }
    130 
    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 
    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 
    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 
    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 }
    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 
    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 
    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 
    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 
    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 
    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 
    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 {
    302     explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
    303 
    304     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:
    319     virtual ~DrmSessionClient() {}
    320 
    321 private:
    322     wp<DrmHal> mDrm;
    323 
    324     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
    325 };
    326 
    327 DrmHal::DrmHal()
    328    : mDrmSessionClient(new DrmSessionClient(this)),
    329      mFactories(makeDrmFactories()),
    330      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
    331 }
    332 
    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 
    344 DrmHal::~DrmHal() {
    345     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
    346 }
    347 
    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 
    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 
    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 
    445 status_t DrmHal::initCheck() const {
    446     return mInitCheck;
    447 }
    448 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    687 status_t DrmHal::destroyPlugin() {
    688     cleanup();
    689     return OK;
    690 }
    691 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    940 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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1132 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 
   1171 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 
   1200 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 
   1228 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 
   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 
   1268 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 
   1295 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
   1296     Mutex::Autolock autoLock(mLock);
   1297     return getPropertyStringInternal(name, value);
   1298 }
   1299 
   1300 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 
   1319 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
   1320     Mutex::Autolock autoLock(mLock);
   1321     return getPropertyByteArrayInternal(name, value);
   1322 }
   1323 
   1324 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 
   1347 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 
   1356 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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1556 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
   1557 {
   1558     cleanup();
   1559 }
   1560 
   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 
   1571 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 
   1606 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