DrmHal.cpp revision ab394d13bab3a84f23677357576cee7a6f0c7899
1a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker/*
2a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * Copyright (C) 2017 The Android Open Source Project
3a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *
4a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
5a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * you may not use this file except in compliance with the License.
6a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * You may obtain a copy of the License at
7a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *
8a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *      http://www.apache.org/licenses/LICENSE-2.0
9a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *
10a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * Unless required by applicable law or agreed to in writing, software
11a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
12a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * See the License for the specific language governing permissions and
14a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * limitations under the License.
15a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker */
16a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
17a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker//#define LOG_NDEBUG 0
18a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#define LOG_TAG "DrmHal"
19a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <utils/Log.h>
20a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
21a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <binder/IPCThreadState.h>
22a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <binder/IServiceManager.h>
23a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
24a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <android/hardware/drm/1.0/IDrmFactory.h>
25a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <android/hardware/drm/1.0/IDrmPlugin.h>
26a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <android/hardware/drm/1.0/types.h>
27abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker#include <android/hidl/manager/1.0/IServiceManager.h>
28593111f4460f2b2e8f541e936670e3577d45fff6Jeff Tinker#include <hidl/ServiceManagement.h>
29a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
30a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/DrmHal.h>
31a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/DrmSessionClientInterface.h>
32a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/DrmSessionManager.h>
3333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce#include <media/PluginMetricsReporting.h>
34a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/drm/DrmAPI.h>
35a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/ADebug.h>
36a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/AString.h>
37a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/hexdump.h>
38a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/MediaErrors.h>
39a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
40a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::EventType;
41a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::IDrmFactory;
42a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::IDrmPlugin;
43a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::KeyedVector;
44a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::KeyRequestType;
45a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::KeyStatus;
46a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::KeyStatusType;
47a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::KeyType;
48a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::KeyValue;
49a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::SecureStop;
50a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::Status;
51a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_array;
52a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_string;
53a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_vec;
54a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::Return;
55a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::Void;
56abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerusing ::android::hidl::manager::V1_0::IServiceManager;
57a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::sp;
58a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
59a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkernamespace android {
60a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
61a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic inline int getCallingPid() {
62a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return IPCThreadState::self()->getCallingPid();
63a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
64a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
65a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic bool checkPermission(const char* permissionString) {
66a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
67a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool ok = checkCallingPermission(String16(permissionString));
68a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!ok) ALOGE("Request requires %s", permissionString);
69a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return ok;
70a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
71a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
72a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
73a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Vector<uint8_t> vector;
74a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vector.appendArray(vec.data(), vec.size());
75a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return *const_cast<const Vector<uint8_t> *>(&vector);
76a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
77a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
78a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
79a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hidl_vec<uint8_t> vec;
80a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
81a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return vec;
82a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
83a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
84a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic String8 toString8(const hidl_string &string) {
85a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return String8(string.c_str());
86a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
87a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
88a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_string toHidlString(const String8& string) {
89a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hidl_string(string.string());
90a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
91a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
92a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
93a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
94a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyedVector) {
95a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    std::vector<KeyValue> stdKeyedVector;
96a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < keyedVector.size(); i++) {
97a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        KeyValue keyValue;
98a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyValue.key = toHidlString(keyedVector.keyAt(i));
99a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyValue.value = toHidlString(keyedVector.valueAt(i));
100a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        stdKeyedVector.push_back(keyValue);
101a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
102a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return ::KeyedVector(stdKeyedVector);
103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
104a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
105a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
106a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyedVector) {
107a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    KeyedVector<String8, String8> keyedVector;
108a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < hKeyedVector.size(); i++) {
109a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyedVector.add(toString8(hKeyedVector[i].key),
110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                toString8(hKeyedVector[i].value));
111a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
112a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return keyedVector;
113a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
114a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
115abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatic List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
116a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hSecureStops) {
117abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    List<Vector<uint8_t>> secureStops;
118a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < hSecureStops.size(); i++) {
119a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secureStops.push_back(toVector(hSecureStops[i].opaqueData));
120a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
121a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return secureStops;
122a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
123a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
124a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic status_t toStatusT(Status status) {
125a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    switch (status) {
126a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::OK:
127a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return OK;
128a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
129a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_NO_LICENSE:
130a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_NO_LICENSE;
131a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
132a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_LICENSE_EXPIRED:
133a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_LICENSE_EXPIRED;
134a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
135a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_SESSION_NOT_OPENED:
136a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_SESSION_NOT_OPENED;
137a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
138a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_CANNOT_HANDLE:
139a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
140a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
141a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_INVALID_STATE:
142a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_TAMPER_DETECTED;
143a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
144a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::BAD_VALUE:
145a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return BAD_VALUE;
146a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
147a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_NOT_PROVISIONED:
148a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_NOT_PROVISIONED;
149a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
150a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_RESOURCE_BUSY:
151a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_RESOURCE_BUSY;
152a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
153a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_DEVICE_REVOKED:
154a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_DEVICE_REVOKED;
155a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
156a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_UNKNOWN:
157a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
158a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_UNKNOWN;
159a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
160a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
161a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
162a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
163a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
164a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerMutex DrmHal::mLock;
165a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
166a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstruct DrmSessionClient : public DrmSessionClientInterface {
167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
170a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        sp<DrmHal> drm = mDrm.promote();
171a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (drm == NULL) {
172a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            return true;
173a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
174a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        status_t err = drm->closeSession(sessionId);
175a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (err != OK) {
176a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            return false;
177a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        drm->sendEvent(EventType::SESSION_RECLAIMED,
179a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                toHidlVec(sessionId), hidl_vec<uint8_t>());
180a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return true;
181a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
182a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
183a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerprotected:
184a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    virtual ~DrmSessionClient() {}
185a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
186a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerprivate:
187a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    wp<DrmHal> mDrm;
188a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
189a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
190a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker};
191a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
192a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerDrmHal::DrmHal()
193a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker   : mDrmSessionClient(new DrmSessionClient(this)),
194abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker     mFactories(makeDrmFactories()),
195abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker     mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
196a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
197a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1986133281c9b06c1d1176eca7f07401bba1067081eJeff Tinkervoid DrmHal::closeOpenSessions() {
1996133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    if (mPlugin != NULL) {
2006133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        for (size_t i = 0; i < mOpenSessions.size(); i++) {
2016133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker            mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
2026133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker            DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
2036133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        }
2046133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    }
2056133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    mOpenSessions.clear();
2066133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker}
2076133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker
208a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerDrmHal::~DrmHal() {
2096133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    closeOpenSessions();
210a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
211a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
213abeb36a8c2f044772297536e70340c3b245863e4Jeff TinkerVector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
214abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Vector<sp<IDrmFactory>> factories;
215c82b9c335e69b617817dace0ef64ad3df3f5080fJeff Tinker
216593111f4460f2b2e8f541e936670e3577d45fff6Jeff Tinker    auto manager = hardware::defaultServiceManager();
217c82b9c335e69b617817dace0ef64ad3df3f5080fJeff Tinker
218abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (manager != NULL) {
219abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        manager->listByInterface(IDrmFactory::descriptor,
220abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                [&factories](const hidl_vec<hidl_string> &registered) {
221abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    for (const auto &instance : registered) {
222abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        auto factory = IDrmFactory::getService(instance);
223abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        if (factory != NULL) {
224abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            factories.push_back(factory);
225abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            ALOGI("makeDrmFactories: factory instance %s is %s",
226abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    instance.c_str(),
227abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    factory->isRemote() ? "Remote" : "Not Remote");
228abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        }
229abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    }
230abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
231abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            );
232abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
233a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
234abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (factories.size() == 0) {
235abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        // must be in passthrough mode, load the default passthrough service
236e309b22bff1719f1fea84b247e4b2bc4c5f09eb5Jeff Tinker        auto passthrough = IDrmFactory::getService();
237abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (passthrough != NULL) {
238abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGI("makeDrmFactories: using default drm instance");
239abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            factories.push_back(passthrough);
240abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        } else {
241abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGE("Failed to find any drm factories");
242abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
243a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
244abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return factories;
245abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker}
246abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
247abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkersp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
248abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        const uint8_t uuid[16], const String8& appPackageName) {
249a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
250a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmPlugin> plugin;
251abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
252a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const sp<IDrmPlugin>& hPlugin) {
253abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                if (status != Status::OK) {
254abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    ALOGE("Failed to make drm plugin");
255abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    return;
256abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
257abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                plugin = hPlugin;
258abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            }
259abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        );
260f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker
261f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker    if (!hResult.isOk()) {
262f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker        ALOGE("createPlugin remote call failed");
263f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker    }
264f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker
265a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return plugin;
266a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
267a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
268a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::initCheck() const {
269a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
270a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
271a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
272a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setListener(const sp<IDrmClient>& listener)
273a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker{
274a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock lock(mEventLock);
275a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mListener != NULL){
276a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        IInterface::asBinder(mListener)->unlinkToDeath(this);
277a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
278a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
279a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        IInterface::asBinder(listener)->linkToDeath(this);
280a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
281a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mListener = listener;
282a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return NO_ERROR;
283a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
284a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
285a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerReturn<void> DrmHal::sendEvent(EventType hEventType,
286a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
287a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
288a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.lock();
289a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmClient> listener = mListener;
290a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.unlock();
291a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
292a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
293a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Parcel obj;
294a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, sessionId);
295a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, data);
296a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
297a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
298a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        DrmPlugin::EventType eventType;
299a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        switch(hEventType) {
300a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::PROVISION_REQUIRED:
301a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
302a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
303a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::KEY_NEEDED:
304a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
305a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
306a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::KEY_EXPIRED:
307a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventKeyExpired;
308a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
309a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::VENDOR_DEFINED:
310a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventVendorDefined;
311a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
312b86f4b3ce066eadbfe9c2f420b16aaf2de741edbRahul Frias        case EventType::SESSION_RECLAIMED:
313b86f4b3ce066eadbfe9c2f420b16aaf2de741edbRahul Frias            eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
314b86f4b3ce066eadbfe9c2f420b16aaf2de741edbRahul Frias            break;
315a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        default:
316a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            return Void();
317a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
318a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        listener->notify(eventType, 0, &obj);
319a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
320a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return Void();
321a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
322a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
323a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerReturn<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
324a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        int64_t expiryTimeInMS) {
325a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
326a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.lock();
327a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmClient> listener = mListener;
328a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.unlock();
329a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
330a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
331a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Parcel obj;
332a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, sessionId);
333a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt64(expiryTimeInMS);
334a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
335a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
336a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
337a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
338a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return Void();
339a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
340a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
341a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerReturn<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
342a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
343a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
344a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.lock();
345a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmClient> listener = mListener;
346a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.unlock();
347a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
348a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
349a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Parcel obj;
350a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, sessionId);
351a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
352a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        size_t nKeys = keyStatusList.size();
353a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(nKeys);
354a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        for (size_t i = 0; i < nKeys; ++i) {
355a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            const KeyStatus &keyStatus = keyStatusList[i];
356a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            writeByteArray(obj, keyStatus.keyId);
357a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            uint32_t type;
358a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            switch(keyStatus.type) {
359a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::USABLE:
360a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_Usable;
361a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
362a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::EXPIRED:
363a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_Expired;
364a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
365a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::OUTPUTNOTALLOWED:
366a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
367a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
368a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::STATUSPENDING:
369a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_StatusPending;
370a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
371a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::INTERNALERROR:
372a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            default:
373a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_InternalError;
374a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
375a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
376a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            obj.writeInt32(type);
377a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
378a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(hasNewUsableKey);
379a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
380a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
381a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
382a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
383a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return Void();
384a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
385a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
386a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
387a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
388a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
389abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
390abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
391abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            if (mimeType != "") {
392abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
393abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    return true;
394abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
395abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            } else {
396abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                return true;
397abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            }
398a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
399a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
400abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return false;
401a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
402a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
40368b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wongstatus_t DrmHal::createPlugin(const uint8_t uuid[16],
40468b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        const String8& appPackageName) {
405a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
406a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
407abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
408abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
409abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
410abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
411abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
412a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
413a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mPlugin == NULL) {
414a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = ERROR_UNSUPPORTED;
415a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
416319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (!mPlugin->setListener(this).isOk()) {
417319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = DEAD_OBJECT;
418319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        } else {
419319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = OK;
420319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        }
421a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
422a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
423a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
424a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
425a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
426a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::destroyPlugin() {
427a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
428a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
429a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
430a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
431a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
4326133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    closeOpenSessions();
43333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    reportMetrics();
434a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    setListener(NULL);
435319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    mInitCheck = NO_INIT;
436319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker
43770367f525a7bf5be52115608d190d72756e972eaJeff Tinker    if (mPlugin != NULL) {
438319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (!mPlugin->setListener(NULL).isOk()) {
439319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = DEAD_OBJECT;
440319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        }
44170367f525a7bf5be52115608d190d72756e972eaJeff Tinker    }
442a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
443a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
444a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
445a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
446a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
447a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
448a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
449a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
450a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
451a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
452a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
453a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t  err = UNKNOWN_ERROR;
454a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
455a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool retry = true;
456a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    do {
457a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hidl_vec<uint8_t> hSessionId;
458a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
459a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Return<void> hResult = mPlugin->openSession(
460a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                [&](Status status, const hidl_vec<uint8_t>& id) {
461a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    if (status == Status::OK) {
462a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        sessionId = toVector(id);
463a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    }
464a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    err = toStatusT(status);
465a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
466a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            );
467a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
468a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (!hResult.isOk()) {
469a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            err = DEAD_OBJECT;
470a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
471a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
472a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
473a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            mLock.unlock();
474a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            // reclaimSession may call back to closeSession, since mLock is
475a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            // shared between Drm instances, we should unlock here to avoid
476a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            // deadlock.
477a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
478a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            mLock.lock();
479a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        } else {
480a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            retry = false;
481a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
482a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } while (retry);
483a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
484a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (err == OK) {
485a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        DrmSessionManager::Instance()->addSession(getCallingPid(),
486a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                mDrmSessionClient, sessionId);
4876133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        mOpenSessions.push(sessionId);
488a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
489a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return err;
490a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
491a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
492a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
493a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
494a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
495a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
496a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
497a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
498a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
499319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
500319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    if (status.isOk()) {
501319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (status == Status::OK) {
502319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            DrmSessionManager::Instance()->removeSession(sessionId);
503319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            for (size_t i = 0; i < mOpenSessions.size(); i++) {
504319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                if (mOpenSessions[i] == sessionId) {
505319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                    mOpenSessions.removeAt(i);
506319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                    break;
507319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                }
5086133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker            }
5096133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        }
510319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        reportMetrics();
511319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        return toStatusT(status);
512a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
513319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    return DEAD_OBJECT;
514a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
515a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
516a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
517a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Vector<uint8_t> const &initData, String8 const &mimeType,
518a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        DrmPlugin::KeyType keyType, KeyedVector<String8,
519a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8> const &optionalParameters, Vector<uint8_t> &request,
520a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
521a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
522a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
523a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
524a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
525a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
526a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
527a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
528a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
529a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    KeyType hKeyType;
530a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (keyType == DrmPlugin::kKeyType_Streaming) {
531a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyType = KeyType::STREAMING;
532a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else if (keyType == DrmPlugin::kKeyType_Offline) {
533a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyType = KeyType::OFFLINE;
534a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else if (keyType == DrmPlugin::kKeyType_Release) {
535a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyType = KeyType::RELEASE;
536a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
537a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return BAD_VALUE;
538a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
539a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
540a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
541a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
542a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
543a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
544a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
545a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
546a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hRequest,
547a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
548a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
549a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
550a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    request = toVector(hRequest);
551a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    defaultUrl = toString8(hDefaultUrl);
552a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
553a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    switch (hKeyRequestType) {
554a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    case KeyRequestType::INITIAL:
555a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
556a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
557a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    case KeyRequestType::RENEWAL:
558a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
559a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
560a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    case KeyRequestType::RELEASE:
561a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
562a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
563a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    default:
564a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
565a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
566a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    }
567a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    err = toStatusT(status);
568a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
569a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            });
570a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
571a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
572a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
573a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
574a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
575a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
576a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
577a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
578a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
579a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
580a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
581a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
582a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
583a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
584a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
585a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
586a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
587a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(response),
588a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
589a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
590a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    keySetId = toVector(hKeySetId);
591a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
592a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
593a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
594a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
595a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
596a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
597a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
598a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
599a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
600a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
601a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
602a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
603a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
604a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
605a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
606a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
607a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
608a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
609a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
610a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Vector<uint8_t> const &keySetId) {
611a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
612a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
613a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
614a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
615a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
616a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
617a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
618a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
619a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
620a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    toHidlVec(keySetId)));
621a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
622a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
623a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
624a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        KeyedVector<String8, String8> &infoMap) const {
625a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
626a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
627a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
628a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
629a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
630a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
631a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
632a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
633a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::KeyedVector hInfoMap;
634a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
635a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
636a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
637a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
638a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<KeyValue>& map) {
639a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
640a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    infoMap = toKeyedVector(map);
641a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
642a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
643a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
644a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
645a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
646a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
647a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
648a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
649a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getProvisionRequest(String8 const &certType,
650a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8 const &certAuthority, Vector<uint8_t> &request,
651a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8 &defaultUrl) {
652a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
653a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
654a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
655a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
656a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
657a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
658a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
659a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
660a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getProvisionRequest(
661a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(certType), toHidlString(certAuthority),
662a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hRequest,
663a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    const hidl_string& hDefaultUrl) {
664a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
665a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    request = toVector(hRequest);
666a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    defaultUrl = toString8(hDefaultUrl);
667a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
668a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
669a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
670a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
671a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
672a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
673a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
674a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
675a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
67668b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
677a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
678a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
679a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
680a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
681a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
682a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
683a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
684a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
685a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
686a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hCertificate,
687a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    const hidl_vec<uint8_t>& hWrappedKey) {
688a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
689a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    certificate = toVector(hCertificate);
690a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    wrappedKey = toVector(hWrappedKey);
691a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
692a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
693a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
694a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
695a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
696a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
697a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
698a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
699abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatus_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
700a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
701a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
702a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
703a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
704a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
705a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
706a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
707a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
708a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getSecureStops(
709a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
710a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
711a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    secureStops = toSecureStops(hSecureStops);
712a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
713a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
714a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
715a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
716a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
717a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
718a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
719a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
720a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
721a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
722a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
723a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
724a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
725a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
726a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
727a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
728a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
729a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
730a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
731a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const SecureStop& hSecureStop) {
732a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
733a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    secureStop = toVector(hSecureStop.opaqueData);
734a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
735a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
736a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
737a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
738a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
739a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
740a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
741a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
742a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
743a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
744a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
745a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
746a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
747a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
748a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
749a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
750a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
751a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
752a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::releaseAllSecureStops() {
753a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
754a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
755a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
756a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
757a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
758a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
759a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->releaseAllSecureStops());
760a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
761a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
762a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
763a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
76433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    return getPropertyStringInternal(name, value);
76533ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce}
76633ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce
76733ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Brucestatus_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
76833ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // This function is internal to the class and should only be called while
76933ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // mLock is already held.
770a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
771a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
772a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
773a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
774a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
775a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
776a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
777a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
778a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_string& hValue) {
779a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
780a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    value = toString8(hValue);
781a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
782a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
783a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
784a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
785a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
786a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
787a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
788a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
789a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
790a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
79133ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    return getPropertyByteArrayInternal(name, value);
79233ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce}
79333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce
79433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Brucestatus_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
79533ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // This function is internal to the class and should only be called while
79633ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // mLock is already held.
797a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
798a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
799a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
800a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
801a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
802a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
803a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
804a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
805a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hValue) {
806a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
807a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    value = toVector(hValue);
808a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
809a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
810a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
811a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
812a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
813a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
814a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
815a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
816a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
817a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
818a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
819a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
820a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
821a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
822a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
823a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status =  mPlugin->setPropertyString(toHidlString(name),
824a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(value));
825a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
826a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
827a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
828a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setPropertyByteArray(String8 const &name,
829a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                                   Vector<uint8_t> const &value ) const {
830a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
831a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
832a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
833a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
834a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
835a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
836a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status = mPlugin->setPropertyByteArray(toHidlString(name),
837a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(value));
838a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
839a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
840a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
841ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stonestatus_t DrmHal::getMetrics(MediaAnalyticsItem* metrics) {
842ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone    // TODO: Replace this with real metrics.
843ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone    metrics->setCString("/drm/mediadrm/dummymetric", "dummy");
844ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone    return OK;
845ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone}
846a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
847a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
848a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                                 String8 const &algorithm) {
849a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
850a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
851a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
852a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
853a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
854a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
855a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
856a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
857a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
858a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(algorithm));
859a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
860a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
861a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
862a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
863a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                              String8 const &algorithm) {
864a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
865a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
866a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
867a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
868a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
869a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
870a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
871a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
872a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
873a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(algorithm));
874a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
875a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
876a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
877a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
87868b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
87968b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
880a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
881a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
882a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
883a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
884a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
885a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
886a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
887a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
888a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
889a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
890a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
891a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
892a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
893a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
894a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    output = toVector(hOutput);
895a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
896a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
897a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
898a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
899a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
900a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
901a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
902a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
903a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
90468b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
90568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
906a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
907a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
908a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
909a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
910a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
911a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
912a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
913a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
914a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t  err = UNKNOWN_ERROR;
915a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
916a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
917a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
918a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
919a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
920a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    output = toVector(hOutput);
921a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
922a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
923a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
924a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
925a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
926a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
927a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
928a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
929a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::sign(Vector<uint8_t> const &sessionId,
93068b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
93168b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> &signature) {
932a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
933a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
934a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
935a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
936a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
937a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
938a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
939a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
940a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
941a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
942a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
943a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(keyId), toHidlVec(message),
944a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
945a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
946a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    signature = toVector(hSignature);
947a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
948a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
949a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
950a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
951a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
952a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
953a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
954a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
955a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::verify(Vector<uint8_t> const &sessionId,
95668b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
95768b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &signature, bool &match) {
958a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
959a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
960a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
961a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
962a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
963a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
964a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
965a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
966a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
967a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
968a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
969a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(message), toHidlVec(signature),
970a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, bool hMatch) {
971a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
972a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    match = hMatch;
973a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                } else {
974a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    match = false;
975a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
976a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
977a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
978a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
979a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
980a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
981a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
982a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
983a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
98468b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        String8 const &algorithm, Vector<uint8_t> const &message,
98568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
986a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
987a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
988a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
989a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
990a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
991a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
992a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
993a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return -EPERM;
994a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
995a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
996a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
997a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
998a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
999a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1000a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1001a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1002a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1003a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1004a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    signature = toVector(hSignature);
1005a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1006a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1007a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1008a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
1009a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1010a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1011a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1012a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1013a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1014a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker{
1015a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
10166133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    closeOpenSessions();
10173e2891674ef57a74e59ca5e27f89647b3f06861bJeff Tinker    setListener(NULL);
1018319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    mInitCheck = NO_INIT;
1019319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker
102070367f525a7bf5be52115608d190d72756e972eaJeff Tinker    if (mPlugin != NULL) {
1021319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (!mPlugin->setListener(NULL).isOk()) {
1022319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = DEAD_OBJECT;
1023319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        }
102470367f525a7bf5be52115608d190d72756e972eaJeff Tinker    }
1025a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
1026a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1027a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1028a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1029a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker{
1030a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (vec.size()) {
1031a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(vec.size());
1032a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.write(vec.data(), vec.size());
1033a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
1034a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(0);
1035a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
1036a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1037a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1038ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone
103933ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Brucevoid DrmHal::reportMetrics() const
104033ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce{
104133ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    Vector<uint8_t> metrics;
104233ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    String8 vendor;
104333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    String8 description;
104433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
104533ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce            getPropertyStringInternal(String8("description"), description) == OK &&
104633ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce            getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
104733ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce        status_t res = android::reportDrmPluginMetrics(
104833ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce                metrics, vendor, description);
104933ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce        if (res != OK) {
105033ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce            ALOGE("Metrics were retrieved but could not be reported: %i", res);
105133ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce        }
105233ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    }
105333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce}
105433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce
1055a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}  // namespace android
1056