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