DrmHal.cpp revision 15177d7eab8c2300b4f1d577267e528bd7e4eedc
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        auto openSessions = mOpenSessions;
256        for (size_t i = 0; i < openSessions.size(); i++) {
257            closeSession(openSessions[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            mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
476        }
477    }
478
479    if (mPlugin == NULL) {
480        mInitCheck = ERROR_UNSUPPORTED;
481    } else {
482        if (!mPlugin->setListener(this).isOk()) {
483            mInitCheck = DEAD_OBJECT;
484        } else {
485            mInitCheck = OK;
486        }
487    }
488
489    return mInitCheck;
490}
491
492status_t DrmHal::destroyPlugin() {
493    Mutex::Autolock autoLock(mLock);
494    INIT_CHECK();
495
496    closeOpenSessions();
497    reportMetrics();
498    setListener(NULL);
499    mInitCheck = NO_INIT;
500
501    if (mPlugin != NULL) {
502        if (!mPlugin->setListener(NULL).isOk()) {
503            mInitCheck = DEAD_OBJECT;
504        }
505    }
506    mPlugin.clear();
507    return OK;
508}
509
510status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
511    Mutex::Autolock autoLock(mLock);
512    INIT_CHECK();
513
514    status_t  err = UNKNOWN_ERROR;
515
516    bool retry = true;
517    do {
518        hidl_vec<uint8_t> hSessionId;
519
520        Return<void> hResult = mPlugin->openSession(
521                [&](Status status, const hidl_vec<uint8_t>& id) {
522                    if (status == Status::OK) {
523                        sessionId = toVector(id);
524                    }
525                    err = toStatusT(status);
526                }
527            );
528
529        if (!hResult.isOk()) {
530            err = DEAD_OBJECT;
531        }
532
533        if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
534            mLock.unlock();
535            // reclaimSession may call back to closeSession, since mLock is
536            // shared between Drm instances, we should unlock here to avoid
537            // deadlock.
538            retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
539            mLock.lock();
540        } else {
541            retry = false;
542        }
543    } while (retry);
544
545    if (err == OK) {
546        DrmSessionManager::Instance()->addSession(getCallingPid(),
547                mDrmSessionClient, sessionId);
548        mOpenSessions.push(sessionId);
549    }
550
551    mMetrics.mOpenSessionCounter.Increment(err);
552    return err;
553}
554
555status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
556    Mutex::Autolock autoLock(mLock);
557    INIT_CHECK();
558
559    Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
560    if (status.isOk()) {
561        if (status == Status::OK) {
562            DrmSessionManager::Instance()->removeSession(sessionId);
563            for (size_t i = 0; i < mOpenSessions.size(); i++) {
564                if (mOpenSessions[i] == sessionId) {
565                    mOpenSessions.removeAt(i);
566                    break;
567                }
568            }
569        }
570        reportMetrics();
571        status_t response = toStatusT(status);
572        mMetrics.mCloseSessionCounter.Increment(response);
573        return response;
574    }
575    mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
576    return DEAD_OBJECT;
577}
578
579status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
580        Vector<uint8_t> const &initData, String8 const &mimeType,
581        DrmPlugin::KeyType keyType, KeyedVector<String8,
582        String8> const &optionalParameters, Vector<uint8_t> &request,
583        String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
584    Mutex::Autolock autoLock(mLock);
585    INIT_CHECK();
586    EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
587
588    DrmSessionManager::Instance()->useSession(sessionId);
589
590    KeyType hKeyType;
591    if (keyType == DrmPlugin::kKeyType_Streaming) {
592        hKeyType = KeyType::STREAMING;
593    } else if (keyType == DrmPlugin::kKeyType_Offline) {
594        hKeyType = KeyType::OFFLINE;
595    } else if (keyType == DrmPlugin::kKeyType_Release) {
596        hKeyType = KeyType::RELEASE;
597    } else {
598        keyRequestTimer.SetAttribute(BAD_VALUE);
599        return BAD_VALUE;
600    }
601
602    ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
603
604    status_t err = UNKNOWN_ERROR;
605
606    if (mPluginV1_1 != NULL) {
607        Return<void> hResult =
608            mPluginV1_1->getKeyRequest_1_1(
609                toHidlVec(sessionId), toHidlVec(initData),
610                toHidlString(mimeType), hKeyType, hOptionalParameters,
611                [&](Status status, const hidl_vec<uint8_t>& hRequest,
612                    drm::V1_1::KeyRequestType hKeyRequestType,
613                    const hidl_string& hDefaultUrl) {
614
615            if (status == Status::OK) {
616                request = toVector(hRequest);
617                defaultUrl = toString8(hDefaultUrl);
618
619                switch (hKeyRequestType) {
620                    case drm::V1_1::KeyRequestType::INITIAL:
621                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
622                        break;
623                    case drm::V1_1::KeyRequestType::RENEWAL:
624                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
625                        break;
626                    case drm::V1_1::KeyRequestType::RELEASE:
627                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
628                        break;
629                    case drm::V1_1::KeyRequestType::NONE:
630                        *keyRequestType = DrmPlugin::kKeyRequestType_None;
631                        break;
632                    case drm::V1_1::KeyRequestType::UPDATE:
633                        *keyRequestType = DrmPlugin::kKeyRequestType_Update;
634                        break;
635                    default:
636                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
637                        break;
638                }
639                err = toStatusT(status);
640            }
641        });
642        return hResult.isOk() ? err : DEAD_OBJECT;
643    }
644
645    Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
646            toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
647            [&](Status status, const hidl_vec<uint8_t>& hRequest,
648                    drm::V1_0::KeyRequestType hKeyRequestType,
649                    const hidl_string& hDefaultUrl) {
650
651                if (status == Status::OK) {
652                    request = toVector(hRequest);
653                    defaultUrl = toString8(hDefaultUrl);
654
655                    switch (hKeyRequestType) {
656                    case drm::V1_0::KeyRequestType::INITIAL:
657                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
658                        break;
659                    case drm::V1_0::KeyRequestType::RENEWAL:
660                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
661                        break;
662                    case drm::V1_0::KeyRequestType::RELEASE:
663                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
664                        break;
665                    default:
666                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
667                        break;
668                    }
669                    err = toStatusT(status);
670                }
671            });
672
673    err = hResult.isOk() ? err : DEAD_OBJECT;
674    keyRequestTimer.SetAttribute(err);
675    return err;
676}
677
678status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
679        Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
680    Mutex::Autolock autoLock(mLock);
681    EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
682
683    INIT_CHECK();
684
685    DrmSessionManager::Instance()->useSession(sessionId);
686
687    status_t err = UNKNOWN_ERROR;
688
689    Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
690            toHidlVec(response),
691            [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
692                if (status == Status::OK) {
693                    keySetId = toVector(hKeySetId);
694                }
695                err = toStatusT(status);
696            }
697        );
698    err = hResult.isOk() ? err : DEAD_OBJECT;
699    keyResponseTimer.SetAttribute(err);
700    return err;
701}
702
703status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
704    Mutex::Autolock autoLock(mLock);
705    INIT_CHECK();
706
707    return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
708}
709
710status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
711        Vector<uint8_t> const &keySetId) {
712    Mutex::Autolock autoLock(mLock);
713    INIT_CHECK();
714
715    DrmSessionManager::Instance()->useSession(sessionId);
716
717    return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
718                    toHidlVec(keySetId)));
719}
720
721status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
722        KeyedVector<String8, String8> &infoMap) const {
723    Mutex::Autolock autoLock(mLock);
724    INIT_CHECK();
725
726    DrmSessionManager::Instance()->useSession(sessionId);
727
728    ::KeyedVector hInfoMap;
729
730    status_t err = UNKNOWN_ERROR;
731
732    Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
733            [&](Status status, const hidl_vec<KeyValue>& map) {
734                if (status == Status::OK) {
735                    infoMap = toKeyedVector(map);
736                }
737                err = toStatusT(status);
738            }
739        );
740
741    return hResult.isOk() ? err : DEAD_OBJECT;
742}
743
744status_t DrmHal::getProvisionRequest(String8 const &certType,
745        String8 const &certAuthority, Vector<uint8_t> &request,
746        String8 &defaultUrl) {
747    Mutex::Autolock autoLock(mLock);
748    INIT_CHECK();
749
750    status_t err = UNKNOWN_ERROR;
751
752    Return<void> hResult = mPlugin->getProvisionRequest(
753            toHidlString(certType), toHidlString(certAuthority),
754            [&](Status status, const hidl_vec<uint8_t>& hRequest,
755                    const hidl_string& hDefaultUrl) {
756                if (status == Status::OK) {
757                    request = toVector(hRequest);
758                    defaultUrl = toString8(hDefaultUrl);
759                }
760                err = toStatusT(status);
761            }
762        );
763
764    err = hResult.isOk() ? err : DEAD_OBJECT;
765    mMetrics.mGetProvisionRequestCounter.Increment(err);
766    return err;
767}
768
769status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
770        Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
771    Mutex::Autolock autoLock(mLock);
772    INIT_CHECK();
773
774    status_t err = UNKNOWN_ERROR;
775
776    Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
777            [&](Status status, const hidl_vec<uint8_t>& hCertificate,
778                    const hidl_vec<uint8_t>& hWrappedKey) {
779                if (status == Status::OK) {
780                    certificate = toVector(hCertificate);
781                    wrappedKey = toVector(hWrappedKey);
782                }
783                err = toStatusT(status);
784            }
785        );
786
787    err = hResult.isOk() ? err : DEAD_OBJECT;
788    mMetrics.mProvideProvisionResponseCounter.Increment(err);
789    return err;
790}
791
792status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
793    Mutex::Autolock autoLock(mLock);
794    INIT_CHECK();
795
796    status_t err = UNKNOWN_ERROR;
797
798    Return<void> hResult = mPlugin->getSecureStops(
799            [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
800                if (status == Status::OK) {
801                    secureStops = toSecureStops(hSecureStops);
802                }
803                err = toStatusT(status);
804            }
805    );
806
807    return hResult.isOk() ? err : DEAD_OBJECT;
808}
809
810
811status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
812    Mutex::Autolock autoLock(mLock);
813
814    if (mInitCheck != OK) {
815        return mInitCheck;
816    }
817
818    if (mPluginV1_1 == NULL) {
819        return ERROR_DRM_CANNOT_HANDLE;
820    }
821
822    status_t err = UNKNOWN_ERROR;
823
824    Return<void> hResult = mPluginV1_1->getSecureStopIds(
825            [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
826                if (status == Status::OK) {
827                    secureStopIds = toSecureStopIds(hSecureStopIds);
828                }
829                err = toStatusT(status);
830            }
831    );
832
833    return hResult.isOk() ? err : DEAD_OBJECT;
834}
835
836
837status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
838    Mutex::Autolock autoLock(mLock);
839    INIT_CHECK();
840
841    status_t err = UNKNOWN_ERROR;
842
843    Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
844            [&](Status status, const SecureStop& hSecureStop) {
845                if (status == Status::OK) {
846                    secureStop = toVector(hSecureStop.opaqueData);
847                }
848                err = toStatusT(status);
849            }
850    );
851
852    return hResult.isOk() ? err : DEAD_OBJECT;
853}
854
855status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
856    Mutex::Autolock autoLock(mLock);
857    INIT_CHECK();
858
859    if (mPluginV1_1 != NULL) {
860        SecureStopRelease secureStopRelease;
861        secureStopRelease.opaqueData = toHidlVec(ssRelease);
862        return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
863    }
864
865    return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
866}
867
868status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
869    Mutex::Autolock autoLock(mLock);
870
871    if (mInitCheck != OK) {
872        return mInitCheck;
873    }
874
875    if (mPluginV1_1 == NULL) {
876        return ERROR_DRM_CANNOT_HANDLE;
877    }
878
879    return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
880}
881
882status_t DrmHal::removeAllSecureStops() {
883    Mutex::Autolock autoLock(mLock);
884    INIT_CHECK();
885
886    if (mPluginV1_1 != NULL) {
887        return toStatusT(mPluginV1_1->removeAllSecureStops());
888    }
889    return toStatusT(mPlugin->releaseAllSecureStops());
890}
891
892status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
893            DrmPlugin::HdcpLevel *max) const {
894    Mutex::Autolock autoLock(mLock);
895    INIT_CHECK();
896
897    if (connected == NULL || max == NULL) {
898        return BAD_VALUE;
899    }
900    status_t err = UNKNOWN_ERROR;
901
902    if (mPluginV1_1 == NULL) {
903        return ERROR_DRM_CANNOT_HANDLE;
904    }
905
906    *connected = DrmPlugin::kHdcpLevelUnknown;
907    *max = DrmPlugin::kHdcpLevelUnknown;
908
909    Return<void> hResult = mPluginV1_1->getHdcpLevels(
910            [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
911                if (status == Status::OK) {
912                    *connected = toHdcpLevel(hConnected);
913                    *max = toHdcpLevel(hMax);
914                }
915                err = toStatusT(status);
916            }
917    );
918
919    return hResult.isOk() ? err : DEAD_OBJECT;
920}
921
922status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
923    Mutex::Autolock autoLock(mLock);
924    INIT_CHECK();
925
926    if (open == NULL || max == NULL) {
927        return BAD_VALUE;
928    }
929    status_t err = UNKNOWN_ERROR;
930
931    *open = 0;
932    *max = 0;
933
934    if (mPluginV1_1 == NULL) {
935        return ERROR_DRM_CANNOT_HANDLE;
936    }
937
938    Return<void> hResult = mPluginV1_1->getNumberOfSessions(
939            [&](Status status, uint32_t hOpen, uint32_t hMax) {
940                if (status == Status::OK) {
941                    *open = hOpen;
942                    *max = hMax;
943                }
944                err = toStatusT(status);
945            }
946    );
947
948    return hResult.isOk() ? err : DEAD_OBJECT;
949}
950
951status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
952        DrmPlugin::SecurityLevel *level) const {
953    Mutex::Autolock autoLock(mLock);
954    INIT_CHECK();
955
956    if (level == NULL) {
957        return BAD_VALUE;
958    }
959    status_t err = UNKNOWN_ERROR;
960
961    if (mPluginV1_1 == NULL) {
962        return ERROR_DRM_CANNOT_HANDLE;
963    }
964
965    *level = DrmPlugin::kSecurityLevelUnknown;
966
967    Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
968            [&](Status status, SecurityLevel hLevel) {
969                if (status == Status::OK) {
970                    *level = toSecurityLevel(hLevel);
971                }
972                err = toStatusT(status);
973            }
974    );
975
976    return hResult.isOk() ? err : DEAD_OBJECT;
977}
978
979status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
980        const DrmPlugin::SecurityLevel& level) {
981    Mutex::Autolock autoLock(mLock);
982    INIT_CHECK();
983
984    if (mPluginV1_1 == NULL) {
985        return ERROR_DRM_CANNOT_HANDLE;
986    }
987
988    SecurityLevel hSecurityLevel;
989
990    switch(level) {
991    case DrmPlugin::kSecurityLevelSwSecureCrypto:
992        hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
993        break;
994    case DrmPlugin::kSecurityLevelSwSecureDecode:
995        hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
996        break;
997    case DrmPlugin::kSecurityLevelHwSecureCrypto:
998        hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
999        break;
1000    case DrmPlugin::kSecurityLevelHwSecureDecode:
1001        hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
1002        break;
1003    case DrmPlugin::kSecurityLevelHwSecureAll:
1004        hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
1005        break;
1006    default:
1007        return ERROR_DRM_CANNOT_HANDLE;
1008    }
1009
1010    Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
1011            hSecurityLevel);
1012    return toStatusT(status);
1013}
1014
1015status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1016    Mutex::Autolock autoLock(mLock);
1017    return getPropertyStringInternal(name, value);
1018}
1019
1020status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1021    // This function is internal to the class and should only be called while
1022    // mLock is already held.
1023    INIT_CHECK();
1024
1025    status_t err = UNKNOWN_ERROR;
1026
1027    Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1028            [&](Status status, const hidl_string& hValue) {
1029                if (status == Status::OK) {
1030                    value = toString8(hValue);
1031                }
1032                err = toStatusT(status);
1033            }
1034    );
1035
1036    return hResult.isOk() ? err : DEAD_OBJECT;
1037}
1038
1039status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1040    Mutex::Autolock autoLock(mLock);
1041    return getPropertyByteArrayInternal(name, value);
1042}
1043
1044status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1045    // This function is internal to the class and should only be called while
1046    // mLock is already held.
1047    INIT_CHECK();
1048
1049    status_t err = UNKNOWN_ERROR;
1050
1051    Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1052            [&](Status status, const hidl_vec<uint8_t>& hValue) {
1053                if (status == Status::OK) {
1054                    value = toVector(hValue);
1055                }
1056                err = toStatusT(status);
1057            }
1058    );
1059
1060    err = hResult.isOk() ? err : DEAD_OBJECT;
1061    if (name == kPropertyDeviceUniqueId) {
1062        mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1063    }
1064    return err;
1065}
1066
1067status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1068    Mutex::Autolock autoLock(mLock);
1069    INIT_CHECK();
1070
1071    Status status = mPlugin->setPropertyString(toHidlString(name),
1072            toHidlString(value));
1073    return toStatusT(status);
1074}
1075
1076status_t DrmHal::setPropertyByteArray(String8 const &name,
1077                                   Vector<uint8_t> const &value ) const {
1078    Mutex::Autolock autoLock(mLock);
1079    INIT_CHECK();
1080
1081    Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1082            toHidlVec(value));
1083    return toStatusT(status);
1084}
1085
1086status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
1087    if (item == nullptr) {
1088      return UNEXPECTED_NULL;
1089    }
1090
1091    mMetrics.Export(item);
1092    return OK;
1093}
1094
1095status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1096                                 String8 const &algorithm) {
1097    Mutex::Autolock autoLock(mLock);
1098    INIT_CHECK();
1099
1100    DrmSessionManager::Instance()->useSession(sessionId);
1101
1102    Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1103            toHidlString(algorithm));
1104    return toStatusT(status);
1105}
1106
1107status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1108                              String8 const &algorithm) {
1109    Mutex::Autolock autoLock(mLock);
1110    INIT_CHECK();
1111
1112    DrmSessionManager::Instance()->useSession(sessionId);
1113
1114    Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1115            toHidlString(algorithm));
1116    return toStatusT(status);
1117}
1118
1119status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
1120        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1121        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1122    Mutex::Autolock autoLock(mLock);
1123    INIT_CHECK();
1124
1125    DrmSessionManager::Instance()->useSession(sessionId);
1126
1127    status_t err = UNKNOWN_ERROR;
1128
1129    Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1130            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1131            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1132                if (status == Status::OK) {
1133                    output = toVector(hOutput);
1134                }
1135                err = toStatusT(status);
1136            }
1137    );
1138
1139    return hResult.isOk() ? err : DEAD_OBJECT;
1140}
1141
1142status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
1143        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1144        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1145    Mutex::Autolock autoLock(mLock);
1146    INIT_CHECK();
1147
1148    DrmSessionManager::Instance()->useSession(sessionId);
1149
1150    status_t  err = UNKNOWN_ERROR;
1151
1152    Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1153            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1154            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1155                if (status == Status::OK) {
1156                    output = toVector(hOutput);
1157                }
1158                err = toStatusT(status);
1159            }
1160    );
1161
1162    return hResult.isOk() ? err : DEAD_OBJECT;
1163}
1164
1165status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
1166        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1167        Vector<uint8_t> &signature) {
1168    Mutex::Autolock autoLock(mLock);
1169    INIT_CHECK();
1170
1171    DrmSessionManager::Instance()->useSession(sessionId);
1172
1173    status_t err = UNKNOWN_ERROR;
1174
1175    Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1176            toHidlVec(keyId), toHidlVec(message),
1177            [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
1178                if (status == Status::OK) {
1179                    signature = toVector(hSignature);
1180                }
1181                err = toStatusT(status);
1182            }
1183    );
1184
1185    return hResult.isOk() ? err : DEAD_OBJECT;
1186}
1187
1188status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
1189        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1190        Vector<uint8_t> const &signature, bool &match) {
1191    Mutex::Autolock autoLock(mLock);
1192    INIT_CHECK();
1193
1194    DrmSessionManager::Instance()->useSession(sessionId);
1195
1196    status_t err = UNKNOWN_ERROR;
1197
1198    Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1199            toHidlVec(message), toHidlVec(signature),
1200            [&](Status status, bool hMatch) {
1201                if (status == Status::OK) {
1202                    match = hMatch;
1203                } else {
1204                    match = false;
1205                }
1206                err = toStatusT(status);
1207            }
1208    );
1209
1210    return hResult.isOk() ? err : DEAD_OBJECT;
1211}
1212
1213status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
1214        String8 const &algorithm, Vector<uint8_t> const &message,
1215        Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
1216    Mutex::Autolock autoLock(mLock);
1217    INIT_CHECK();
1218
1219    if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1220        return -EPERM;
1221    }
1222
1223    DrmSessionManager::Instance()->useSession(sessionId);
1224
1225    status_t err = UNKNOWN_ERROR;
1226
1227    Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1228            toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1229            [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1230                if (status == Status::OK) {
1231                    signature = toVector(hSignature);
1232                }
1233                err = toStatusT(status);
1234            }
1235        );
1236
1237    return hResult.isOk() ? err : DEAD_OBJECT;
1238}
1239
1240void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1241{
1242    Mutex::Autolock autoLock(mLock);
1243    closeOpenSessions();
1244    setListener(NULL);
1245    mInitCheck = NO_INIT;
1246
1247    if (mPlugin != NULL) {
1248        if (!mPlugin->setListener(NULL).isOk()) {
1249            mInitCheck = DEAD_OBJECT;
1250        }
1251    }
1252    mPlugin.clear();
1253}
1254
1255void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1256{
1257    if (vec.size()) {
1258        obj.writeInt32(vec.size());
1259        obj.write(vec.data(), vec.size());
1260    } else {
1261        obj.writeInt32(0);
1262    }
1263}
1264
1265
1266void DrmHal::reportMetrics() const
1267{
1268    Vector<uint8_t> metrics;
1269    String8 vendor;
1270    String8 description;
1271    if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1272            getPropertyStringInternal(String8("description"), description) == OK &&
1273            getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1274        status_t res = android::reportDrmPluginMetrics(
1275                metrics, vendor, description);
1276        if (res != OK) {
1277            ALOGE("Metrics were retrieved but could not be reported: %i", res);
1278        }
1279    }
1280}
1281
1282}  // namespace android
1283