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