blob: 757ccdaf951cf166e34b4096599138f9de8e4d0f [file] [log] [blame]
Jeff Tinkera53d6552017-01-20 00:31:46 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmHal"
Adam Stonefb679e32018-02-07 10:25:48 -080019#include <iomanip>
20
Jeff Tinkera53d6552017-01-20 00:31:46 -080021#include <utils/Log.h>
22
Robert Shih6152d7c2019-11-19 22:54:27 -080023#include <android/binder_manager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080024
Robert Shih0f3a8a02019-11-14 15:43:39 -080025#include <aidl/android/media/BnResourceManagerClient.h>
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070026#include <android/hardware/drm/1.2/types.h>
Peter Kalauskasca5642c2018-11-12 12:34:42 -080027#include <android/hidl/manager/1.2/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070028#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080029#include <media/EventMetric.h>
Robert Shih82ea6be2019-11-07 17:47:23 -080030#include <media/MediaMetrics.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070031#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080032#include <media/drm/DrmAPI.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080035#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080036#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080038#include <mediadrm/DrmHal.h>
39#include <mediadrm/DrmSessionClientInterface.h>
40#include <mediadrm/DrmSessionManager.h>
Robert Shih93538812019-11-12 12:21:35 -080041#include <mediadrm/IDrmMetricsConsumer.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080042
Robert Shih61e1c762019-10-31 21:26:58 -070043#include <vector>
44
Jeff Tinker6d998b62017-12-18 14:37:43 -080045using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080046using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_0::KeyType;
48using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080049using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080050using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080051using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070052using drm::V1_1::HdcpLevel;
53using drm::V1_1::SecureStopRelease;
54using drm::V1_1::SecurityLevel;
55using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070056using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080057using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080058using ::android::hardware::hidl_array;
59using ::android::hardware::hidl_string;
60using ::android::hardware::hidl_vec;
61using ::android::hardware::Return;
62using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080063using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080064using ::android::sp;
65
Jeff Tinkerb8684f32018-12-12 08:41:31 -080066typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
67typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080068typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080069
Adam Stonecea91ce2018-01-22 19:23:28 -080070namespace {
71
72// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
73// in the MediaDrm API.
74constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080075constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080076
Adam Stone32494f52018-02-26 22:53:27 -080077template<typename T>
78std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070079 // Note that the base 64 conversion only works with arrays of single-byte
80 // values. If the source is empty or is not an array of single-byte values,
81 // return empty string.
82 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080083 return "";
84 }
Adam Stone32494f52018-02-26 22:53:27 -080085
86 android::AString outputString;
87 encodeBase64(data, size, &outputString);
88 // Remove trailing equals padding if it exists.
89 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
90 outputString.erase(outputString.size() - 1, 1);
91 }
92
93 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080094}
95
Adam Stone32494f52018-02-26 22:53:27 -080096} // anonymous namespace
97
Jeff Tinkera53d6552017-01-20 00:31:46 -080098namespace android {
99
Jeff Tinker6d998b62017-12-18 14:37:43 -0800100#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
101
Jeff Tinkera53d6552017-01-20 00:31:46 -0800102static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
103 Vector<uint8_t> vector;
104 vector.appendArray(vec.data(), vec.size());
105 return *const_cast<const Vector<uint8_t> *>(&vector);
106}
107
108static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
109 hidl_vec<uint8_t> vec;
110 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
111 return vec;
112}
113
114static String8 toString8(const hidl_string &string) {
115 return String8(string.c_str());
116}
117
118static hidl_string toHidlString(const String8& string) {
119 return hidl_string(string.string());
120}
121
Jeff Tinker6d998b62017-12-18 14:37:43 -0800122static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
123 switch(level) {
124 case SecurityLevel::SW_SECURE_CRYPTO:
125 return DrmPlugin::kSecurityLevelSwSecureCrypto;
126 case SecurityLevel::SW_SECURE_DECODE:
127 return DrmPlugin::kSecurityLevelSwSecureDecode;
128 case SecurityLevel::HW_SECURE_CRYPTO:
129 return DrmPlugin::kSecurityLevelHwSecureCrypto;
130 case SecurityLevel::HW_SECURE_DECODE:
131 return DrmPlugin::kSecurityLevelHwSecureDecode;
132 case SecurityLevel::HW_SECURE_ALL:
133 return DrmPlugin::kSecurityLevelHwSecureAll;
134 default:
135 return DrmPlugin::kSecurityLevelUnknown;
136 }
137}
138
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800139static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
140 switch(level) {
141 case DrmPlugin::kSecurityLevelSwSecureCrypto:
142 return SecurityLevel::SW_SECURE_CRYPTO;
143 case DrmPlugin::kSecurityLevelSwSecureDecode:
144 return SecurityLevel::SW_SECURE_DECODE;
145 case DrmPlugin::kSecurityLevelHwSecureCrypto:
146 return SecurityLevel::HW_SECURE_CRYPTO;
147 case DrmPlugin::kSecurityLevelHwSecureDecode:
148 return SecurityLevel::HW_SECURE_DECODE;
149 case DrmPlugin::kSecurityLevelHwSecureAll:
150 return SecurityLevel::HW_SECURE_ALL;
151 default:
152 return SecurityLevel::UNKNOWN;
153 }
154}
155
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700156static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
157 OfflineLicenseState licenseState) {
158 switch(licenseState) {
159 case OfflineLicenseState::USABLE:
160 return DrmPlugin::kOfflineLicenseStateUsable;
161 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800162 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700163 default:
164 return DrmPlugin::kOfflineLicenseStateUnknown;
165 }
166}
167
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800168static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800169 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800170 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800171 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800172 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800173 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800174 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800175 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800176 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800177 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800178 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800179 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800180 case HdcpLevel_V1_2::HDCP_V2_3:
181 return DrmPlugin::kHdcpV2_3;
182 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800183 return DrmPlugin::kHdcpNoOutput;
184 default:
185 return DrmPlugin::kHdcpLevelUnknown;
186 }
187}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800188static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
189 keyedVector) {
190 std::vector<KeyValue> stdKeyedVector;
191 for (size_t i = 0; i < keyedVector.size(); i++) {
192 KeyValue keyValue;
193 keyValue.key = toHidlString(keyedVector.keyAt(i));
194 keyValue.value = toHidlString(keyedVector.valueAt(i));
195 stdKeyedVector.push_back(keyValue);
196 }
197 return ::KeyedVector(stdKeyedVector);
198}
199
200static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
201 hKeyedVector) {
202 KeyedVector<String8, String8> keyedVector;
203 for (size_t i = 0; i < hKeyedVector.size(); i++) {
204 keyedVector.add(toString8(hKeyedVector[i].key),
205 toString8(hKeyedVector[i].value));
206 }
207 return keyedVector;
208}
209
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800210static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800211 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800212 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800213 for (size_t i = 0; i < hSecureStops.size(); i++) {
214 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
215 }
216 return secureStops;
217}
218
Jeff Tinker15177d72018-01-25 12:57:55 -0800219static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
220 hSecureStopIds) {
221 List<Vector<uint8_t>> secureStopIds;
222 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
223 secureStopIds.push_back(toVector(hSecureStopIds[i]));
224 }
225 return secureStopIds;
226}
227
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700228static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
229 hKeySetIds) {
230 List<Vector<uint8_t>> keySetIds;
231 for (size_t i = 0; i < hKeySetIds.size(); i++) {
232 keySetIds.push_back(toVector(hKeySetIds[i]));
233 }
234 return keySetIds;
235}
236
Jeff Tinkera53d6552017-01-20 00:31:46 -0800237static status_t toStatusT(Status status) {
238 switch (status) {
239 case Status::OK:
240 return OK;
241 break;
242 case Status::ERROR_DRM_NO_LICENSE:
243 return ERROR_DRM_NO_LICENSE;
244 break;
245 case Status::ERROR_DRM_LICENSE_EXPIRED:
246 return ERROR_DRM_LICENSE_EXPIRED;
247 break;
248 case Status::ERROR_DRM_SESSION_NOT_OPENED:
249 return ERROR_DRM_SESSION_NOT_OPENED;
250 break;
251 case Status::ERROR_DRM_CANNOT_HANDLE:
252 return ERROR_DRM_CANNOT_HANDLE;
253 break;
254 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800255 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800256 break;
257 case Status::BAD_VALUE:
258 return BAD_VALUE;
259 break;
260 case Status::ERROR_DRM_NOT_PROVISIONED:
261 return ERROR_DRM_NOT_PROVISIONED;
262 break;
263 case Status::ERROR_DRM_RESOURCE_BUSY:
264 return ERROR_DRM_RESOURCE_BUSY;
265 break;
266 case Status::ERROR_DRM_DEVICE_REVOKED:
267 return ERROR_DRM_DEVICE_REVOKED;
268 break;
269 case Status::ERROR_DRM_UNKNOWN:
270 default:
271 return ERROR_DRM_UNKNOWN;
272 break;
273 }
274}
275
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800276static status_t toStatusT_1_2(Status_V1_2 status) {
277 switch (status) {
278 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
279 return ERROR_DRM_RESOURCE_CONTENTION;
280 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
281 return ERROR_DRM_FRAME_TOO_LARGE;
282 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
283 return ERROR_DRM_INSUFFICIENT_SECURITY;
284 default:
285 return toStatusT(static_cast<Status>(status));
286 }
287}
288
Jeff Tinkera53d6552017-01-20 00:31:46 -0800289Mutex DrmHal::mLock;
290
Robert Shih0f3a8a02019-11-14 15:43:39 -0800291struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700292 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
293 : mSessionId(sessionId),
294 mDrm(drm) {}
295
Robert Shih0f3a8a02019-11-14 15:43:39 -0800296 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
297 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700298
299 const Vector<uint8_t> mSessionId;
300
Chong Zhang181e6952019-10-09 13:23:39 -0700301 virtual ~DrmSessionClient();
302
303private:
304 wp<DrmHal> mDrm;
305
306 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
307};
308
Robert Shih0f3a8a02019-11-14 15:43:39 -0800309::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
310 auto sessionId = mSessionId;
Robert Shihc3af31b2019-09-20 21:45:01 -0700311 sp<DrmHal> drm = mDrm.promote();
312 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700313 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800314 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800315 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800316 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700317 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700318 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800319 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700320 }
321 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800322 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700323 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800324 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700325}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800326
Robert Shih0f3a8a02019-11-14 15:43:39 -0800327::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700328 String8 name;
329 sp<DrmHal> drm = mDrm.promote();
330 if (drm == NULL) {
331 name.append("<deleted>");
332 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
333 || name.isEmpty()) {
334 name.append("<Get vendor failed or is empty>");
335 }
336 name.append("[");
337 for (size_t i = 0; i < mSessionId.size(); ++i) {
338 name.appendFormat("%02x", mSessionId[i]);
339 }
340 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700341 *_aidl_return = name;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800342 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700343}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800344
Robert Shihc3af31b2019-09-20 21:45:01 -0700345DrmHal::DrmSessionClient::~DrmSessionClient() {
346 DrmSessionManager::Instance()->removeSession(mSessionId);
347}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800348
349DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700350 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800351 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800352}
353
Jeff Tinker61332812017-05-15 16:53:10 -0700354void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800355 Mutex::Autolock autoLock(mLock);
356 auto openSessions = mOpenSessions;
357 for (size_t i = 0; i < openSessions.size(); i++) {
358 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700359 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800360 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700361 }
362 mOpenSessions.clear();
363}
364
Jeff Tinkera53d6552017-01-20 00:31:46 -0800365DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800366}
367
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800368void DrmHal::cleanup() {
369 closeOpenSessions();
370
371 Mutex::Autolock autoLock(mLock);
372 reportPluginMetrics();
373 reportFrameworkMetrics();
374
375 setListener(NULL);
376 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800377 if (mPluginV1_2 != NULL) {
378 if (!mPluginV1_2->setListener(NULL).isOk()) {
379 mInitCheck = DEAD_OBJECT;
380 }
381 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800382 if (!mPlugin->setListener(NULL).isOk()) {
383 mInitCheck = DEAD_OBJECT;
384 }
385 }
386 mPlugin.clear();
387 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700388 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800389}
390
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800391Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
392 Vector<sp<IDrmFactory>> factories;
393
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800394 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800395
396 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800397 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800398 [&factories](const hidl_vec<hidl_string> &registered) {
399 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000400 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800401 if (factory != NULL) {
402 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000403 }
404 }
405 }
406 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800407 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000408 [&factories](const hidl_vec<hidl_string> &registered) {
409 for (const auto &instance : registered) {
410 auto factory = drm::V1_1::IDrmFactory::getService(instance);
411 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000412 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800413 }
414 }
415 }
416 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700417 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700418 [&factories](const hidl_vec<hidl_string> &registered) {
419 for (const auto &instance : registered) {
420 auto factory = drm::V1_2::IDrmFactory::getService(instance);
421 if (factory != NULL) {
422 factories.push_back(factory);
423 }
424 }
425 }
426 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800427 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800428
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800429 if (factories.size() == 0) {
430 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700431 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800432 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000433 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800434 factories.push_back(passthrough);
435 } else {
436 ALOGE("Failed to find any drm factories");
437 }
438 }
439 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800440}
441
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800442sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
443 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800444 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800445 mMetrics.SetAppPackageName(appPackageName);
Robert Shih6152d7c2019-11-19 22:54:27 -0800446 mMetrics.SetAppUid(AIBinder_getCallingUid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800447
448 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800449 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800450 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800451 if (status != Status::OK) {
452 ALOGE("Failed to make drm plugin");
453 return;
454 }
455 plugin = hPlugin;
456 }
457 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700458
459 if (!hResult.isOk()) {
460 ALOGE("createPlugin remote call failed");
461 }
462
Jeff Tinkera53d6552017-01-20 00:31:46 -0800463 return plugin;
464}
465
466status_t DrmHal::initCheck() const {
467 return mInitCheck;
468}
469
470status_t DrmHal::setListener(const sp<IDrmClient>& listener)
471{
472 Mutex::Autolock lock(mEventLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800473 mListener = listener;
474 return NO_ERROR;
475}
476
477Return<void> DrmHal::sendEvent(EventType hEventType,
478 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800479 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800480
481 mEventLock.lock();
482 sp<IDrmClient> listener = mListener;
483 mEventLock.unlock();
484
485 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800486 Mutex::Autolock lock(mNotifyLock);
487 DrmPlugin::EventType eventType;
488 switch(hEventType) {
489 case EventType::PROVISION_REQUIRED:
490 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
491 break;
492 case EventType::KEY_NEEDED:
493 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
494 break;
495 case EventType::KEY_EXPIRED:
496 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
497 break;
498 case EventType::VENDOR_DEFINED:
499 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
500 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700501 case EventType::SESSION_RECLAIMED:
502 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
503 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800504 default:
505 return Void();
506 }
Robert Shih61e1c762019-10-31 21:26:58 -0700507 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800508 }
509 return Void();
510}
511
512Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
513 int64_t expiryTimeInMS) {
514
515 mEventLock.lock();
516 sp<IDrmClient> listener = mListener;
517 mEventLock.unlock();
518
519 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800520 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700521 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800522 }
523 return Void();
524}
525
526Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700527 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
528 std::vector<KeyStatus> keyStatusVec;
529 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
530 keyStatusVec.push_back({keyStatus_V1_0.keyId,
531 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
532 }
533 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
534 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
535}
536
537Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700538 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800539
540 mEventLock.lock();
541 sp<IDrmClient> listener = mListener;
542 mEventLock.unlock();
543
544 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700545 std::vector<DrmKeyStatus> keyStatusList;
546 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800547 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700548 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800549 uint32_t type;
550 switch(keyStatus.type) {
551 case KeyStatusType::USABLE:
552 type = DrmPlugin::kKeyStatusType_Usable;
553 break;
554 case KeyStatusType::EXPIRED:
555 type = DrmPlugin::kKeyStatusType_Expired;
556 break;
557 case KeyStatusType::OUTPUTNOTALLOWED:
558 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
559 break;
560 case KeyStatusType::STATUSPENDING:
561 type = DrmPlugin::kKeyStatusType_StatusPending;
562 break;
Robert Shiha5033262019-05-06 14:15:12 -0700563 case KeyStatusType::USABLEINFUTURE:
564 type = DrmPlugin::kKeyStatusType_UsableInFuture;
565 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800566 case KeyStatusType::INTERNALERROR:
567 default:
568 type = DrmPlugin::kKeyStatusType_InternalError;
569 break;
570 }
Robert Shih61e1c762019-10-31 21:26:58 -0700571 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800572 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800573 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800574
575 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700576 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800577 } else {
578 // There's no listener. But we still want to count the key change
579 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700580 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800581 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700582 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800583 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800584 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800585
Jeff Tinkera53d6552017-01-20 00:31:46 -0800586 return Void();
587}
588
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800589Return<void> DrmHal::sendSessionLostState(
590 const hidl_vec<uint8_t>& sessionId) {
591
592 mEventLock.lock();
593 sp<IDrmClient> listener = mListener;
594 mEventLock.unlock();
595
596 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800597 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700598 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800599 }
600 return Void();
601}
602
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800603status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
604 const uint8_t uuid[16],
605 const String8 &mimeType,
606 DrmPlugin::SecurityLevel level,
607 bool *isSupported) {
608 *isSupported = false;
609
610 // handle default value cases
611 if (level == DrmPlugin::kSecurityLevelUnknown) {
612 if (mimeType == "") {
613 // isCryptoSchemeSupported(uuid)
614 *isSupported = true;
615 } else {
616 // isCryptoSchemeSupported(uuid, mimeType)
617 *isSupported = factory->isContentTypeSupported(mimeType.string());
618 }
619 return OK;
620 } else if (mimeType == "") {
621 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800622 }
623
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800624 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
625 if (factoryV1_2 == NULL) {
626 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800627 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800628 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
629 mimeType.string(), toHidlSecurityLevel(level));
630 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800631 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800632}
633
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800634status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
635 const String8 &mimeType,
636 DrmPlugin::SecurityLevel level,
637 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800638 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800639 *isSupported = false;
640 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
641 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
642 return matchMimeTypeAndSecurityLevel(mFactories[i],
643 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800644 }
645 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800646 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800647}
648
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800649status_t DrmHal::createPlugin(const uint8_t uuid[16],
650 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800651 Mutex::Autolock autoLock(mLock);
652
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800653 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800654 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800655 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
656 if (plugin != NULL) {
657 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800658 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700659 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800660 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800661 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800662 }
663 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664
665 if (mPlugin == NULL) {
666 mInitCheck = ERROR_UNSUPPORTED;
667 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800668 mInitCheck = OK;
669 if (mPluginV1_2 != NULL) {
670 if (!mPluginV1_2->setListener(this).isOk()) {
671 mInitCheck = DEAD_OBJECT;
672 }
673 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700674 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800675 }
676 if (mInitCheck != OK) {
677 mPlugin.clear();
678 mPluginV1_1.clear();
679 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700680 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800681 }
682
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800683
Jeff Tinkera53d6552017-01-20 00:31:46 -0800684 return mInitCheck;
685}
686
687status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800688 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800689 return OK;
690}
691
Jeff Tinker41d279a2018-02-11 19:52:08 +0000692status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
693 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800694 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800695 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800696
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800697 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000698 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000699
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800700 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000701 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800702 } else {
703 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
704 return ERROR_DRM_CANNOT_HANDLE;
705 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000706 }
707
708 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800709 bool retry = true;
710 do {
711 hidl_vec<uint8_t> hSessionId;
712
Jeff Tinker41d279a2018-02-11 19:52:08 +0000713 Return<void> hResult;
714 if (mPluginV1_1 == NULL || !setSecurityLevel) {
715 hResult = mPlugin->openSession(
716 [&](Status status,const hidl_vec<uint8_t>& id) {
717 if (status == Status::OK) {
718 sessionId = toVector(id);
719 }
720 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800721 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000722 );
723 } else {
724 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
725 [&](Status status, const hidl_vec<uint8_t>& id) {
726 if (status == Status::OK) {
727 sessionId = toVector(id);
728 }
729 err = toStatusT(status);
730 }
731 );
732 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800733
734 if (!hResult.isOk()) {
735 err = DEAD_OBJECT;
736 }
737
738 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
739 mLock.unlock();
740 // reclaimSession may call back to closeSession, since mLock is
741 // shared between Drm instances, we should unlock here to avoid
742 // deadlock.
Robert Shih6152d7c2019-11-19 22:54:27 -0800743 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800744 mLock.lock();
745 } else {
746 retry = false;
747 }
748 } while (retry);
749
750 if (err == OK) {
Robert Shih0f3a8a02019-11-14 15:43:39 -0800751 std::shared_ptr<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
Robert Shih6152d7c2019-11-19 22:54:27 -0800752 DrmSessionManager::Instance()->addSession(AIBinder_getCallingPid(),
Robert Shih0f3a8a02019-11-14 15:43:39 -0800753 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
754 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800755 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800756 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800757
Adam Stonef0e618d2018-01-17 19:20:41 -0800758 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800759 return err;
760}
761
762status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
763 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800764 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800765
Jeff Tinker319d5f42017-07-26 15:44:33 -0700766 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
767 if (status.isOk()) {
768 if (status == Status::OK) {
769 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800770 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
771 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
772 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700773 break;
774 }
Jeff Tinker61332812017-05-15 16:53:10 -0700775 }
776 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800777 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800778 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800779 mMetrics.mCloseSessionCounter.Increment(response);
780 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800781 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800782 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700783 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800784}
785
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800786static DrmPlugin::KeyRequestType toKeyRequestType(
787 KeyRequestType keyRequestType) {
788 switch (keyRequestType) {
789 case KeyRequestType::INITIAL:
790 return DrmPlugin::kKeyRequestType_Initial;
791 break;
792 case KeyRequestType::RENEWAL:
793 return DrmPlugin::kKeyRequestType_Renewal;
794 break;
795 case KeyRequestType::RELEASE:
796 return DrmPlugin::kKeyRequestType_Release;
797 break;
798 default:
799 return DrmPlugin::kKeyRequestType_Unknown;
800 break;
801 }
802}
803
804static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
805 KeyRequestType_V1_1 keyRequestType) {
806 switch (keyRequestType) {
807 case KeyRequestType_V1_1::NONE:
808 return DrmPlugin::kKeyRequestType_None;
809 break;
810 case KeyRequestType_V1_1::UPDATE:
811 return DrmPlugin::kKeyRequestType_Update;
812 break;
813 default:
814 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
815 break;
816 }
817}
818
Jeff Tinkera53d6552017-01-20 00:31:46 -0800819status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
820 Vector<uint8_t> const &initData, String8 const &mimeType,
821 DrmPlugin::KeyType keyType, KeyedVector<String8,
822 String8> const &optionalParameters, Vector<uint8_t> &request,
823 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
824 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800825 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800826 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800827
828 DrmSessionManager::Instance()->useSession(sessionId);
829
830 KeyType hKeyType;
831 if (keyType == DrmPlugin::kKeyType_Streaming) {
832 hKeyType = KeyType::STREAMING;
833 } else if (keyType == DrmPlugin::kKeyType_Offline) {
834 hKeyType = KeyType::OFFLINE;
835 } else if (keyType == DrmPlugin::kKeyType_Release) {
836 hKeyType = KeyType::RELEASE;
837 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800838 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800839 return BAD_VALUE;
840 }
841
842 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
843
844 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800845 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800846
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800847 if (mPluginV1_2 != NULL) {
848 hResult = mPluginV1_2->getKeyRequest_1_2(
849 toHidlVec(sessionId), toHidlVec(initData),
850 toHidlString(mimeType), hKeyType, hOptionalParameters,
851 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
852 KeyRequestType_V1_1 hKeyRequestType,
853 const hidl_string& hDefaultUrl) {
854 if (status == Status_V1_2::OK) {
855 request = toVector(hRequest);
856 defaultUrl = toString8(hDefaultUrl);
857 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
858 }
859 err = toStatusT_1_2(status);
860 });
861 } else if (mPluginV1_1 != NULL) {
862 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800863 toHidlVec(sessionId), toHidlVec(initData),
864 toHidlString(mimeType), hKeyType, hOptionalParameters,
865 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800866 KeyRequestType_V1_1 hKeyRequestType,
867 const hidl_string& hDefaultUrl) {
868 if (status == Status::OK) {
869 request = toVector(hRequest);
870 defaultUrl = toString8(hDefaultUrl);
871 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800872 }
873 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800874 });
875 } else {
876 hResult = mPlugin->getKeyRequest(
877 toHidlVec(sessionId), toHidlVec(initData),
878 toHidlString(mimeType), hKeyType, hOptionalParameters,
879 [&](Status status, const hidl_vec<uint8_t>& hRequest,
880 KeyRequestType hKeyRequestType,
881 const hidl_string& hDefaultUrl) {
882 if (status == Status::OK) {
883 request = toVector(hRequest);
884 defaultUrl = toString8(hDefaultUrl);
885 *keyRequestType = toKeyRequestType(hKeyRequestType);
886 }
887 err = toStatusT(status);
888 });
889 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800890
Adam Stonef0e618d2018-01-17 19:20:41 -0800891 err = hResult.isOk() ? err : DEAD_OBJECT;
892 keyRequestTimer.SetAttribute(err);
893 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800894}
895
896status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
897 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
898 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800899 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700900 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800901
902 DrmSessionManager::Instance()->useSession(sessionId);
903
904 status_t err = UNKNOWN_ERROR;
905
906 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
907 toHidlVec(response),
908 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
909 if (status == Status::OK) {
910 keySetId = toVector(hKeySetId);
911 }
912 err = toStatusT(status);
913 }
914 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800915 err = hResult.isOk() ? err : DEAD_OBJECT;
916 keyResponseTimer.SetAttribute(err);
917 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800918}
919
920status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
921 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800922 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800923
Jeff Tinker58ad4752018-02-16 16:51:59 -0800924 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
925 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800926}
927
928status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
929 Vector<uint8_t> const &keySetId) {
930 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800931 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932
933 DrmSessionManager::Instance()->useSession(sessionId);
934
Jeff Tinker58ad4752018-02-16 16:51:59 -0800935 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
936 toHidlVec(keySetId));
937 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800938}
939
940status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
941 KeyedVector<String8, String8> &infoMap) const {
942 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800943 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800944
945 DrmSessionManager::Instance()->useSession(sessionId);
946
947 ::KeyedVector hInfoMap;
948
949 status_t err = UNKNOWN_ERROR;
950
951 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
952 [&](Status status, const hidl_vec<KeyValue>& map) {
953 if (status == Status::OK) {
954 infoMap = toKeyedVector(map);
955 }
956 err = toStatusT(status);
957 }
958 );
959
960 return hResult.isOk() ? err : DEAD_OBJECT;
961}
962
963status_t DrmHal::getProvisionRequest(String8 const &certType,
964 String8 const &certAuthority, Vector<uint8_t> &request,
965 String8 &defaultUrl) {
966 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800967 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800968
969 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800970 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800971
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800972 if (mPluginV1_2 != NULL) {
973 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
974 toHidlString(certType), toHidlString(certAuthority),
975 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
976 const hidl_string& hDefaultUrl) {
977 if (status == Status_V1_2::OK) {
978 request = toVector(hRequest);
979 defaultUrl = toString8(hDefaultUrl);
980 }
981 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800982 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800983 );
984 } else {
985 Return<void> hResult = mPlugin->getProvisionRequest(
986 toHidlString(certType), toHidlString(certAuthority),
987 [&](Status status, const hidl_vec<uint8_t>& hRequest,
988 const hidl_string& hDefaultUrl) {
989 if (status == Status::OK) {
990 request = toVector(hRequest);
991 defaultUrl = toString8(hDefaultUrl);
992 }
993 err = toStatusT(status);
994 }
995 );
996 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800997
Adam Stonecea91ce2018-01-22 19:23:28 -0800998 err = hResult.isOk() ? err : DEAD_OBJECT;
999 mMetrics.mGetProvisionRequestCounter.Increment(err);
1000 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001001}
1002
1003status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001004 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001005 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001006 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001007
1008 status_t err = UNKNOWN_ERROR;
1009
1010 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1011 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1012 const hidl_vec<uint8_t>& hWrappedKey) {
1013 if (status == Status::OK) {
1014 certificate = toVector(hCertificate);
1015 wrappedKey = toVector(hWrappedKey);
1016 }
1017 err = toStatusT(status);
1018 }
1019 );
1020
Adam Stonecea91ce2018-01-22 19:23:28 -08001021 err = hResult.isOk() ? err : DEAD_OBJECT;
1022 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1023 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001024}
1025
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001026status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001027 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001028 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001029
1030 status_t err = UNKNOWN_ERROR;
1031
1032 Return<void> hResult = mPlugin->getSecureStops(
1033 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1034 if (status == Status::OK) {
1035 secureStops = toSecureStops(hSecureStops);
1036 }
1037 err = toStatusT(status);
1038 }
1039 );
1040
1041 return hResult.isOk() ? err : DEAD_OBJECT;
1042}
1043
1044
Jeff Tinker15177d72018-01-25 12:57:55 -08001045status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1046 Mutex::Autolock autoLock(mLock);
1047
1048 if (mInitCheck != OK) {
1049 return mInitCheck;
1050 }
1051
1052 if (mPluginV1_1 == NULL) {
1053 return ERROR_DRM_CANNOT_HANDLE;
1054 }
1055
1056 status_t err = UNKNOWN_ERROR;
1057
1058 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1059 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1060 if (status == Status::OK) {
1061 secureStopIds = toSecureStopIds(hSecureStopIds);
1062 }
1063 err = toStatusT(status);
1064 }
1065 );
1066
1067 return hResult.isOk() ? err : DEAD_OBJECT;
1068}
1069
1070
Jeff Tinkera53d6552017-01-20 00:31:46 -08001071status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1072 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001073 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001074
1075 status_t err = UNKNOWN_ERROR;
1076
1077 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1078 [&](Status status, const SecureStop& hSecureStop) {
1079 if (status == Status::OK) {
1080 secureStop = toVector(hSecureStop.opaqueData);
1081 }
1082 err = toStatusT(status);
1083 }
1084 );
1085
1086 return hResult.isOk() ? err : DEAD_OBJECT;
1087}
1088
1089status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1090 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001091 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001092
Jeff Tinker58ad4752018-02-16 16:51:59 -08001093 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001094 if (mPluginV1_1 != NULL) {
1095 SecureStopRelease secureStopRelease;
1096 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001097 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1098 } else {
1099 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001100 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001101 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001102}
1103
Jeff Tinker15177d72018-01-25 12:57:55 -08001104status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1105 Mutex::Autolock autoLock(mLock);
1106
1107 if (mInitCheck != OK) {
1108 return mInitCheck;
1109 }
1110
1111 if (mPluginV1_1 == NULL) {
1112 return ERROR_DRM_CANNOT_HANDLE;
1113 }
1114
Jeff Tinker58ad4752018-02-16 16:51:59 -08001115 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1116 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001117}
1118
1119status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001120 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001121 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001122
Jeff Tinker58ad4752018-02-16 16:51:59 -08001123 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001124 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001125 status = mPluginV1_1->removeAllSecureStops();
1126 } else {
1127 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001128 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001129 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001130}
1131
Jeff Tinker6d998b62017-12-18 14:37:43 -08001132status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1133 DrmPlugin::HdcpLevel *max) const {
1134 Mutex::Autolock autoLock(mLock);
1135 INIT_CHECK();
1136
1137 if (connected == NULL || max == NULL) {
1138 return BAD_VALUE;
1139 }
1140 status_t err = UNKNOWN_ERROR;
1141
Jeff Tinker6d998b62017-12-18 14:37:43 -08001142 *connected = DrmPlugin::kHdcpLevelUnknown;
1143 *max = DrmPlugin::kHdcpLevelUnknown;
1144
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001145 Return<void> hResult;
1146 if (mPluginV1_2 != NULL) {
1147 hResult = mPluginV1_2->getHdcpLevels_1_2(
1148 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1149 if (status == Status_V1_2::OK) {
1150 *connected = toHdcpLevel(hConnected);
1151 *max = toHdcpLevel(hMax);
1152 }
1153 err = toStatusT_1_2(status);
1154 });
1155 } else if (mPluginV1_1 != NULL) {
1156 hResult = mPluginV1_1->getHdcpLevels(
1157 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1158 if (status == Status::OK) {
1159 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1160 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1161 }
1162 err = toStatusT(status);
1163 });
1164 } else {
1165 return ERROR_DRM_CANNOT_HANDLE;
1166 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001167
1168 return hResult.isOk() ? err : DEAD_OBJECT;
1169}
1170
1171status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1172 Mutex::Autolock autoLock(mLock);
1173 INIT_CHECK();
1174
1175 if (open == NULL || max == NULL) {
1176 return BAD_VALUE;
1177 }
1178 status_t err = UNKNOWN_ERROR;
1179
1180 *open = 0;
1181 *max = 0;
1182
1183 if (mPluginV1_1 == NULL) {
1184 return ERROR_DRM_CANNOT_HANDLE;
1185 }
1186
1187 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1188 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1189 if (status == Status::OK) {
1190 *open = hOpen;
1191 *max = hMax;
1192 }
1193 err = toStatusT(status);
1194 }
1195 );
1196
1197 return hResult.isOk() ? err : DEAD_OBJECT;
1198}
1199
1200status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1201 DrmPlugin::SecurityLevel *level) const {
1202 Mutex::Autolock autoLock(mLock);
1203 INIT_CHECK();
1204
1205 if (level == NULL) {
1206 return BAD_VALUE;
1207 }
1208 status_t err = UNKNOWN_ERROR;
1209
1210 if (mPluginV1_1 == NULL) {
1211 return ERROR_DRM_CANNOT_HANDLE;
1212 }
1213
1214 *level = DrmPlugin::kSecurityLevelUnknown;
1215
1216 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1217 [&](Status status, SecurityLevel hLevel) {
1218 if (status == Status::OK) {
1219 *level = toSecurityLevel(hLevel);
1220 }
1221 err = toStatusT(status);
1222 }
1223 );
1224
1225 return hResult.isOk() ? err : DEAD_OBJECT;
1226}
1227
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001228status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1229 Mutex::Autolock autoLock(mLock);
1230
1231 if (mInitCheck != OK) {
1232 return mInitCheck;
1233 }
1234
1235 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001236 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001237 }
1238
1239 status_t err = UNKNOWN_ERROR;
1240
1241 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1242 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1243 if (status == Status::OK) {
1244 keySetIds = toKeySetIds(hKeySetIds);
1245 }
1246 err = toStatusT(status);
1247 }
1248 );
1249
1250 return hResult.isOk() ? err : DEAD_OBJECT;
1251}
1252
1253status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1254 Mutex::Autolock autoLock(mLock);
1255
1256 if (mInitCheck != OK) {
1257 return mInitCheck;
1258 }
1259
1260 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001261 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001262 }
1263
1264 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1265 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1266}
1267
1268status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1269 DrmPlugin::OfflineLicenseState *licenseState) const {
1270 Mutex::Autolock autoLock(mLock);
1271
1272 if (mInitCheck != OK) {
1273 return mInitCheck;
1274 }
1275
1276 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001277 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001278 }
1279 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1280
1281 status_t err = UNKNOWN_ERROR;
1282
1283 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1284 [&](Status status, OfflineLicenseState hLicenseState) {
1285 if (status == Status::OK) {
1286 *licenseState = toOfflineLicenseState(hLicenseState);
1287 }
1288 err = toStatusT(status);
1289 }
1290 );
1291
1292 return hResult.isOk() ? err : DEAD_OBJECT;
1293}
1294
Jeff Tinkera53d6552017-01-20 00:31:46 -08001295status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1296 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001297 return getPropertyStringInternal(name, value);
1298}
1299
1300status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1301 // This function is internal to the class and should only be called while
1302 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001303 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001304
1305 status_t err = UNKNOWN_ERROR;
1306
1307 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1308 [&](Status status, const hidl_string& hValue) {
1309 if (status == Status::OK) {
1310 value = toString8(hValue);
1311 }
1312 err = toStatusT(status);
1313 }
1314 );
1315
1316 return hResult.isOk() ? err : DEAD_OBJECT;
1317}
1318
1319status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1320 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001321 return getPropertyByteArrayInternal(name, value);
1322}
1323
1324status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1325 // This function is internal to the class and should only be called while
1326 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001327 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001328
1329 status_t err = UNKNOWN_ERROR;
1330
1331 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1332 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1333 if (status == Status::OK) {
1334 value = toVector(hValue);
1335 }
1336 err = toStatusT(status);
1337 }
1338 );
1339
Adam Stonecea91ce2018-01-22 19:23:28 -08001340 err = hResult.isOk() ? err : DEAD_OBJECT;
1341 if (name == kPropertyDeviceUniqueId) {
1342 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1343 }
1344 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001345}
1346
1347status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1348 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001349 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001350
Jeff Tinker58ad4752018-02-16 16:51:59 -08001351 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001352 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001353 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001354}
1355
1356status_t DrmHal::setPropertyByteArray(String8 const &name,
1357 Vector<uint8_t> const &value ) const {
1358 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001359 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001360
Jeff Tinker58ad4752018-02-16 16:51:59 -08001361 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001362 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001363 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001364}
1365
Robert Shih93538812019-11-12 12:21:35 -08001366status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
1367 if (consumer == nullptr) {
Adam Stone28f27c32018-02-05 15:07:48 -08001368 return UNEXPECTED_NULL;
1369 }
Robert Shih93538812019-11-12 12:21:35 -08001370 consumer->consumeFrameworkMetrics(mMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001371
1372 // Append vendor metrics if they are supported.
1373 if (mPluginV1_1 != NULL) {
1374 String8 vendor;
1375 String8 description;
1376 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1377 || vendor.isEmpty()) {
1378 ALOGE("Get vendor failed or is empty");
1379 vendor = "NONE";
1380 }
1381 if (getPropertyStringInternal(String8("description"), description) != OK
1382 || description.isEmpty()) {
1383 ALOGE("Get description failed or is empty.");
1384 description = "NONE";
1385 }
1386 vendor += ".";
1387 vendor += description;
1388
1389 hidl_vec<DrmMetricGroup> pluginMetrics;
1390 status_t err = UNKNOWN_ERROR;
1391
1392 Return<void> status = mPluginV1_1->getMetrics(
1393 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1394 if (status != Status::OK) {
1395 ALOGV("Error getting plugin metrics: %d", status);
1396 } else {
Robert Shih93538812019-11-12 12:21:35 -08001397 consumer->consumeHidlMetrics(vendor, pluginMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001398 }
1399 err = toStatusT(status);
1400 });
1401 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001402 }
1403
Adam Stoneab394d12017-12-22 12:34:20 -08001404 return OK;
1405}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001406
1407status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1408 String8 const &algorithm) {
1409 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001410 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001411
1412 DrmSessionManager::Instance()->useSession(sessionId);
1413
Jeff Tinkere6412942018-04-30 17:35:16 -07001414 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001415 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001416 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001417}
1418
1419status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1420 String8 const &algorithm) {
1421 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001422 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001423
1424 DrmSessionManager::Instance()->useSession(sessionId);
1425
Jeff Tinkere6412942018-04-30 17:35:16 -07001426 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001427 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001428 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001429}
1430
1431status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001432 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1433 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001434 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001435 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001436
1437 DrmSessionManager::Instance()->useSession(sessionId);
1438
1439 status_t err = UNKNOWN_ERROR;
1440
1441 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1442 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1443 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1444 if (status == Status::OK) {
1445 output = toVector(hOutput);
1446 }
1447 err = toStatusT(status);
1448 }
1449 );
1450
1451 return hResult.isOk() ? err : DEAD_OBJECT;
1452}
1453
1454status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001455 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1456 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001457 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001458 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001459
1460 DrmSessionManager::Instance()->useSession(sessionId);
1461
1462 status_t err = UNKNOWN_ERROR;
1463
1464 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1465 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1466 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1467 if (status == Status::OK) {
1468 output = toVector(hOutput);
1469 }
1470 err = toStatusT(status);
1471 }
1472 );
1473
1474 return hResult.isOk() ? err : DEAD_OBJECT;
1475}
1476
1477status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001478 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1479 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001480 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001481 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001482
1483 DrmSessionManager::Instance()->useSession(sessionId);
1484
1485 status_t err = UNKNOWN_ERROR;
1486
1487 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1488 toHidlVec(keyId), toHidlVec(message),
1489 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1490 if (status == Status::OK) {
1491 signature = toVector(hSignature);
1492 }
1493 err = toStatusT(status);
1494 }
1495 );
1496
1497 return hResult.isOk() ? err : DEAD_OBJECT;
1498}
1499
1500status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001501 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1502 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001503 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001504 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001505
1506 DrmSessionManager::Instance()->useSession(sessionId);
1507
1508 status_t err = UNKNOWN_ERROR;
1509
1510 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1511 toHidlVec(message), toHidlVec(signature),
1512 [&](Status status, bool hMatch) {
1513 if (status == Status::OK) {
1514 match = hMatch;
1515 } else {
1516 match = false;
1517 }
1518 err = toStatusT(status);
1519 }
1520 );
1521
1522 return hResult.isOk() ? err : DEAD_OBJECT;
1523}
1524
1525status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001526 String8 const &algorithm, Vector<uint8_t> const &message,
1527 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001528 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001529 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001530
Jeff Tinkera53d6552017-01-20 00:31:46 -08001531 DrmSessionManager::Instance()->useSession(sessionId);
1532
1533 status_t err = UNKNOWN_ERROR;
1534
1535 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1536 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1537 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1538 if (status == Status::OK) {
1539 signature = toVector(hSignature);
1540 }
1541 err = toStatusT(status);
1542 }
1543 );
1544
1545 return hResult.isOk() ? err : DEAD_OBJECT;
1546}
1547
Adam Stonefb679e32018-02-07 10:25:48 -08001548void DrmHal::reportFrameworkMetrics() const
1549{
Robert Shih82ea6be2019-11-07 17:47:23 -08001550 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1551 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001552 String8 vendor;
1553 String8 description;
1554 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1555 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001556 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001557 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001558 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001559 }
1560 result = getPropertyStringInternal(String8("description"), description);
1561 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001562 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001563 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001564 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001565 }
Adam Stoneab394d12017-12-22 12:34:20 -08001566
Adam Stonefb679e32018-02-07 10:25:48 -08001567 std::string serializedMetrics;
1568 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1569 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001570 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001571 }
Adam Stone32494f52018-02-26 22:53:27 -08001572 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1573 serializedMetrics.size());
1574 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001575 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001576 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001577 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001578 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001579 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001580 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001581}
1582
1583void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001584{
Adam Stone32494f52018-02-26 22:53:27 -08001585 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001586 String8 vendor;
1587 String8 description;
1588 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1589 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001590 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1591 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1592 metricsVector.size());
1593 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001594 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001595 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001596 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001597 }
1598 }
1599}
1600
Jeff Tinkera53d6552017-01-20 00:31:46 -08001601} // namespace android