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