DrmHal.cpp revision 28f27c3bee88b0f47b1086feeaa904bcdec37af6
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"
19fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone#include <iomanip>
20fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone
21a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <utils/Log.h>
22a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
23a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <binder/IPCThreadState.h>
24a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <binder/IServiceManager.h>
25a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
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>
33f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone#include <media/EventMetric.h>
3433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce#include <media/PluginMetricsReporting.h>
35a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/drm/DrmAPI.h>
36a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/ADebug.h>
37a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/AString.h>
38a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/hexdump.h>
39a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/MediaErrors.h>
40a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
416d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_0::KeyedVector;
426d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_0::KeyStatusType;
436d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_0::KeyType;
446d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_0::KeyValue;
456d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_1::HdcpLevel;;
466d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_0::SecureStop;
4715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinkerusing drm::V1_1::SecureStopRelease;
4815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinkerusing drm::V1_0::SecureStopId;
496d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_1::SecurityLevel;
506d998b67be330843f633a563c23c606593060165Jeff Tinkerusing drm::V1_0::Status;
5128f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stoneusing ::android::hardware::drm::V1_1::DrmMetricGroup;
52a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_array;
53a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_string;
54a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_vec;
55a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::Return;
56a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::Void;
57abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerusing ::android::hidl::manager::V1_0::IServiceManager;
58637b7855829920114a8863b93fe52203b7471eeaAdam Stoneusing ::android::os::PersistableBundle;
59a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::sp;
60a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
61cea91ce60260d7ebb94449ad7674150fdc227886Adam Stonenamespace {
62cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone
63cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
64cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone// in the MediaDrm API.
65cea91ce60260d7ebb94449ad7674150fdc227886Adam Stoneconstexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
66cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone
67cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone}
68cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone
69a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkernamespace android {
70a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
716d998b67be330843f633a563c23c606593060165Jeff Tinker#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
726d998b67be330843f633a563c23c606593060165Jeff Tinker
73a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic inline int getCallingPid() {
74a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return IPCThreadState::self()->getCallingPid();
75a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
76a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
77a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic bool checkPermission(const char* permissionString) {
78a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
79a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool ok = checkCallingPermission(String16(permissionString));
80a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!ok) ALOGE("Request requires %s", permissionString);
81a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return ok;
82a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
83a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
84a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
85a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Vector<uint8_t> vector;
86a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vector.appendArray(vec.data(), vec.size());
87a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return *const_cast<const Vector<uint8_t> *>(&vector);
88a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
89a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
90a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
91a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hidl_vec<uint8_t> vec;
92a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
93a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return vec;
94a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
95a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
96a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic String8 toString8(const hidl_string &string) {
97a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return String8(string.c_str());
98a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
99a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
100a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_string toHidlString(const String8& string) {
101a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hidl_string(string.string());
102a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
104fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stonestd::string ToHexString(const std::string& str) {
105fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone  std::ostringstream out;
106fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone  out << std::hex << std::setfill('0');
107fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone  for (size_t i = 0; i < str.size(); i++) {
108fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    out << std::setw(2) << (int)(str[i]);
109fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone  }
110fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone  return out.str();
111fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone}
112fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone
1136d998b67be330843f633a563c23c606593060165Jeff Tinkerstatic DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
1146d998b67be330843f633a563c23c606593060165Jeff Tinker    switch(level) {
1156d998b67be330843f633a563c23c606593060165Jeff Tinker    case SecurityLevel::SW_SECURE_CRYPTO:
1166d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kSecurityLevelSwSecureCrypto;
1176d998b67be330843f633a563c23c606593060165Jeff Tinker    case SecurityLevel::SW_SECURE_DECODE:
1186d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kSecurityLevelSwSecureDecode;
1196d998b67be330843f633a563c23c606593060165Jeff Tinker    case SecurityLevel::HW_SECURE_CRYPTO:
1206d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kSecurityLevelHwSecureCrypto;
1216d998b67be330843f633a563c23c606593060165Jeff Tinker    case SecurityLevel::HW_SECURE_DECODE:
1226d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kSecurityLevelHwSecureDecode;
1236d998b67be330843f633a563c23c606593060165Jeff Tinker    case SecurityLevel::HW_SECURE_ALL:
1246d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kSecurityLevelHwSecureAll;
1256d998b67be330843f633a563c23c606593060165Jeff Tinker    default:
1266d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kSecurityLevelUnknown;
1276d998b67be330843f633a563c23c606593060165Jeff Tinker    }
1286d998b67be330843f633a563c23c606593060165Jeff Tinker}
1296d998b67be330843f633a563c23c606593060165Jeff Tinker
1306d998b67be330843f633a563c23c606593060165Jeff Tinkerstatic DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
1316d998b67be330843f633a563c23c606593060165Jeff Tinker    switch(level) {
1326d998b67be330843f633a563c23c606593060165Jeff Tinker    case HdcpLevel::HDCP_NONE:
1336d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpNone;
1346d998b67be330843f633a563c23c606593060165Jeff Tinker    case HdcpLevel::HDCP_V1:
1356d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpV1;
1366d998b67be330843f633a563c23c606593060165Jeff Tinker    case HdcpLevel::HDCP_V2:
1376d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpV2;
1386d998b67be330843f633a563c23c606593060165Jeff Tinker    case HdcpLevel::HDCP_V2_1:
1396d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpV2_1;
1406d998b67be330843f633a563c23c606593060165Jeff Tinker    case HdcpLevel::HDCP_V2_2:
1416d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpV2_2;
1426d998b67be330843f633a563c23c606593060165Jeff Tinker    case HdcpLevel::HDCP_NO_OUTPUT:
1436d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpNoOutput;
1446d998b67be330843f633a563c23c606593060165Jeff Tinker    default:
1456d998b67be330843f633a563c23c606593060165Jeff Tinker        return DrmPlugin::kHdcpLevelUnknown;
1466d998b67be330843f633a563c23c606593060165Jeff Tinker    }
1476d998b67be330843f633a563c23c606593060165Jeff Tinker}
1486d998b67be330843f633a563c23c606593060165Jeff Tinker
149a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
150a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
151a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyedVector) {
152a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    std::vector<KeyValue> stdKeyedVector;
153a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < keyedVector.size(); i++) {
154a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        KeyValue keyValue;
155a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyValue.key = toHidlString(keyedVector.keyAt(i));
156a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyValue.value = toHidlString(keyedVector.valueAt(i));
157a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        stdKeyedVector.push_back(keyValue);
158a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
159a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return ::KeyedVector(stdKeyedVector);
160a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
161a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
162a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
163a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyedVector) {
164a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    KeyedVector<String8, String8> keyedVector;
165a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < hKeyedVector.size(); i++) {
166a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        keyedVector.add(toString8(hKeyedVector[i].key),
167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                toString8(hKeyedVector[i].value));
168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return keyedVector;
170a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
171a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
172abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatic List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
173a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hSecureStops) {
174abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    List<Vector<uint8_t>> secureStops;
175a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < hSecureStops.size(); i++) {
176a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secureStops.push_back(toVector(hSecureStops[i].opaqueData));
177a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return secureStops;
179a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
180a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
18115177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinkerstatic List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
18215177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        hSecureStopIds) {
18315177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    List<Vector<uint8_t>> secureStopIds;
18415177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    for (size_t i = 0; i < hSecureStopIds.size(); i++) {
18515177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        secureStopIds.push_back(toVector(hSecureStopIds[i]));
18615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
18715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    return secureStopIds;
18815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker}
18915177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
190a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic status_t toStatusT(Status status) {
191a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    switch (status) {
192a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::OK:
193a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return OK;
194a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
195a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_NO_LICENSE:
196a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_NO_LICENSE;
197a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
198a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_LICENSE_EXPIRED:
199a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_LICENSE_EXPIRED;
200a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
201a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_SESSION_NOT_OPENED:
202a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_SESSION_NOT_OPENED;
203a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
204a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_CANNOT_HANDLE:
205a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
206a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
207a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_INVALID_STATE:
208a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_TAMPER_DETECTED;
209a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
210a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::BAD_VALUE:
211a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return BAD_VALUE;
212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
213a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_NOT_PROVISIONED:
214a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_NOT_PROVISIONED;
215a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
216a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_RESOURCE_BUSY:
217a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_RESOURCE_BUSY;
218a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
219a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_DEVICE_REVOKED:
220a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_DEVICE_REVOKED;
221a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
222a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_UNKNOWN:
223a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
224a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_UNKNOWN;
225a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
226a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
227a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
228a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
229a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
230a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerMutex DrmHal::mLock;
231a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
232a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstruct DrmSessionClient : public DrmSessionClientInterface {
233a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
234a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
235a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
236a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        sp<DrmHal> drm = mDrm.promote();
237a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (drm == NULL) {
238a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            return true;
239a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
240a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        status_t err = drm->closeSession(sessionId);
241a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (err != OK) {
242a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            return false;
243a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
244a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        drm->sendEvent(EventType::SESSION_RECLAIMED,
245a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                toHidlVec(sessionId), hidl_vec<uint8_t>());
246a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return true;
247a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
248a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
249a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerprotected:
250a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    virtual ~DrmSessionClient() {}
251a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
252a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerprivate:
253a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    wp<DrmHal> mDrm;
254a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
255a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
256a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker};
257a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
258a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerDrmHal::DrmHal()
259a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker   : mDrmSessionClient(new DrmSessionClient(this)),
260abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker     mFactories(makeDrmFactories()),
261abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker     mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
262a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
263a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
2646133281c9b06c1d1176eca7f07401bba1067081eJeff Tinkervoid DrmHal::closeOpenSessions() {
2656133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    if (mPlugin != NULL) {
266b2b66fa4da5528cf9cdfc32f619e81e4d97ca654Jeff Tinker        for (size_t i = 0; i < mOpenSessions.size(); i++) {
267b2b66fa4da5528cf9cdfc32f619e81e4d97ca654Jeff Tinker            mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
268b2b66fa4da5528cf9cdfc32f619e81e4d97ca654Jeff Tinker            DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
2696133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        }
2706133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    }
2716133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    mOpenSessions.clear();
2726133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker}
2736133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker
274a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerDrmHal::~DrmHal() {
2756133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    closeOpenSessions();
276a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
277a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
278a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
279abeb36a8c2f044772297536e70340c3b245863e4Jeff TinkerVector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
280abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Vector<sp<IDrmFactory>> factories;
281c82b9c335e69b617817dace0ef64ad3df3f5080fJeff Tinker
282593111f4460f2b2e8f541e936670e3577d45fff6Jeff Tinker    auto manager = hardware::defaultServiceManager();
283c82b9c335e69b617817dace0ef64ad3df3f5080fJeff Tinker
284abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (manager != NULL) {
285e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker        manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
286abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                [&factories](const hidl_vec<hidl_string> &registered) {
287abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    for (const auto &instance : registered) {
288e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                        auto factory = drm::V1_0::IDrmFactory::getService(instance);
289abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        if (factory != NULL) {
290e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                            ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
291e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                            factories.push_back(factory);
292e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                        }
293e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                    }
294e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                }
295e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker            );
296e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker        manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
297e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                [&factories](const hidl_vec<hidl_string> &registered) {
298e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                    for (const auto &instance : registered) {
299e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                        auto factory = drm::V1_1::IDrmFactory::getService(instance);
300e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                        if (factory != NULL) {
301e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker                            ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
302abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            factories.push_back(factory);
303abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        }
304abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    }
305abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
306abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            );
307abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
308a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
309abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (factories.size() == 0) {
310abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        // must be in passthrough mode, load the default passthrough service
311e309b22bff1719f1fea84b247e4b2bc4c5f09eb5Jeff Tinker        auto passthrough = IDrmFactory::getService();
312abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (passthrough != NULL) {
313e307dc4e7b2c9d3c4018a755db687309cf590369Jeff Tinker            ALOGI("makeDrmFactories: using default passthrough drm instance");
314abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            factories.push_back(passthrough);
315abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        } else {
316abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGE("Failed to find any drm factories");
317abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
318a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
319abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return factories;
320abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker}
321abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
322abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkersp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
323abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        const uint8_t uuid[16], const String8& appPackageName) {
324fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    mMetrics.SetAppPackageName(appPackageName);
325a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
326a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmPlugin> plugin;
327abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
328a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const sp<IDrmPlugin>& hPlugin) {
329abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                if (status != Status::OK) {
330abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    ALOGE("Failed to make drm plugin");
331abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    return;
332abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
333abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                plugin = hPlugin;
334abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            }
335abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        );
336f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker
337f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker    if (!hResult.isOk()) {
338f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker        ALOGE("createPlugin remote call failed");
339f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker    }
340f0e89b0b248976f622fc41da4f678955399def08Jeff Tinker
341a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return plugin;
342a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
343a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
344a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::initCheck() const {
345a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
346a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
347a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
348a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setListener(const sp<IDrmClient>& listener)
349a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker{
350a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock lock(mEventLock);
351a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mListener != NULL){
352a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        IInterface::asBinder(mListener)->unlinkToDeath(this);
353a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
354a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
355a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        IInterface::asBinder(listener)->linkToDeath(this);
356a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
357a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mListener = listener;
358a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return NO_ERROR;
359a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
360a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
361a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerReturn<void> DrmHal::sendEvent(EventType hEventType,
362a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
363cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    mMetrics.mEventCounter.Increment(hEventType);
364a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
365a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.lock();
366a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmClient> listener = mListener;
367a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.unlock();
368a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
369a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
370a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Parcel obj;
371a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, sessionId);
372a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, data);
373a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
374a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
375a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        DrmPlugin::EventType eventType;
376a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        switch(hEventType) {
377a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::PROVISION_REQUIRED:
378a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
379a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
380a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::KEY_NEEDED:
381a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
382a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
383a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::KEY_EXPIRED:
384a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventKeyExpired;
385a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
386a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        case EventType::VENDOR_DEFINED:
387a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            eventType = DrmPlugin::kDrmPluginEventVendorDefined;
388a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            break;
389b86f4b3ce066eadbfe9c2f420b16aaf2de741edbRahul Frias        case EventType::SESSION_RECLAIMED:
390b86f4b3ce066eadbfe9c2f420b16aaf2de741edbRahul Frias            eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
391b86f4b3ce066eadbfe9c2f420b16aaf2de741edbRahul Frias            break;
392a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        default:
393a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            return Void();
394a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
395a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        listener->notify(eventType, 0, &obj);
396a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
397a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return Void();
398a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
399a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
400a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerReturn<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
401a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        int64_t expiryTimeInMS) {
402a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
403a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.lock();
404a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmClient> listener = mListener;
405a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.unlock();
406a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
407a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
408a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Parcel obj;
409a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, sessionId);
410a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt64(expiryTimeInMS);
411a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
412a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
413a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
414a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
415a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return Void();
416a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
417a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
418a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerReturn<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
419a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
420a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
421a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.lock();
422a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<IDrmClient> listener = mListener;
423a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mEventLock.unlock();
424a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
425a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (listener != NULL) {
426a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Parcel obj;
427a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        writeByteArray(obj, sessionId);
428a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
429a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        size_t nKeys = keyStatusList.size();
430a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(nKeys);
431a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        for (size_t i = 0; i < nKeys; ++i) {
432a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            const KeyStatus &keyStatus = keyStatusList[i];
433a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            writeByteArray(obj, keyStatus.keyId);
434a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            uint32_t type;
435a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            switch(keyStatus.type) {
436a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::USABLE:
437a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_Usable;
438a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
439a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::EXPIRED:
440a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_Expired;
441a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
442a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::OUTPUTNOTALLOWED:
443a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
444a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
445a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::STATUSPENDING:
446a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_StatusPending;
447a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
448a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            case KeyStatusType::INTERNALERROR:
449a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            default:
450a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                type = DrmPlugin::kKeyStatusType_InternalError;
451a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                break;
452a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
453a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            obj.writeInt32(type);
454cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone            mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
455a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
456a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(hasNewUsableKey);
457a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
458a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Mutex::Autolock lock(mNotifyLock);
459a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
460cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    } else {
461cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        // There's no listener. But we still want to count the key change
462cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        // events.
463cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        size_t nKeys = keyStatusList.size();
464cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        for (size_t i = 0; i < nKeys; i++) {
465cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone            mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
466cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        }
467a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
468cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone
469a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return Void();
470a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
471a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
472a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
473a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
474a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
475abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
476abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
477abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            if (mimeType != "") {
478abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
479abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    return true;
480abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
481abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            } else {
482abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                return true;
483abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            }
484a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
485a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
486abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return false;
487a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
488a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
48968b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wongstatus_t DrmHal::createPlugin(const uint8_t uuid[16],
49068b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        const String8& appPackageName) {
491a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
492a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
493abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
494abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
495abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
4965641aa251bf9a6e7b6bf8a73214f92e42c393a2fEdwin Wong            if (mPlugin != NULL) {
4975641aa251bf9a6e7b6bf8a73214f92e42c393a2fEdwin Wong                mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
4985641aa251bf9a6e7b6bf8a73214f92e42c393a2fEdwin Wong            }
499abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
500abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
501a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
502a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mPlugin == NULL) {
503a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = ERROR_UNSUPPORTED;
504a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
505319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (!mPlugin->setListener(this).isOk()) {
506319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = DEAD_OBJECT;
507319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        } else {
508319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = OK;
509319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        }
510a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
511a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
512a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
513a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
514a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
515a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::destroyPlugin() {
516a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
5176d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
518a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
5196133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    closeOpenSessions();
520fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    reportPluginMetrics();
521fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    reportFrameworkMetrics();
522a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    setListener(NULL);
523319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    mInitCheck = NO_INIT;
524319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker
52570367f525a7bf5be52115608d190d72756e972eaJeff Tinker    if (mPlugin != NULL) {
526319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (!mPlugin->setListener(NULL).isOk()) {
527319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = DEAD_OBJECT;
528319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        }
52970367f525a7bf5be52115608d190d72756e972eaJeff Tinker    }
530a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
5315641aa251bf9a6e7b6bf8a73214f92e42c393a2fEdwin Wong    mPluginV1_1.clear();
532a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
533a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
534a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
53541d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinkerstatus_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
53641d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        Vector<uint8_t> &sessionId) {
537a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
5386d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
539a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
54041d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    SecurityLevel hSecurityLevel;
54141d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    bool setSecurityLevel = true;
54241d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker
54341d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    switch(level) {
54441d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    case DrmPlugin::kSecurityLevelSwSecureCrypto:
54541d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
54641d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        break;
54741d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    case DrmPlugin::kSecurityLevelSwSecureDecode:
54841d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
54941d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        break;
55041d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    case DrmPlugin::kSecurityLevelHwSecureCrypto:
55141d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
55241d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        break;
55341d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    case DrmPlugin::kSecurityLevelHwSecureDecode:
55441d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
55541d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        break;
55641d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    case DrmPlugin::kSecurityLevelHwSecureAll:
55741d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
55841d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        break;
55941d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    case DrmPlugin::kSecurityLevelMax:
56041d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        setSecurityLevel = false;
56141d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        break;
56241d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    default:
56341d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
56441d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    }
5655f5e43fa83551a3636b92871bd2ad6b260a8815bTobias Thierer
56641d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker    status_t  err = UNKNOWN_ERROR;
567a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool retry = true;
568a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    do {
569a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hidl_vec<uint8_t> hSessionId;
570a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
57141d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        Return<void> hResult;
57241d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        if (mPluginV1_1 == NULL || !setSecurityLevel) {
57341d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker            hResult = mPlugin->openSession(
57441d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                    [&](Status status,const hidl_vec<uint8_t>& id) {
57541d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                        if (status == Status::OK) {
57641d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                            sessionId = toVector(id);
57741d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                        }
57841d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                        err = toStatusT(status);
57956134cc9e790f39b3b10a18b701b0607c20b6154Jeff Tinker                    }
58041d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                );
58141d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        } else {
58241d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker            hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
58341d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                    [&](Status status, const hidl_vec<uint8_t>& id) {
58441d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                        if (status == Status::OK) {
58541d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                            sessionId = toVector(id);
58641d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                        }
58741d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                        err = toStatusT(status);
58841d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                    }
58941d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker                );
59041d279a7f3bc55a63b510d4dce07e18964cda152Jeff Tinker        }
591a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
592a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (!hResult.isOk()) {
593a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            err = DEAD_OBJECT;
594a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
595a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
596a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
597a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            mLock.unlock();
598a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            // reclaimSession may call back to closeSession, since mLock is
599a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            // shared between Drm instances, we should unlock here to avoid
600a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            // deadlock.
601a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
602a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            mLock.lock();
603a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        } else {
604a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            retry = false;
605a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        }
606a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } while (retry);
607a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
608a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (err == OK) {
609a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        DrmSessionManager::Instance()->addSession(getCallingPid(),
610a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                mDrmSessionClient, sessionId);
6116133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        mOpenSessions.push(sessionId);
612568b3c45d48fab64c80b2780e8547564d35722e9Adam Stone        mMetrics.SetSessionStart(sessionId);
613a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
614aaf87dd09686bdb47df0a638b622a4c2ea37a331Adam Stone
615f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone    mMetrics.mOpenSessionCounter.Increment(err);
616a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return err;
617a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
618a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
619a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
620a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
6216d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
622a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
623319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
624319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    if (status.isOk()) {
625319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (status == Status::OK) {
626319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            DrmSessionManager::Instance()->removeSession(sessionId);
627319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            for (size_t i = 0; i < mOpenSessions.size(); i++) {
628319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                if (mOpenSessions[i] == sessionId) {
629319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                    mOpenSessions.removeAt(i);
630319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                    break;
631319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker                }
6326133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker            }
6336133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker        }
634cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        status_t response = toStatusT(status);
635568b3c45d48fab64c80b2780e8547564d35722e9Adam Stone        mMetrics.SetSessionEnd(sessionId);
636cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        mMetrics.mCloseSessionCounter.Increment(response);
637fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        reportPluginMetrics();
638cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        return response;
639a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
640cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
641319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    return DEAD_OBJECT;
642a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
643a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
644a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
645a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Vector<uint8_t> const &initData, String8 const &mimeType,
646a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        DrmPlugin::KeyType keyType, KeyedVector<String8,
647a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8> const &optionalParameters, Vector<uint8_t> &request,
648a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
649a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
6506d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
651fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
652a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
653a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
654a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
655a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    KeyType hKeyType;
656a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (keyType == DrmPlugin::kKeyType_Streaming) {
657a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyType = KeyType::STREAMING;
658a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else if (keyType == DrmPlugin::kKeyType_Offline) {
659a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyType = KeyType::OFFLINE;
660a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else if (keyType == DrmPlugin::kKeyType_Release) {
661a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hKeyType = KeyType::RELEASE;
662a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
663f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone        keyRequestTimer.SetAttribute(BAD_VALUE);
664a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return BAD_VALUE;
665a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
666a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
667a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
668a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
669a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
670a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
67159bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias    if (mPluginV1_1 != NULL) {
67259bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias        Return<void> hResult =
67359bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias            mPluginV1_1->getKeyRequest_1_1(
67459bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                toHidlVec(sessionId), toHidlVec(initData),
67559bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                toHidlString(mimeType), hKeyType, hOptionalParameters,
67659bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                [&](Status status, const hidl_vec<uint8_t>& hRequest,
67759bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    drm::V1_1::KeyRequestType hKeyRequestType,
67859bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    const hidl_string& hDefaultUrl) {
67959bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias
68059bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias            if (status == Status::OK) {
68159bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                request = toVector(hRequest);
68259bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                defaultUrl = toString8(hDefaultUrl);
68359bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias
68459bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                switch (hKeyRequestType) {
68559bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_1::KeyRequestType::INITIAL:
68659bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
68759bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        break;
68859bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_1::KeyRequestType::RENEWAL:
68959bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
69059bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        break;
69159bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_1::KeyRequestType::RELEASE:
69259bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
69359bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        break;
69459bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_1::KeyRequestType::NONE:
69559bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        *keyRequestType = DrmPlugin::kKeyRequestType_None;
69659bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        break;
69759bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_1::KeyRequestType::UPDATE:
69859bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        *keyRequestType = DrmPlugin::kKeyRequestType_Update;
69959bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        break;
70059bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    default:
70159bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
70259bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                        break;
70359bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                }
70459bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                err = toStatusT(status);
70559bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias            }
70659bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias        });
70759bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias        return hResult.isOk() ? err : DEAD_OBJECT;
70859bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias    }
70959bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias
710a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
711a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
712a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hRequest,
71359bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    drm::V1_0::KeyRequestType hKeyRequestType,
71459bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    const hidl_string& hDefaultUrl) {
715a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
716a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
717a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    request = toVector(hRequest);
718a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    defaultUrl = toString8(hDefaultUrl);
719a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
720a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    switch (hKeyRequestType) {
72159bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_0::KeyRequestType::INITIAL:
722a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
723a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
72459bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_0::KeyRequestType::RENEWAL:
725a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
726a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
72759bc3fa914467f37c32aea1963e9354355b244e7Rahul Frias                    case drm::V1_0::KeyRequestType::RELEASE:
728a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Release;
729a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
730a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    default:
731a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
732a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                        break;
733a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    }
734a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    err = toStatusT(status);
735a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
736a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            });
737a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
738f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone    err = hResult.isOk() ? err : DEAD_OBJECT;
739f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone    keyRequestTimer.SetAttribute(err);
740f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone    return err;
741a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
742a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
743a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
744a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
745a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
746fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
747cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone
7486d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
749a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
750a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
751a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
752a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
753a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
754a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
755a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(response),
756a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
757a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
758a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    keySetId = toVector(hKeySetId);
759a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
760a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
761a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
762a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
763cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    err = hResult.isOk() ? err : DEAD_OBJECT;
764cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    keyResponseTimer.SetAttribute(err);
765cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    return err;
766a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
767a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
768a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
769a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
7706d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
771a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
772a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
773a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
774a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
775a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
776a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        Vector<uint8_t> const &keySetId) {
777a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
7786d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
779a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
780a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
781a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
782a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
783a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    toHidlVec(keySetId)));
784a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
785a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
786a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
787a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        KeyedVector<String8, String8> &infoMap) const {
788a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
7896d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
790a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
791a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
792a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
793a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::KeyedVector hInfoMap;
794a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
795a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
796a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
797a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
798a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<KeyValue>& map) {
799a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
800a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    infoMap = toKeyedVector(map);
801a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
802a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
803a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
804a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
805a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
806a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
807a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
808a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
809a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getProvisionRequest(String8 const &certType,
810a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8 const &certAuthority, Vector<uint8_t> &request,
811a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        String8 &defaultUrl) {
812a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
8136d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
814a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
815a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
816a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
817a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getProvisionRequest(
818a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(certType), toHidlString(certAuthority),
819a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hRequest,
820a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    const hidl_string& hDefaultUrl) {
821a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
822a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    request = toVector(hRequest);
823a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    defaultUrl = toString8(hDefaultUrl);
824a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
825a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
826a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
827a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
828a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
829cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    err = hResult.isOk() ? err : DEAD_OBJECT;
830cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    mMetrics.mGetProvisionRequestCounter.Increment(err);
831cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    return err;
832a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
833a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
834a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
83568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
836a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
8376d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
838a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
839a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
840a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
841a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
842a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hCertificate,
843a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    const hidl_vec<uint8_t>& hWrappedKey) {
844a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
845a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    certificate = toVector(hCertificate);
846a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    wrappedKey = toVector(hWrappedKey);
847a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
848a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
849a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
850a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
851a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
852cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    err = hResult.isOk() ? err : DEAD_OBJECT;
853cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    mMetrics.mProvideProvisionResponseCounter.Increment(err);
854cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    return err;
855a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
856a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
857abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatus_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
858a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
8596d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
860a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
861a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
862a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
863a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getSecureStops(
864a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
865a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
866a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    secureStops = toSecureStops(hSecureStops);
867a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
868a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
869a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
870a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
871a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
872a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
873a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
874a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
875a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
87615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinkerstatus_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
87715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    Mutex::Autolock autoLock(mLock);
87815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
87915177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    if (mInitCheck != OK) {
88015177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        return mInitCheck;
88115177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
88215177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
88315177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    if (mPluginV1_1 == NULL) {
88415177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
88515177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
88615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
88715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    status_t err = UNKNOWN_ERROR;
88815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
88915177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    Return<void> hResult = mPluginV1_1->getSecureStopIds(
89015177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker            [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
89115177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker                if (status == Status::OK) {
89215177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker                    secureStopIds = toSecureStopIds(hSecureStopIds);
89315177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker                }
89415177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker                err = toStatusT(status);
89515177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker            }
89615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    );
89715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
89815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
89915177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker}
90015177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
90115177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
902a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
903a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
9046d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
905a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
906a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
907a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
908a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
909a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const SecureStop& hSecureStop) {
910a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
911a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    secureStop = toVector(hSecureStop.opaqueData);
912a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
913a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
914a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
915a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
916a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
917a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
918a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
919a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
920a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
921a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
9226d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
923a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
92415177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    if (mPluginV1_1 != NULL) {
92515177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        SecureStopRelease secureStopRelease;
92615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        secureStopRelease.opaqueData = toHidlVec(ssRelease);
92715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
92815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
92915177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
930a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
931a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
932a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
93315177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinkerstatus_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
93415177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    Mutex::Autolock autoLock(mLock);
93515177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
93615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    if (mInitCheck != OK) {
93715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        return mInitCheck;
93815177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
93915177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
94015177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    if (mPluginV1_1 == NULL) {
94115177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
94215177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
94315177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
94415177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
94515177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker}
94615177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker
94715177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinkerstatus_t DrmHal::removeAllSecureStops() {
948a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
9496d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
950a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
95115177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    if (mPluginV1_1 != NULL) {
95215177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker        return toStatusT(mPluginV1_1->removeAllSecureStops());
95315177d7eab8c2300b4f1d577267e528bd7e4eedcJeff Tinker    }
9546d998b67be330843f633a563c23c606593060165Jeff Tinker    return toStatusT(mPlugin->releaseAllSecureStops());
9556d998b67be330843f633a563c23c606593060165Jeff Tinker}
9566d998b67be330843f633a563c23c606593060165Jeff Tinker
9576d998b67be330843f633a563c23c606593060165Jeff Tinkerstatus_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
9586d998b67be330843f633a563c23c606593060165Jeff Tinker            DrmPlugin::HdcpLevel *max) const {
9596d998b67be330843f633a563c23c606593060165Jeff Tinker    Mutex::Autolock autoLock(mLock);
9606d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
9616d998b67be330843f633a563c23c606593060165Jeff Tinker
9626d998b67be330843f633a563c23c606593060165Jeff Tinker    if (connected == NULL || max == NULL) {
9636d998b67be330843f633a563c23c606593060165Jeff Tinker        return BAD_VALUE;
964a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
9656d998b67be330843f633a563c23c606593060165Jeff Tinker    status_t err = UNKNOWN_ERROR;
966a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
9676d998b67be330843f633a563c23c606593060165Jeff Tinker    if (mPluginV1_1 == NULL) {
9686d998b67be330843f633a563c23c606593060165Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
9696d998b67be330843f633a563c23c606593060165Jeff Tinker    }
9706d998b67be330843f633a563c23c606593060165Jeff Tinker
9716d998b67be330843f633a563c23c606593060165Jeff Tinker    *connected = DrmPlugin::kHdcpLevelUnknown;
9726d998b67be330843f633a563c23c606593060165Jeff Tinker    *max = DrmPlugin::kHdcpLevelUnknown;
9736d998b67be330843f633a563c23c606593060165Jeff Tinker
9746d998b67be330843f633a563c23c606593060165Jeff Tinker    Return<void> hResult = mPluginV1_1->getHdcpLevels(
9756d998b67be330843f633a563c23c606593060165Jeff Tinker            [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
9766d998b67be330843f633a563c23c606593060165Jeff Tinker                if (status == Status::OK) {
9776d998b67be330843f633a563c23c606593060165Jeff Tinker                    *connected = toHdcpLevel(hConnected);
9786d998b67be330843f633a563c23c606593060165Jeff Tinker                    *max = toHdcpLevel(hMax);
9796d998b67be330843f633a563c23c606593060165Jeff Tinker                }
9806d998b67be330843f633a563c23c606593060165Jeff Tinker                err = toStatusT(status);
9816d998b67be330843f633a563c23c606593060165Jeff Tinker            }
9826d998b67be330843f633a563c23c606593060165Jeff Tinker    );
9836d998b67be330843f633a563c23c606593060165Jeff Tinker
9846d998b67be330843f633a563c23c606593060165Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
9856d998b67be330843f633a563c23c606593060165Jeff Tinker}
9866d998b67be330843f633a563c23c606593060165Jeff Tinker
9876d998b67be330843f633a563c23c606593060165Jeff Tinkerstatus_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
9886d998b67be330843f633a563c23c606593060165Jeff Tinker    Mutex::Autolock autoLock(mLock);
9896d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
9906d998b67be330843f633a563c23c606593060165Jeff Tinker
9916d998b67be330843f633a563c23c606593060165Jeff Tinker    if (open == NULL || max == NULL) {
9926d998b67be330843f633a563c23c606593060165Jeff Tinker        return BAD_VALUE;
9936d998b67be330843f633a563c23c606593060165Jeff Tinker    }
9946d998b67be330843f633a563c23c606593060165Jeff Tinker    status_t err = UNKNOWN_ERROR;
9956d998b67be330843f633a563c23c606593060165Jeff Tinker
9966d998b67be330843f633a563c23c606593060165Jeff Tinker    *open = 0;
9976d998b67be330843f633a563c23c606593060165Jeff Tinker    *max = 0;
9986d998b67be330843f633a563c23c606593060165Jeff Tinker
9996d998b67be330843f633a563c23c606593060165Jeff Tinker    if (mPluginV1_1 == NULL) {
10006d998b67be330843f633a563c23c606593060165Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
10016d998b67be330843f633a563c23c606593060165Jeff Tinker    }
10026d998b67be330843f633a563c23c606593060165Jeff Tinker
10036d998b67be330843f633a563c23c606593060165Jeff Tinker    Return<void> hResult = mPluginV1_1->getNumberOfSessions(
10046d998b67be330843f633a563c23c606593060165Jeff Tinker            [&](Status status, uint32_t hOpen, uint32_t hMax) {
10056d998b67be330843f633a563c23c606593060165Jeff Tinker                if (status == Status::OK) {
10066d998b67be330843f633a563c23c606593060165Jeff Tinker                    *open = hOpen;
10076d998b67be330843f633a563c23c606593060165Jeff Tinker                    *max = hMax;
10086d998b67be330843f633a563c23c606593060165Jeff Tinker                }
10096d998b67be330843f633a563c23c606593060165Jeff Tinker                err = toStatusT(status);
10106d998b67be330843f633a563c23c606593060165Jeff Tinker            }
10116d998b67be330843f633a563c23c606593060165Jeff Tinker    );
10126d998b67be330843f633a563c23c606593060165Jeff Tinker
10136d998b67be330843f633a563c23c606593060165Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
10146d998b67be330843f633a563c23c606593060165Jeff Tinker}
10156d998b67be330843f633a563c23c606593060165Jeff Tinker
10166d998b67be330843f633a563c23c606593060165Jeff Tinkerstatus_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
10176d998b67be330843f633a563c23c606593060165Jeff Tinker        DrmPlugin::SecurityLevel *level) const {
10186d998b67be330843f633a563c23c606593060165Jeff Tinker    Mutex::Autolock autoLock(mLock);
10196d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
10206d998b67be330843f633a563c23c606593060165Jeff Tinker
10216d998b67be330843f633a563c23c606593060165Jeff Tinker    if (level == NULL) {
10226d998b67be330843f633a563c23c606593060165Jeff Tinker        return BAD_VALUE;
10236d998b67be330843f633a563c23c606593060165Jeff Tinker    }
10246d998b67be330843f633a563c23c606593060165Jeff Tinker    status_t err = UNKNOWN_ERROR;
10256d998b67be330843f633a563c23c606593060165Jeff Tinker
10266d998b67be330843f633a563c23c606593060165Jeff Tinker    if (mPluginV1_1 == NULL) {
10276d998b67be330843f633a563c23c606593060165Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
10286d998b67be330843f633a563c23c606593060165Jeff Tinker    }
10296d998b67be330843f633a563c23c606593060165Jeff Tinker
10306d998b67be330843f633a563c23c606593060165Jeff Tinker    *level = DrmPlugin::kSecurityLevelUnknown;
10316d998b67be330843f633a563c23c606593060165Jeff Tinker
10326d998b67be330843f633a563c23c606593060165Jeff Tinker    Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
10336d998b67be330843f633a563c23c606593060165Jeff Tinker            [&](Status status, SecurityLevel hLevel) {
10346d998b67be330843f633a563c23c606593060165Jeff Tinker                if (status == Status::OK) {
10356d998b67be330843f633a563c23c606593060165Jeff Tinker                    *level = toSecurityLevel(hLevel);
10366d998b67be330843f633a563c23c606593060165Jeff Tinker                }
10376d998b67be330843f633a563c23c606593060165Jeff Tinker                err = toStatusT(status);
10386d998b67be330843f633a563c23c606593060165Jeff Tinker            }
10396d998b67be330843f633a563c23c606593060165Jeff Tinker    );
10406d998b67be330843f633a563c23c606593060165Jeff Tinker
10416d998b67be330843f633a563c23c606593060165Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
10426d998b67be330843f633a563c23c606593060165Jeff Tinker}
10436d998b67be330843f633a563c23c606593060165Jeff Tinker
1044a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1045a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
104633ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    return getPropertyStringInternal(name, value);
104733ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce}
104833ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce
104933ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Brucestatus_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
105033ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // This function is internal to the class and should only be called while
105133ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // mLock is already held.
10526d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1053a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1054a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
1055a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1056a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1057a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_string& hValue) {
1058a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1059a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    value = toString8(hValue);
1060a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1061a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1062a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1063a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
1064a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1065a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1066a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1067a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1068a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1069a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
107033ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    return getPropertyByteArrayInternal(name, value);
107133ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce}
107233ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce
107333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Brucestatus_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
107433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // This function is internal to the class and should only be called while
107533ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    // mLock is already held.
10766d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1077a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1078a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
1079a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1080a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1081a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hValue) {
1082a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1083a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    value = toVector(hValue);
1084a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1085a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1086a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1087a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
1088a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1089cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    err = hResult.isOk() ? err : DEAD_OBJECT;
1090cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    if (name == kPropertyDeviceUniqueId) {
1091cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone        mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1092cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    }
1093cea91ce60260d7ebb94449ad7674150fdc227886Adam Stone    return err;
1094a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1095a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1096a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1097a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
10986d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1099a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
11006d998b67be330843f633a563c23c606593060165Jeff Tinker    Status status = mPlugin->setPropertyString(toHidlString(name),
1101a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(value));
1102a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
1103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1104a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1105a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setPropertyByteArray(String8 const &name,
1106a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                                   Vector<uint8_t> const &value ) const {
1107a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
11086d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1109a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1111a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(value));
1112a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
1113a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1114a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
111528f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stonestatus_t DrmHal::getMetrics(PersistableBundle* metrics) {
111628f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone    if (metrics == nullptr) {
111728f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        return UNEXPECTED_NULL;
111828f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone    }
111928f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone    mMetrics.Export(metrics);
112028f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone
112128f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone    // Append vendor metrics if they are supported.
112228f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone    if (mPluginV1_1 != NULL) {
112328f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        String8 vendor;
112428f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        String8 description;
112528f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        if (getPropertyStringInternal(String8("vendor"), vendor) != OK
112628f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone            || vendor.isEmpty()) {
112728f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone          ALOGE("Get vendor failed or is empty");
112828f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone          vendor = "NONE";
112928f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        }
113028f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        if (getPropertyStringInternal(String8("description"), description) != OK
113128f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone            || description.isEmpty()) {
113228f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone          ALOGE("Get description failed or is empty.");
113328f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone          description = "NONE";
113428f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        }
113528f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        vendor += ".";
113628f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        vendor += description;
113728f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone
113828f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        hidl_vec<DrmMetricGroup> pluginMetrics;
113928f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        status_t err = UNKNOWN_ERROR;
114028f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone
114128f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        Return<void> status = mPluginV1_1->getMetrics(
114228f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
114328f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                    if (status != Status::OK) {
114428f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                      ALOGV("Error getting plugin metrics: %d", status);
114528f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                    } else {
114628f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                        PersistableBundle pluginBundle;
114728f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                        if (MediaDrmMetrics::HidlMetricsToBundle(
114828f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                                pluginMetrics, &pluginBundle) == OK) {
114928f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                            metrics->putPersistableBundle(String16(vendor), pluginBundle);
115028f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                        }
115128f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                    }
115228f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                    err = toStatusT(status);
115328f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone                });
115428f27c3bee88b0f47b1086feeaa904bcdec37af6Adam Stone        return status.isOk() ? err : DEAD_OBJECT;
1155f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone    }
1156f0e618d0ee16c63f918c7bb87ec1ff264d177746Adam Stone
1157ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone    return OK;
1158ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone}
1159a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1160a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1161a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                                 String8 const &algorithm) {
1162a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
11636d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1164a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1165a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1166a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(algorithm));
1169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
1170a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1171a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1172a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1173a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                              String8 const &algorithm) {
1174a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
11756d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1176a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1177a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1179a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1180a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(algorithm));
1181a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(status);
1182a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1183a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1184a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
118568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
118668b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1187a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
11886d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1189a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1190a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1191a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1192a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
1193a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1194a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1195a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1196a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1197a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1198a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    output = toVector(hOutput);
1199a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1200a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1201a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1202a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
1203a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1204a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1205a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1206a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1207a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
120868b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
120968b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1210a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
12116d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1213a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1214a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1215a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t  err = UNKNOWN_ERROR;
1216a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1217a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1218a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1219a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1220a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1221a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    output = toVector(hOutput);
1222a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1223a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1224a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1225a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
1226a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1227a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1228a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1229a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1230a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::sign(Vector<uint8_t> const &sessionId,
123168b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
123268b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> &signature) {
1233a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
12346d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1235a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1236a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1237a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1238a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
1239a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1240a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1241a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(keyId), toHidlVec(message),
1242a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
1243a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1244a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    signature = toVector(hSignature);
1245a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1246a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1247a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1248a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
1249a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1250a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1251a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1252a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1253a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::verify(Vector<uint8_t> const &sessionId,
125468b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
125568b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &signature, bool &match) {
1256a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
12576d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1258a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1259a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1260a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1261a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
1262a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1263a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1264a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(message), toHidlVec(signature),
1265a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, bool hMatch) {
1266a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1267a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    match = hMatch;
1268a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                } else {
1269a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    match = false;
1270a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1271a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1272a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1273a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    );
1274a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1275a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1276a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1277a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1278a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
127968b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        String8 const &algorithm, Vector<uint8_t> const &message,
128068b3d9f49e68a11af5225175dc9e60ce88819e84Edwin Wong        Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
1281a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
12826d998b67be330843f633a563c23c606593060165Jeff Tinker    INIT_CHECK();
1283a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1284a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1285a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return -EPERM;
1286a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
1287a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1288a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    DrmSessionManager::Instance()->useSession(sessionId);
1289a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1290a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
1291a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1292a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1293a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1294a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1295a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
1296a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    signature = toVector(hSignature);
1297a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
1298a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
1299a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
1300a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
1301a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1302a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hResult.isOk() ? err : DEAD_OBJECT;
1303a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1304a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1305a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1306a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker{
1307a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
13086133281c9b06c1d1176eca7f07401bba1067081eJeff Tinker    closeOpenSessions();
13093e2891674ef57a74e59ca5e27f89647b3f06861bJeff Tinker    setListener(NULL);
1310319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker    mInitCheck = NO_INIT;
1311319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker
131270367f525a7bf5be52115608d190d72756e972eaJeff Tinker    if (mPlugin != NULL) {
1313319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        if (!mPlugin->setListener(NULL).isOk()) {
1314319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker            mInitCheck = DEAD_OBJECT;
1315319d5f43d196ca1fc26c5d6169ae0bdd14a81d54Jeff Tinker        }
131670367f525a7bf5be52115608d190d72756e972eaJeff Tinker    }
1317a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
1318a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1319a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1320a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1321a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker{
1322a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (vec.size()) {
1323a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(vec.size());
1324a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.write(vec.data(), vec.size());
1325a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
1326a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        obj.writeInt32(0);
1327a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
1328a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
1329a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
1330fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stonevoid DrmHal::reportFrameworkMetrics() const
1331fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone{
1332fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    MediaAnalyticsItem item("mediadrm");
1333fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    item.generateSessionID();
1334fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    item.setPkgName(mMetrics.GetAppPackageName().c_str());
1335fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    String8 vendor;
1336fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    String8 description;
1337fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1338fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    if (result != OK) {
1339fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        ALOGE("Failed to get vendor from drm plugin. %d", result);
1340fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    } else {
1341fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        item.setCString("vendor", vendor.c_str());
1342fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    }
1343fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    result = getPropertyStringInternal(String8("description"), description);
1344fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    if (result != OK) {
1345fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        ALOGE("Failed to get description from drm plugin. %d", result);
1346fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    } else {
1347fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        item.setCString("description", description.c_str());
1348fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    }
1349fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone
1350fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    std::string serializedMetrics;
1351fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1352fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    if (result != OK) {
1353fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        ALOGE("Failed to serialize Framework metrics: %d", result);
1354fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    }
1355fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    serializedMetrics = ToHexString(serializedMetrics);
1356fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    if (!serializedMetrics.empty()) {
1357fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        item.setCString("serialized_metrics", serializedMetrics.c_str());
1358fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    }
1359fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    if (!item.selfrecord()) {
1360fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone        ALOGE("Failed to self record framework metrics.");
1361fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone    }
1362fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stone}
1363ab394d13bab3a84f23677357576cee7a6f0c7899Adam Stone
1364fb679e38bbc91614faa917024adddeb51ff07d0aAdam Stonevoid DrmHal::reportPluginMetrics() const
136533ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce{
136633ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    Vector<uint8_t> metrics;
136733ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    String8 vendor;
136833ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    String8 description;
136933ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
137033ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce            getPropertyStringInternal(String8("description"), description) == OK &&
137133ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce            getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
137233ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce        status_t res = android::reportDrmPluginMetrics(
137333ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce                metrics, vendor, description);
137433ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce        if (res != OK) {
137533ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce            ALOGE("Metrics were retrieved but could not be reported: %i", res);
137633ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce        }
137733ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce    }
137833ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce}
137933ecc4f6b0e53ea7088ff4f151323e29183070c5John W. Bruce
1380a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}  // namespace android
1381