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