DrmHal.cpp revision 59bc3fa914467f37c32aea1963e9354355b244e7
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/PluginMetricsReporting.h>
34#include <media/drm/DrmAPI.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AString.h>
37#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/MediaErrors.h>
39
40using drm::V1_0::KeyedVector;
41using drm::V1_0::KeyStatusType;
42using drm::V1_0::KeyType;
43using drm::V1_0::KeyValue;
44using drm::V1_1::HdcpLevel;;
45using drm::V1_0::SecureStop;
46using drm::V1_1::SecurityLevel;
47using drm::V1_0::Status;
48using ::android::hardware::hidl_array;
49using ::android::hardware::hidl_string;
50using ::android::hardware::hidl_vec;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
53using ::android::hidl::manager::V1_0::IServiceManager;
54using ::android::sp;
55
56namespace android {
57
58#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
59
60static inline int getCallingPid() {
61    return IPCThreadState::self()->getCallingPid();
62}
63
64static 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
71static 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
77static 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
83static String8 toString8(const hidl_string &string) {
84    return String8(string.c_str());
85}
86
87static hidl_string toHidlString(const String8& string) {
88    return hidl_string(string.string());
89}
90
91static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
92    switch(level) {
93    case SecurityLevel::SW_SECURE_CRYPTO:
94        return DrmPlugin::kSecurityLevelSwSecureCrypto;
95    case SecurityLevel::SW_SECURE_DECODE:
96        return DrmPlugin::kSecurityLevelSwSecureDecode;
97    case SecurityLevel::HW_SECURE_CRYPTO:
98        return DrmPlugin::kSecurityLevelHwSecureCrypto;
99    case SecurityLevel::HW_SECURE_DECODE:
100        return DrmPlugin::kSecurityLevelHwSecureDecode;
101    case SecurityLevel::HW_SECURE_ALL:
102        return DrmPlugin::kSecurityLevelHwSecureAll;
103    default:
104        return DrmPlugin::kSecurityLevelUnknown;
105    }
106}
107
108static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
109    switch(level) {
110    case HdcpLevel::HDCP_NONE:
111        return DrmPlugin::kHdcpNone;
112    case HdcpLevel::HDCP_V1:
113        return DrmPlugin::kHdcpV1;
114    case HdcpLevel::HDCP_V2:
115        return DrmPlugin::kHdcpV2;
116    case HdcpLevel::HDCP_V2_1:
117        return DrmPlugin::kHdcpV2_1;
118    case HdcpLevel::HDCP_V2_2:
119        return DrmPlugin::kHdcpV2_2;
120    case HdcpLevel::HDCP_NO_OUTPUT:
121        return DrmPlugin::kHdcpNoOutput;
122    default:
123        return DrmPlugin::kHdcpLevelUnknown;
124    }
125}
126
127
128static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
129        keyedVector) {
130    std::vector<KeyValue> stdKeyedVector;
131    for (size_t i = 0; i < keyedVector.size(); i++) {
132        KeyValue keyValue;
133        keyValue.key = toHidlString(keyedVector.keyAt(i));
134        keyValue.value = toHidlString(keyedVector.valueAt(i));
135        stdKeyedVector.push_back(keyValue);
136    }
137    return ::KeyedVector(stdKeyedVector);
138}
139
140static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
141        hKeyedVector) {
142    KeyedVector<String8, String8> keyedVector;
143    for (size_t i = 0; i < hKeyedVector.size(); i++) {
144        keyedVector.add(toString8(hKeyedVector[i].key),
145                toString8(hKeyedVector[i].value));
146    }
147    return keyedVector;
148}
149
150static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
151        hSecureStops) {
152    List<Vector<uint8_t>> secureStops;
153    for (size_t i = 0; i < hSecureStops.size(); i++) {
154        secureStops.push_back(toVector(hSecureStops[i].opaqueData));
155    }
156    return secureStops;
157}
158
159static status_t toStatusT(Status status) {
160    switch (status) {
161    case Status::OK:
162        return OK;
163        break;
164    case Status::ERROR_DRM_NO_LICENSE:
165        return ERROR_DRM_NO_LICENSE;
166        break;
167    case Status::ERROR_DRM_LICENSE_EXPIRED:
168        return ERROR_DRM_LICENSE_EXPIRED;
169        break;
170    case Status::ERROR_DRM_SESSION_NOT_OPENED:
171        return ERROR_DRM_SESSION_NOT_OPENED;
172        break;
173    case Status::ERROR_DRM_CANNOT_HANDLE:
174        return ERROR_DRM_CANNOT_HANDLE;
175        break;
176    case Status::ERROR_DRM_INVALID_STATE:
177        return ERROR_DRM_TAMPER_DETECTED;
178        break;
179    case Status::BAD_VALUE:
180        return BAD_VALUE;
181        break;
182    case Status::ERROR_DRM_NOT_PROVISIONED:
183        return ERROR_DRM_NOT_PROVISIONED;
184        break;
185    case Status::ERROR_DRM_RESOURCE_BUSY:
186        return ERROR_DRM_RESOURCE_BUSY;
187        break;
188    case Status::ERROR_DRM_DEVICE_REVOKED:
189        return ERROR_DRM_DEVICE_REVOKED;
190        break;
191    case Status::ERROR_DRM_UNKNOWN:
192    default:
193        return ERROR_DRM_UNKNOWN;
194        break;
195    }
196}
197
198
199Mutex DrmHal::mLock;
200
201struct DrmSessionClient : public DrmSessionClientInterface {
202    explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
203
204    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
205        sp<DrmHal> drm = mDrm.promote();
206        if (drm == NULL) {
207            return true;
208        }
209        status_t err = drm->closeSession(sessionId);
210        if (err != OK) {
211            return false;
212        }
213        drm->sendEvent(EventType::SESSION_RECLAIMED,
214                toHidlVec(sessionId), hidl_vec<uint8_t>());
215        return true;
216    }
217
218protected:
219    virtual ~DrmSessionClient() {}
220
221private:
222    wp<DrmHal> mDrm;
223
224    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
225};
226
227DrmHal::DrmHal()
228   : mDrmSessionClient(new DrmSessionClient(this)),
229     mFactories(makeDrmFactories()),
230     mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
231}
232
233void DrmHal::closeOpenSessions() {
234    if (mPlugin != NULL) {
235        for (size_t i = 0; i < mOpenSessions.size(); i++) {
236            mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
237            DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
238        }
239    }
240    mOpenSessions.clear();
241}
242
243DrmHal::~DrmHal() {
244    closeOpenSessions();
245    DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
246}
247
248Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
249    Vector<sp<IDrmFactory>> factories;
250
251    auto manager = hardware::defaultServiceManager();
252
253    if (manager != NULL) {
254        manager->listByInterface(IDrmFactory::descriptor,
255                [&factories](const hidl_vec<hidl_string> &registered) {
256                    for (const auto &instance : registered) {
257                        auto factory = IDrmFactory::getService(instance);
258                        if (factory != NULL) {
259                            factories.push_back(factory);
260                            ALOGI("makeDrmFactories: factory instance %s is %s",
261                                    instance.c_str(),
262                                    factory->isRemote() ? "Remote" : "Not Remote");
263                        }
264                    }
265                }
266            );
267    }
268
269    if (factories.size() == 0) {
270        // must be in passthrough mode, load the default passthrough service
271        auto passthrough = IDrmFactory::getService();
272        if (passthrough != NULL) {
273            ALOGI("makeDrmFactories: using default drm instance");
274            factories.push_back(passthrough);
275        } else {
276            ALOGE("Failed to find any drm factories");
277        }
278    }
279    return factories;
280}
281
282sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
283        const uint8_t uuid[16], const String8& appPackageName) {
284
285    sp<IDrmPlugin> plugin;
286    Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
287            [&](Status status, const sp<IDrmPlugin>& hPlugin) {
288                if (status != Status::OK) {
289                    ALOGE("Failed to make drm plugin");
290                    return;
291                }
292                plugin = hPlugin;
293            }
294        );
295
296    if (!hResult.isOk()) {
297        ALOGE("createPlugin remote call failed");
298    }
299
300    return plugin;
301}
302
303status_t DrmHal::initCheck() const {
304    return mInitCheck;
305}
306
307status_t DrmHal::setListener(const sp<IDrmClient>& listener)
308{
309    Mutex::Autolock lock(mEventLock);
310    if (mListener != NULL){
311        IInterface::asBinder(mListener)->unlinkToDeath(this);
312    }
313    if (listener != NULL) {
314        IInterface::asBinder(listener)->linkToDeath(this);
315    }
316    mListener = listener;
317    return NO_ERROR;
318}
319
320Return<void> DrmHal::sendEvent(EventType hEventType,
321        const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
322
323    mEventLock.lock();
324    sp<IDrmClient> listener = mListener;
325    mEventLock.unlock();
326
327    if (listener != NULL) {
328        Parcel obj;
329        writeByteArray(obj, sessionId);
330        writeByteArray(obj, data);
331
332        Mutex::Autolock lock(mNotifyLock);
333        DrmPlugin::EventType eventType;
334        switch(hEventType) {
335        case EventType::PROVISION_REQUIRED:
336            eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
337            break;
338        case EventType::KEY_NEEDED:
339            eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
340            break;
341        case EventType::KEY_EXPIRED:
342            eventType = DrmPlugin::kDrmPluginEventKeyExpired;
343            break;
344        case EventType::VENDOR_DEFINED:
345            eventType = DrmPlugin::kDrmPluginEventVendorDefined;
346            break;
347        case EventType::SESSION_RECLAIMED:
348            eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
349            break;
350        default:
351            return Void();
352        }
353        listener->notify(eventType, 0, &obj);
354    }
355    return Void();
356}
357
358Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
359        int64_t expiryTimeInMS) {
360
361    mEventLock.lock();
362    sp<IDrmClient> listener = mListener;
363    mEventLock.unlock();
364
365    if (listener != NULL) {
366        Parcel obj;
367        writeByteArray(obj, sessionId);
368        obj.writeInt64(expiryTimeInMS);
369
370        Mutex::Autolock lock(mNotifyLock);
371        listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
372    }
373    return Void();
374}
375
376Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
377        const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
378
379    mEventLock.lock();
380    sp<IDrmClient> listener = mListener;
381    mEventLock.unlock();
382
383    if (listener != NULL) {
384        Parcel obj;
385        writeByteArray(obj, sessionId);
386
387        size_t nKeys = keyStatusList.size();
388        obj.writeInt32(nKeys);
389        for (size_t i = 0; i < nKeys; ++i) {
390            const KeyStatus &keyStatus = keyStatusList[i];
391            writeByteArray(obj, keyStatus.keyId);
392            uint32_t type;
393            switch(keyStatus.type) {
394            case KeyStatusType::USABLE:
395                type = DrmPlugin::kKeyStatusType_Usable;
396                break;
397            case KeyStatusType::EXPIRED:
398                type = DrmPlugin::kKeyStatusType_Expired;
399                break;
400            case KeyStatusType::OUTPUTNOTALLOWED:
401                type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
402                break;
403            case KeyStatusType::STATUSPENDING:
404                type = DrmPlugin::kKeyStatusType_StatusPending;
405                break;
406            case KeyStatusType::INTERNALERROR:
407            default:
408                type = DrmPlugin::kKeyStatusType_InternalError;
409                break;
410            }
411            obj.writeInt32(type);
412        }
413        obj.writeInt32(hasNewUsableKey);
414
415        Mutex::Autolock lock(mNotifyLock);
416        listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
417    }
418    return Void();
419}
420
421bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
422    Mutex::Autolock autoLock(mLock);
423
424    for (size_t i = 0; i < mFactories.size(); i++) {
425        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
426            if (mimeType != "") {
427                if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
428                    return true;
429                }
430            } else {
431                return true;
432            }
433        }
434    }
435    return false;
436}
437
438status_t DrmHal::createPlugin(const uint8_t uuid[16],
439        const String8& appPackageName) {
440    Mutex::Autolock autoLock(mLock);
441
442    for (size_t i = 0; i < mFactories.size(); i++) {
443        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
444            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
445            mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
446        }
447    }
448
449    if (mPlugin == NULL) {
450        mInitCheck = ERROR_UNSUPPORTED;
451    } else {
452        if (!mPlugin->setListener(this).isOk()) {
453            mInitCheck = DEAD_OBJECT;
454        } else {
455            mInitCheck = OK;
456        }
457    }
458
459    return mInitCheck;
460}
461
462status_t DrmHal::destroyPlugin() {
463    Mutex::Autolock autoLock(mLock);
464    INIT_CHECK();
465
466    closeOpenSessions();
467    reportMetrics();
468    setListener(NULL);
469    mInitCheck = NO_INIT;
470
471    if (mPlugin != NULL) {
472        if (!mPlugin->setListener(NULL).isOk()) {
473            mInitCheck = DEAD_OBJECT;
474        }
475    }
476    mPlugin.clear();
477    return OK;
478}
479
480status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
481    Mutex::Autolock autoLock(mLock);
482    INIT_CHECK();
483
484    status_t  err = UNKNOWN_ERROR;
485
486    bool retry = true;
487    do {
488        hidl_vec<uint8_t> hSessionId;
489
490        Return<void> hResult = mPlugin->openSession(
491                [&](Status status, const hidl_vec<uint8_t>& id) {
492                    if (status == Status::OK) {
493                        sessionId = toVector(id);
494                    }
495                    err = toStatusT(status);
496                }
497            );
498
499        if (!hResult.isOk()) {
500            err = DEAD_OBJECT;
501        }
502
503        if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
504            mLock.unlock();
505            // reclaimSession may call back to closeSession, since mLock is
506            // shared between Drm instances, we should unlock here to avoid
507            // deadlock.
508            retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
509            mLock.lock();
510        } else {
511            retry = false;
512        }
513    } while (retry);
514
515    if (err == OK) {
516        DrmSessionManager::Instance()->addSession(getCallingPid(),
517                mDrmSessionClient, sessionId);
518        mOpenSessions.push(sessionId);
519    }
520    return err;
521}
522
523status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
524    Mutex::Autolock autoLock(mLock);
525    INIT_CHECK();
526
527    Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
528    if (status.isOk()) {
529        if (status == Status::OK) {
530            DrmSessionManager::Instance()->removeSession(sessionId);
531            for (size_t i = 0; i < mOpenSessions.size(); i++) {
532                if (mOpenSessions[i] == sessionId) {
533                    mOpenSessions.removeAt(i);
534                    break;
535                }
536            }
537        }
538        reportMetrics();
539        return toStatusT(status);
540    }
541    return DEAD_OBJECT;
542}
543
544status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
545        Vector<uint8_t> const &initData, String8 const &mimeType,
546        DrmPlugin::KeyType keyType, KeyedVector<String8,
547        String8> const &optionalParameters, Vector<uint8_t> &request,
548        String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
549    Mutex::Autolock autoLock(mLock);
550    INIT_CHECK();
551
552    DrmSessionManager::Instance()->useSession(sessionId);
553
554    KeyType hKeyType;
555    if (keyType == DrmPlugin::kKeyType_Streaming) {
556        hKeyType = KeyType::STREAMING;
557    } else if (keyType == DrmPlugin::kKeyType_Offline) {
558        hKeyType = KeyType::OFFLINE;
559    } else if (keyType == DrmPlugin::kKeyType_Release) {
560        hKeyType = KeyType::RELEASE;
561    } else {
562        return BAD_VALUE;
563    }
564
565    ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
566
567    status_t err = UNKNOWN_ERROR;
568
569    if (mPluginV1_1 != NULL) {
570        Return<void> hResult =
571            mPluginV1_1->getKeyRequest_1_1(
572                toHidlVec(sessionId), toHidlVec(initData),
573                toHidlString(mimeType), hKeyType, hOptionalParameters,
574                [&](Status status, const hidl_vec<uint8_t>& hRequest,
575                    drm::V1_1::KeyRequestType hKeyRequestType,
576                    const hidl_string& hDefaultUrl) {
577
578            if (status == Status::OK) {
579                request = toVector(hRequest);
580                defaultUrl = toString8(hDefaultUrl);
581
582                switch (hKeyRequestType) {
583                    case drm::V1_1::KeyRequestType::INITIAL:
584                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
585                        break;
586                    case drm::V1_1::KeyRequestType::RENEWAL:
587                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
588                        break;
589                    case drm::V1_1::KeyRequestType::RELEASE:
590                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
591                        break;
592                    case drm::V1_1::KeyRequestType::NONE:
593                        *keyRequestType = DrmPlugin::kKeyRequestType_None;
594                        break;
595                    case drm::V1_1::KeyRequestType::UPDATE:
596                        *keyRequestType = DrmPlugin::kKeyRequestType_Update;
597                        break;
598                    default:
599                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
600                        break;
601                }
602                err = toStatusT(status);
603            }
604        });
605        return hResult.isOk() ? err : DEAD_OBJECT;
606    }
607
608    Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
609            toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
610            [&](Status status, const hidl_vec<uint8_t>& hRequest,
611                    drm::V1_0::KeyRequestType hKeyRequestType,
612                    const hidl_string& hDefaultUrl) {
613
614                if (status == Status::OK) {
615                    request = toVector(hRequest);
616                    defaultUrl = toString8(hDefaultUrl);
617
618                    switch (hKeyRequestType) {
619                    case drm::V1_0::KeyRequestType::INITIAL:
620                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
621                        break;
622                    case drm::V1_0::KeyRequestType::RENEWAL:
623                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
624                        break;
625                    case drm::V1_0::KeyRequestType::RELEASE:
626                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
627                        break;
628                    default:
629                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
630                        break;
631                    }
632                    err = toStatusT(status);
633                }
634            });
635
636    return hResult.isOk() ? err : DEAD_OBJECT;
637}
638
639status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
640        Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
641    Mutex::Autolock autoLock(mLock);
642    INIT_CHECK();
643
644    DrmSessionManager::Instance()->useSession(sessionId);
645
646    status_t err = UNKNOWN_ERROR;
647
648    Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
649            toHidlVec(response),
650            [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
651                if (status == Status::OK) {
652                    keySetId = toVector(hKeySetId);
653                }
654                err = toStatusT(status);
655            }
656        );
657
658    return hResult.isOk() ? err : DEAD_OBJECT;
659}
660
661status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
662    Mutex::Autolock autoLock(mLock);
663    INIT_CHECK();
664
665    return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
666}
667
668status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
669        Vector<uint8_t> const &keySetId) {
670    Mutex::Autolock autoLock(mLock);
671    INIT_CHECK();
672
673    DrmSessionManager::Instance()->useSession(sessionId);
674
675    return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
676                    toHidlVec(keySetId)));
677}
678
679status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
680        KeyedVector<String8, String8> &infoMap) const {
681    Mutex::Autolock autoLock(mLock);
682    INIT_CHECK();
683
684    DrmSessionManager::Instance()->useSession(sessionId);
685
686    ::KeyedVector hInfoMap;
687
688    status_t err = UNKNOWN_ERROR;
689
690    Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
691            [&](Status status, const hidl_vec<KeyValue>& map) {
692                if (status == Status::OK) {
693                    infoMap = toKeyedVector(map);
694                }
695                err = toStatusT(status);
696            }
697        );
698
699    return hResult.isOk() ? err : DEAD_OBJECT;
700}
701
702status_t DrmHal::getProvisionRequest(String8 const &certType,
703        String8 const &certAuthority, Vector<uint8_t> &request,
704        String8 &defaultUrl) {
705    Mutex::Autolock autoLock(mLock);
706    INIT_CHECK();
707
708    status_t err = UNKNOWN_ERROR;
709
710    Return<void> hResult = mPlugin->getProvisionRequest(
711            toHidlString(certType), toHidlString(certAuthority),
712            [&](Status status, const hidl_vec<uint8_t>& hRequest,
713                    const hidl_string& hDefaultUrl) {
714                if (status == Status::OK) {
715                    request = toVector(hRequest);
716                    defaultUrl = toString8(hDefaultUrl);
717                }
718                err = toStatusT(status);
719            }
720        );
721
722    return hResult.isOk() ? err : DEAD_OBJECT;
723}
724
725status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
726        Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
727    Mutex::Autolock autoLock(mLock);
728    INIT_CHECK();
729
730    status_t err = UNKNOWN_ERROR;
731
732    Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
733            [&](Status status, const hidl_vec<uint8_t>& hCertificate,
734                    const hidl_vec<uint8_t>& hWrappedKey) {
735                if (status == Status::OK) {
736                    certificate = toVector(hCertificate);
737                    wrappedKey = toVector(hWrappedKey);
738                }
739                err = toStatusT(status);
740            }
741        );
742
743    return hResult.isOk() ? err : DEAD_OBJECT;
744}
745
746status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
747    Mutex::Autolock autoLock(mLock);
748    INIT_CHECK();
749
750    status_t err = UNKNOWN_ERROR;
751
752    Return<void> hResult = mPlugin->getSecureStops(
753            [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
754                if (status == Status::OK) {
755                    secureStops = toSecureStops(hSecureStops);
756                }
757                err = toStatusT(status);
758            }
759    );
760
761    return hResult.isOk() ? err : DEAD_OBJECT;
762}
763
764
765status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
766    Mutex::Autolock autoLock(mLock);
767    INIT_CHECK();
768
769    status_t err = UNKNOWN_ERROR;
770
771    Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
772            [&](Status status, const SecureStop& hSecureStop) {
773                if (status == Status::OK) {
774                    secureStop = toVector(hSecureStop.opaqueData);
775                }
776                err = toStatusT(status);
777            }
778    );
779
780    return hResult.isOk() ? err : DEAD_OBJECT;
781}
782
783status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
784    Mutex::Autolock autoLock(mLock);
785    INIT_CHECK();
786
787    return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
788}
789
790status_t DrmHal::releaseAllSecureStops() {
791    Mutex::Autolock autoLock(mLock);
792    INIT_CHECK();
793
794    return toStatusT(mPlugin->releaseAllSecureStops());
795}
796
797status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
798            DrmPlugin::HdcpLevel *max) const {
799    Mutex::Autolock autoLock(mLock);
800    INIT_CHECK();
801
802    if (connected == NULL || max == NULL) {
803        return BAD_VALUE;
804    }
805    status_t err = UNKNOWN_ERROR;
806
807    if (mPluginV1_1 == NULL) {
808        return ERROR_DRM_CANNOT_HANDLE;
809    }
810
811    *connected = DrmPlugin::kHdcpLevelUnknown;
812    *max = DrmPlugin::kHdcpLevelUnknown;
813
814    Return<void> hResult = mPluginV1_1->getHdcpLevels(
815            [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
816                if (status == Status::OK) {
817                    *connected = toHdcpLevel(hConnected);
818                    *max = toHdcpLevel(hMax);
819                }
820                err = toStatusT(status);
821            }
822    );
823
824    return hResult.isOk() ? err : DEAD_OBJECT;
825}
826
827status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
828    Mutex::Autolock autoLock(mLock);
829    INIT_CHECK();
830
831    if (open == NULL || max == NULL) {
832        return BAD_VALUE;
833    }
834    status_t err = UNKNOWN_ERROR;
835
836    *open = 0;
837    *max = 0;
838
839    if (mPluginV1_1 == NULL) {
840        return ERROR_DRM_CANNOT_HANDLE;
841    }
842
843    Return<void> hResult = mPluginV1_1->getNumberOfSessions(
844            [&](Status status, uint32_t hOpen, uint32_t hMax) {
845                if (status == Status::OK) {
846                    *open = hOpen;
847                    *max = hMax;
848                }
849                err = toStatusT(status);
850            }
851    );
852
853    return hResult.isOk() ? err : DEAD_OBJECT;
854}
855
856status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
857        DrmPlugin::SecurityLevel *level) const {
858    Mutex::Autolock autoLock(mLock);
859    INIT_CHECK();
860
861    if (level == NULL) {
862        return BAD_VALUE;
863    }
864    status_t err = UNKNOWN_ERROR;
865
866    if (mPluginV1_1 == NULL) {
867        return ERROR_DRM_CANNOT_HANDLE;
868    }
869
870    *level = DrmPlugin::kSecurityLevelUnknown;
871
872    Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
873            [&](Status status, SecurityLevel hLevel) {
874                if (status == Status::OK) {
875                    *level = toSecurityLevel(hLevel);
876                }
877                err = toStatusT(status);
878            }
879    );
880
881    return hResult.isOk() ? err : DEAD_OBJECT;
882}
883
884status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
885        const DrmPlugin::SecurityLevel& level) {
886    Mutex::Autolock autoLock(mLock);
887    INIT_CHECK();
888
889    if (mPluginV1_1 == NULL) {
890        return ERROR_DRM_CANNOT_HANDLE;
891    }
892
893    SecurityLevel hSecurityLevel;
894
895    switch(level) {
896    case DrmPlugin::kSecurityLevelSwSecureCrypto:
897        hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
898        break;
899    case DrmPlugin::kSecurityLevelSwSecureDecode:
900        hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
901        break;
902    case DrmPlugin::kSecurityLevelHwSecureCrypto:
903        hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
904        break;
905    case DrmPlugin::kSecurityLevelHwSecureDecode:
906        hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
907        break;
908    case DrmPlugin::kSecurityLevelHwSecureAll:
909        hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
910        break;
911    default:
912        return ERROR_DRM_CANNOT_HANDLE;
913    }
914
915    Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
916            hSecurityLevel);
917    return toStatusT(status);
918}
919
920status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
921    Mutex::Autolock autoLock(mLock);
922    return getPropertyStringInternal(name, value);
923}
924
925status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
926    // This function is internal to the class and should only be called while
927    // mLock is already held.
928    INIT_CHECK();
929
930    status_t err = UNKNOWN_ERROR;
931
932    Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
933            [&](Status status, const hidl_string& hValue) {
934                if (status == Status::OK) {
935                    value = toString8(hValue);
936                }
937                err = toStatusT(status);
938            }
939    );
940
941    return hResult.isOk() ? err : DEAD_OBJECT;
942}
943
944status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
945    Mutex::Autolock autoLock(mLock);
946    return getPropertyByteArrayInternal(name, value);
947}
948
949status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
950    // This function is internal to the class and should only be called while
951    // mLock is already held.
952    INIT_CHECK();
953
954    status_t err = UNKNOWN_ERROR;
955
956    Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
957            [&](Status status, const hidl_vec<uint8_t>& hValue) {
958                if (status == Status::OK) {
959                    value = toVector(hValue);
960                }
961                err = toStatusT(status);
962            }
963    );
964
965    return hResult.isOk() ? err : DEAD_OBJECT;
966}
967
968status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
969    Mutex::Autolock autoLock(mLock);
970    INIT_CHECK();
971
972    Status status = mPlugin->setPropertyString(toHidlString(name),
973            toHidlString(value));
974    return toStatusT(status);
975}
976
977status_t DrmHal::setPropertyByteArray(String8 const &name,
978                                   Vector<uint8_t> const &value ) const {
979    Mutex::Autolock autoLock(mLock);
980    INIT_CHECK();
981
982    Status status = mPlugin->setPropertyByteArray(toHidlString(name),
983            toHidlVec(value));
984    return toStatusT(status);
985}
986
987status_t DrmHal::getMetrics(MediaAnalyticsItem* metrics) {
988    // TODO: Replace this with real metrics.
989    metrics->setCString("/drm/mediadrm/dummymetric", "dummy");
990    return OK;
991}
992
993status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
994                                 String8 const &algorithm) {
995    Mutex::Autolock autoLock(mLock);
996    INIT_CHECK();
997
998    DrmSessionManager::Instance()->useSession(sessionId);
999
1000    Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1001            toHidlString(algorithm));
1002    return toStatusT(status);
1003}
1004
1005status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1006                              String8 const &algorithm) {
1007    Mutex::Autolock autoLock(mLock);
1008    INIT_CHECK();
1009
1010    DrmSessionManager::Instance()->useSession(sessionId);
1011
1012    Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1013            toHidlString(algorithm));
1014    return toStatusT(status);
1015}
1016
1017status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
1018        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1019        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1020    Mutex::Autolock autoLock(mLock);
1021    INIT_CHECK();
1022
1023    DrmSessionManager::Instance()->useSession(sessionId);
1024
1025    status_t err = UNKNOWN_ERROR;
1026
1027    Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1028            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1029            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1030                if (status == Status::OK) {
1031                    output = toVector(hOutput);
1032                }
1033                err = toStatusT(status);
1034            }
1035    );
1036
1037    return hResult.isOk() ? err : DEAD_OBJECT;
1038}
1039
1040status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
1041        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1042        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1043    Mutex::Autolock autoLock(mLock);
1044    INIT_CHECK();
1045
1046    DrmSessionManager::Instance()->useSession(sessionId);
1047
1048    status_t  err = UNKNOWN_ERROR;
1049
1050    Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1051            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1052            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1053                if (status == Status::OK) {
1054                    output = toVector(hOutput);
1055                }
1056                err = toStatusT(status);
1057            }
1058    );
1059
1060    return hResult.isOk() ? err : DEAD_OBJECT;
1061}
1062
1063status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
1064        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1065        Vector<uint8_t> &signature) {
1066    Mutex::Autolock autoLock(mLock);
1067    INIT_CHECK();
1068
1069    DrmSessionManager::Instance()->useSession(sessionId);
1070
1071    status_t err = UNKNOWN_ERROR;
1072
1073    Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1074            toHidlVec(keyId), toHidlVec(message),
1075            [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
1076                if (status == Status::OK) {
1077                    signature = toVector(hSignature);
1078                }
1079                err = toStatusT(status);
1080            }
1081    );
1082
1083    return hResult.isOk() ? err : DEAD_OBJECT;
1084}
1085
1086status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
1087        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1088        Vector<uint8_t> const &signature, bool &match) {
1089    Mutex::Autolock autoLock(mLock);
1090    INIT_CHECK();
1091
1092    DrmSessionManager::Instance()->useSession(sessionId);
1093
1094    status_t err = UNKNOWN_ERROR;
1095
1096    Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1097            toHidlVec(message), toHidlVec(signature),
1098            [&](Status status, bool hMatch) {
1099                if (status == Status::OK) {
1100                    match = hMatch;
1101                } else {
1102                    match = false;
1103                }
1104                err = toStatusT(status);
1105            }
1106    );
1107
1108    return hResult.isOk() ? err : DEAD_OBJECT;
1109}
1110
1111status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
1112        String8 const &algorithm, Vector<uint8_t> const &message,
1113        Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
1114    Mutex::Autolock autoLock(mLock);
1115    INIT_CHECK();
1116
1117    if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1118        return -EPERM;
1119    }
1120
1121    DrmSessionManager::Instance()->useSession(sessionId);
1122
1123    status_t err = UNKNOWN_ERROR;
1124
1125    Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1126            toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1127            [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1128                if (status == Status::OK) {
1129                    signature = toVector(hSignature);
1130                }
1131                err = toStatusT(status);
1132            }
1133        );
1134
1135    return hResult.isOk() ? err : DEAD_OBJECT;
1136}
1137
1138void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1139{
1140    Mutex::Autolock autoLock(mLock);
1141    closeOpenSessions();
1142    setListener(NULL);
1143    mInitCheck = NO_INIT;
1144
1145    if (mPlugin != NULL) {
1146        if (!mPlugin->setListener(NULL).isOk()) {
1147            mInitCheck = DEAD_OBJECT;
1148        }
1149    }
1150    mPlugin.clear();
1151}
1152
1153void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1154{
1155    if (vec.size()) {
1156        obj.writeInt32(vec.size());
1157        obj.write(vec.data(), vec.size());
1158    } else {
1159        obj.writeInt32(0);
1160    }
1161}
1162
1163
1164void DrmHal::reportMetrics() const
1165{
1166    Vector<uint8_t> metrics;
1167    String8 vendor;
1168    String8 description;
1169    if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1170            getPropertyStringInternal(String8("description"), description) == OK &&
1171            getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1172        status_t res = android::reportDrmPluginMetrics(
1173                metrics, vendor, description);
1174        if (res != OK) {
1175            ALOGE("Metrics were retrieved but could not be reported: %i", res);
1176        }
1177    }
1178}
1179
1180}  // namespace android
1181