blob: bd4b521f222695ccf053a421c59886dd9539ab7c [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
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080025
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>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070030#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080031#include <media/drm/DrmAPI.h>
32#include <media/stagefright/foundation/ADebug.h>
33#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080034#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080035#include <media/stagefright/foundation/hexdump.h>
36#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080037#include <mediadrm/DrmHal.h>
38#include <mediadrm/DrmSessionClientInterface.h>
39#include <mediadrm/DrmSessionManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080040
Jeff Tinker6d998b62017-12-18 14:37:43 -080041using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080042using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080043using drm::V1_0::KeyType;
44using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080045using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080046using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070048using drm::V1_1::HdcpLevel;
49using drm::V1_1::SecureStopRelease;
50using drm::V1_1::SecurityLevel;
51using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070052using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080053using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080054using ::android::hardware::hidl_array;
55using ::android::hardware::hidl_string;
56using ::android::hardware::hidl_vec;
57using ::android::hardware::Return;
58using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080059using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080060using ::android::sp;
61
Jeff Tinkerb8684f32018-12-12 08:41:31 -080062typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
63typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080064typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080065
Adam Stonecea91ce2018-01-22 19:23:28 -080066namespace {
67
68// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
69// in the MediaDrm API.
70constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080071constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080072
Adam Stone32494f52018-02-26 22:53:27 -080073template<typename T>
74std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070075 // Note that the base 64 conversion only works with arrays of single-byte
76 // values. If the source is empty or is not an array of single-byte values,
77 // return empty string.
78 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080079 return "";
80 }
Adam Stone32494f52018-02-26 22:53:27 -080081
82 android::AString outputString;
83 encodeBase64(data, size, &outputString);
84 // Remove trailing equals padding if it exists.
85 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
86 outputString.erase(outputString.size() - 1, 1);
87 }
88
89 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080090}
91
Adam Stone32494f52018-02-26 22:53:27 -080092} // anonymous namespace
93
Jeff Tinkera53d6552017-01-20 00:31:46 -080094namespace android {
95
Jeff Tinker6d998b62017-12-18 14:37:43 -080096#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
97
Jeff Tinkera53d6552017-01-20 00:31:46 -080098static inline int getCallingPid() {
99 return IPCThreadState::self()->getCallingPid();
100}
101
102static bool checkPermission(const char* permissionString) {
103 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
104 bool ok = checkCallingPermission(String16(permissionString));
105 if (!ok) ALOGE("Request requires %s", permissionString);
106 return ok;
107}
108
109static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
110 Vector<uint8_t> vector;
111 vector.appendArray(vec.data(), vec.size());
112 return *const_cast<const Vector<uint8_t> *>(&vector);
113}
114
115static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
116 hidl_vec<uint8_t> vec;
117 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
118 return vec;
119}
120
121static String8 toString8(const hidl_string &string) {
122 return String8(string.c_str());
123}
124
125static hidl_string toHidlString(const String8& string) {
126 return hidl_string(string.string());
127}
128
Jeff Tinker6d998b62017-12-18 14:37:43 -0800129static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
130 switch(level) {
131 case SecurityLevel::SW_SECURE_CRYPTO:
132 return DrmPlugin::kSecurityLevelSwSecureCrypto;
133 case SecurityLevel::SW_SECURE_DECODE:
134 return DrmPlugin::kSecurityLevelSwSecureDecode;
135 case SecurityLevel::HW_SECURE_CRYPTO:
136 return DrmPlugin::kSecurityLevelHwSecureCrypto;
137 case SecurityLevel::HW_SECURE_DECODE:
138 return DrmPlugin::kSecurityLevelHwSecureDecode;
139 case SecurityLevel::HW_SECURE_ALL:
140 return DrmPlugin::kSecurityLevelHwSecureAll;
141 default:
142 return DrmPlugin::kSecurityLevelUnknown;
143 }
144}
145
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800146static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
147 switch(level) {
148 case DrmPlugin::kSecurityLevelSwSecureCrypto:
149 return SecurityLevel::SW_SECURE_CRYPTO;
150 case DrmPlugin::kSecurityLevelSwSecureDecode:
151 return SecurityLevel::SW_SECURE_DECODE;
152 case DrmPlugin::kSecurityLevelHwSecureCrypto:
153 return SecurityLevel::HW_SECURE_CRYPTO;
154 case DrmPlugin::kSecurityLevelHwSecureDecode:
155 return SecurityLevel::HW_SECURE_DECODE;
156 case DrmPlugin::kSecurityLevelHwSecureAll:
157 return SecurityLevel::HW_SECURE_ALL;
158 default:
159 return SecurityLevel::UNKNOWN;
160 }
161}
162
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700163static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
164 OfflineLicenseState licenseState) {
165 switch(licenseState) {
166 case OfflineLicenseState::USABLE:
167 return DrmPlugin::kOfflineLicenseStateUsable;
168 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800169 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700170 default:
171 return DrmPlugin::kOfflineLicenseStateUnknown;
172 }
173}
174
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800175static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800176 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800177 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800178 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800179 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800180 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800181 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800182 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800183 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800184 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800185 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800186 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800187 case HdcpLevel_V1_2::HDCP_V2_3:
188 return DrmPlugin::kHdcpV2_3;
189 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800190 return DrmPlugin::kHdcpNoOutput;
191 default:
192 return DrmPlugin::kHdcpLevelUnknown;
193 }
194}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800195static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
196 keyedVector) {
197 std::vector<KeyValue> stdKeyedVector;
198 for (size_t i = 0; i < keyedVector.size(); i++) {
199 KeyValue keyValue;
200 keyValue.key = toHidlString(keyedVector.keyAt(i));
201 keyValue.value = toHidlString(keyedVector.valueAt(i));
202 stdKeyedVector.push_back(keyValue);
203 }
204 return ::KeyedVector(stdKeyedVector);
205}
206
207static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
208 hKeyedVector) {
209 KeyedVector<String8, String8> keyedVector;
210 for (size_t i = 0; i < hKeyedVector.size(); i++) {
211 keyedVector.add(toString8(hKeyedVector[i].key),
212 toString8(hKeyedVector[i].value));
213 }
214 return keyedVector;
215}
216
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800217static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800218 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800219 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800220 for (size_t i = 0; i < hSecureStops.size(); i++) {
221 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
222 }
223 return secureStops;
224}
225
Jeff Tinker15177d72018-01-25 12:57:55 -0800226static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
227 hSecureStopIds) {
228 List<Vector<uint8_t>> secureStopIds;
229 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
230 secureStopIds.push_back(toVector(hSecureStopIds[i]));
231 }
232 return secureStopIds;
233}
234
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700235static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
236 hKeySetIds) {
237 List<Vector<uint8_t>> keySetIds;
238 for (size_t i = 0; i < hKeySetIds.size(); i++) {
239 keySetIds.push_back(toVector(hKeySetIds[i]));
240 }
241 return keySetIds;
242}
243
Jeff Tinkera53d6552017-01-20 00:31:46 -0800244static status_t toStatusT(Status status) {
245 switch (status) {
246 case Status::OK:
247 return OK;
248 break;
249 case Status::ERROR_DRM_NO_LICENSE:
250 return ERROR_DRM_NO_LICENSE;
251 break;
252 case Status::ERROR_DRM_LICENSE_EXPIRED:
253 return ERROR_DRM_LICENSE_EXPIRED;
254 break;
255 case Status::ERROR_DRM_SESSION_NOT_OPENED:
256 return ERROR_DRM_SESSION_NOT_OPENED;
257 break;
258 case Status::ERROR_DRM_CANNOT_HANDLE:
259 return ERROR_DRM_CANNOT_HANDLE;
260 break;
261 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800262 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800263 break;
264 case Status::BAD_VALUE:
265 return BAD_VALUE;
266 break;
267 case Status::ERROR_DRM_NOT_PROVISIONED:
268 return ERROR_DRM_NOT_PROVISIONED;
269 break;
270 case Status::ERROR_DRM_RESOURCE_BUSY:
271 return ERROR_DRM_RESOURCE_BUSY;
272 break;
273 case Status::ERROR_DRM_DEVICE_REVOKED:
274 return ERROR_DRM_DEVICE_REVOKED;
275 break;
276 case Status::ERROR_DRM_UNKNOWN:
277 default:
278 return ERROR_DRM_UNKNOWN;
279 break;
280 }
281}
282
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800283static status_t toStatusT_1_2(Status_V1_2 status) {
284 switch (status) {
285 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
286 return ERROR_DRM_RESOURCE_CONTENTION;
287 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
288 return ERROR_DRM_FRAME_TOO_LARGE;
289 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
290 return ERROR_DRM_INSUFFICIENT_SECURITY;
291 default:
292 return toStatusT(static_cast<Status>(status));
293 }
294}
295
Jeff Tinkera53d6552017-01-20 00:31:46 -0800296Mutex DrmHal::mLock;
297
Robert Shihc3af31b2019-09-20 21:45:01 -0700298bool DrmHal::DrmSessionClient::reclaimResource() {
299 sp<DrmHal> drm = mDrm.promote();
300 if (drm == NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800301 return true;
302 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700303 status_t err = drm->closeSession(mSessionId);
304 if (err != OK) {
305 return false;
306 }
307 drm->sendEvent(EventType::SESSION_RECLAIMED,
308 toHidlVec(mSessionId), hidl_vec<uint8_t>());
309 return true;
310}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800311
Robert Shihc3af31b2019-09-20 21:45:01 -0700312String8 DrmHal::DrmSessionClient::getName() {
313 String8 name;
314 sp<DrmHal> drm = mDrm.promote();
315 if (drm == NULL) {
316 name.append("<deleted>");
317 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
318 || name.isEmpty()) {
319 name.append("<Get vendor failed or is empty>");
320 }
321 name.append("[");
322 for (size_t i = 0; i < mSessionId.size(); ++i) {
323 name.appendFormat("%02x", mSessionId[i]);
324 }
325 name.append("]");
326 return name;
327}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800328
Robert Shihc3af31b2019-09-20 21:45:01 -0700329DrmHal::DrmSessionClient::~DrmSessionClient() {
330 DrmSessionManager::Instance()->removeSession(mSessionId);
331}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800332
333DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700334 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800335 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800336}
337
Jeff Tinker61332812017-05-15 16:53:10 -0700338void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800339 Mutex::Autolock autoLock(mLock);
340 auto openSessions = mOpenSessions;
341 for (size_t i = 0; i < openSessions.size(); i++) {
342 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700343 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800344 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700345 }
346 mOpenSessions.clear();
347}
348
Jeff Tinkera53d6552017-01-20 00:31:46 -0800349DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800350}
351
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800352void DrmHal::cleanup() {
353 closeOpenSessions();
354
355 Mutex::Autolock autoLock(mLock);
356 reportPluginMetrics();
357 reportFrameworkMetrics();
358
359 setListener(NULL);
360 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800361 if (mPluginV1_2 != NULL) {
362 if (!mPluginV1_2->setListener(NULL).isOk()) {
363 mInitCheck = DEAD_OBJECT;
364 }
365 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800366 if (!mPlugin->setListener(NULL).isOk()) {
367 mInitCheck = DEAD_OBJECT;
368 }
369 }
370 mPlugin.clear();
371 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700372 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800373}
374
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800375Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
376 Vector<sp<IDrmFactory>> factories;
377
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800378 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800379
380 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800381 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800382 [&factories](const hidl_vec<hidl_string> &registered) {
383 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000384 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800385 if (factory != NULL) {
386 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000387 }
388 }
389 }
390 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800391 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000392 [&factories](const hidl_vec<hidl_string> &registered) {
393 for (const auto &instance : registered) {
394 auto factory = drm::V1_1::IDrmFactory::getService(instance);
395 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000396 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800397 }
398 }
399 }
400 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700401 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700402 [&factories](const hidl_vec<hidl_string> &registered) {
403 for (const auto &instance : registered) {
404 auto factory = drm::V1_2::IDrmFactory::getService(instance);
405 if (factory != NULL) {
406 factories.push_back(factory);
407 }
408 }
409 }
410 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800411 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800412
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800413 if (factories.size() == 0) {
414 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700415 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800416 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000417 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800418 factories.push_back(passthrough);
419 } else {
420 ALOGE("Failed to find any drm factories");
421 }
422 }
423 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424}
425
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800426sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
427 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800428 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800429 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800430
431 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800432 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800433 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800434 if (status != Status::OK) {
435 ALOGE("Failed to make drm plugin");
436 return;
437 }
438 plugin = hPlugin;
439 }
440 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700441
442 if (!hResult.isOk()) {
443 ALOGE("createPlugin remote call failed");
444 }
445
Jeff Tinkera53d6552017-01-20 00:31:46 -0800446 return plugin;
447}
448
449status_t DrmHal::initCheck() const {
450 return mInitCheck;
451}
452
453status_t DrmHal::setListener(const sp<IDrmClient>& listener)
454{
455 Mutex::Autolock lock(mEventLock);
456 if (mListener != NULL){
457 IInterface::asBinder(mListener)->unlinkToDeath(this);
458 }
459 if (listener != NULL) {
460 IInterface::asBinder(listener)->linkToDeath(this);
461 }
462 mListener = listener;
463 return NO_ERROR;
464}
465
466Return<void> DrmHal::sendEvent(EventType hEventType,
467 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800468 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800469
470 mEventLock.lock();
471 sp<IDrmClient> listener = mListener;
472 mEventLock.unlock();
473
474 if (listener != NULL) {
475 Parcel obj;
476 writeByteArray(obj, sessionId);
477 writeByteArray(obj, data);
478
479 Mutex::Autolock lock(mNotifyLock);
480 DrmPlugin::EventType eventType;
481 switch(hEventType) {
482 case EventType::PROVISION_REQUIRED:
483 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
484 break;
485 case EventType::KEY_NEEDED:
486 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
487 break;
488 case EventType::KEY_EXPIRED:
489 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
490 break;
491 case EventType::VENDOR_DEFINED:
492 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
493 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700494 case EventType::SESSION_RECLAIMED:
495 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
496 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800497 default:
498 return Void();
499 }
500 listener->notify(eventType, 0, &obj);
501 }
502 return Void();
503}
504
505Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
506 int64_t expiryTimeInMS) {
507
508 mEventLock.lock();
509 sp<IDrmClient> listener = mListener;
510 mEventLock.unlock();
511
512 if (listener != NULL) {
513 Parcel obj;
514 writeByteArray(obj, sessionId);
515 obj.writeInt64(expiryTimeInMS);
516
517 Mutex::Autolock lock(mNotifyLock);
518 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
519 }
520 return Void();
521}
522
523Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700524 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
525 std::vector<KeyStatus> keyStatusVec;
526 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
527 keyStatusVec.push_back({keyStatus_V1_0.keyId,
528 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
529 }
530 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
531 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
532}
533
534Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Jeff Tinkera53d6552017-01-20 00:31:46 -0800535 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
536
537 mEventLock.lock();
538 sp<IDrmClient> listener = mListener;
539 mEventLock.unlock();
540
541 if (listener != NULL) {
542 Parcel obj;
543 writeByteArray(obj, sessionId);
544
545 size_t nKeys = keyStatusList.size();
546 obj.writeInt32(nKeys);
547 for (size_t i = 0; i < nKeys; ++i) {
548 const KeyStatus &keyStatus = keyStatusList[i];
549 writeByteArray(obj, keyStatus.keyId);
550 uint32_t type;
551 switch(keyStatus.type) {
552 case KeyStatusType::USABLE:
553 type = DrmPlugin::kKeyStatusType_Usable;
554 break;
555 case KeyStatusType::EXPIRED:
556 type = DrmPlugin::kKeyStatusType_Expired;
557 break;
558 case KeyStatusType::OUTPUTNOTALLOWED:
559 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
560 break;
561 case KeyStatusType::STATUSPENDING:
562 type = DrmPlugin::kKeyStatusType_StatusPending;
563 break;
Robert Shiha5033262019-05-06 14:15:12 -0700564 case KeyStatusType::USABLEINFUTURE:
565 type = DrmPlugin::kKeyStatusType_UsableInFuture;
566 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800567 case KeyStatusType::INTERNALERROR:
568 default:
569 type = DrmPlugin::kKeyStatusType_InternalError;
570 break;
571 }
572 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800573 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800574 }
575 obj.writeInt32(hasNewUsableKey);
576
577 Mutex::Autolock lock(mNotifyLock);
578 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800579 } else {
580 // There's no listener. But we still want to count the key change
581 // events.
582 size_t nKeys = keyStatusList.size();
583 for (size_t i = 0; i < nKeys; i++) {
584 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
585 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800586 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800587
Jeff Tinkera53d6552017-01-20 00:31:46 -0800588 return Void();
589}
590
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800591Return<void> DrmHal::sendSessionLostState(
592 const hidl_vec<uint8_t>& sessionId) {
593
594 mEventLock.lock();
595 sp<IDrmClient> listener = mListener;
596 mEventLock.unlock();
597
598 if (listener != NULL) {
599 Parcel obj;
600 writeByteArray(obj, sessionId);
601 Mutex::Autolock lock(mNotifyLock);
602 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
603 }
604 return Void();
605}
606
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800607status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
608 const uint8_t uuid[16],
609 const String8 &mimeType,
610 DrmPlugin::SecurityLevel level,
611 bool *isSupported) {
612 *isSupported = false;
613
614 // handle default value cases
615 if (level == DrmPlugin::kSecurityLevelUnknown) {
616 if (mimeType == "") {
617 // isCryptoSchemeSupported(uuid)
618 *isSupported = true;
619 } else {
620 // isCryptoSchemeSupported(uuid, mimeType)
621 *isSupported = factory->isContentTypeSupported(mimeType.string());
622 }
623 return OK;
624 } else if (mimeType == "") {
625 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800626 }
627
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800628 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
629 if (factoryV1_2 == NULL) {
630 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800631 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800632 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
633 mimeType.string(), toHidlSecurityLevel(level));
634 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800635 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800636}
637
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800638status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
639 const String8 &mimeType,
640 DrmPlugin::SecurityLevel level,
641 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800642 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800643 *isSupported = false;
644 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
645 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
646 return matchMimeTypeAndSecurityLevel(mFactories[i],
647 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800648 }
649 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800650 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800651}
652
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800653status_t DrmHal::createPlugin(const uint8_t uuid[16],
654 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800655 Mutex::Autolock autoLock(mLock);
656
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800657 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800658 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800659 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
660 if (plugin != NULL) {
661 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800662 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700663 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800664 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800665 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800666 }
667 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800668
669 if (mPlugin == NULL) {
670 mInitCheck = ERROR_UNSUPPORTED;
671 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800672 mInitCheck = OK;
673 if (mPluginV1_2 != NULL) {
674 if (!mPluginV1_2->setListener(this).isOk()) {
675 mInitCheck = DEAD_OBJECT;
676 }
677 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700678 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800679 }
680 if (mInitCheck != OK) {
681 mPlugin.clear();
682 mPluginV1_1.clear();
683 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700684 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800685 }
686
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800687
Jeff Tinkera53d6552017-01-20 00:31:46 -0800688 return mInitCheck;
689}
690
691status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800692 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800693 return OK;
694}
695
Jeff Tinker41d279a2018-02-11 19:52:08 +0000696status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
697 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800698 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800699 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800700
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800701 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000702 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000703
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800704 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000705 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800706 } else {
707 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
708 return ERROR_DRM_CANNOT_HANDLE;
709 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000710 }
711
712 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800713 bool retry = true;
714 do {
715 hidl_vec<uint8_t> hSessionId;
716
Jeff Tinker41d279a2018-02-11 19:52:08 +0000717 Return<void> hResult;
718 if (mPluginV1_1 == NULL || !setSecurityLevel) {
719 hResult = mPlugin->openSession(
720 [&](Status status,const hidl_vec<uint8_t>& id) {
721 if (status == Status::OK) {
722 sessionId = toVector(id);
723 }
724 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800725 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000726 );
727 } else {
728 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
729 [&](Status status, const hidl_vec<uint8_t>& id) {
730 if (status == Status::OK) {
731 sessionId = toVector(id);
732 }
733 err = toStatusT(status);
734 }
735 );
736 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800737
738 if (!hResult.isOk()) {
739 err = DEAD_OBJECT;
740 }
741
742 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
743 mLock.unlock();
744 // reclaimSession may call back to closeSession, since mLock is
745 // shared between Drm instances, we should unlock here to avoid
746 // deadlock.
747 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
748 mLock.lock();
749 } else {
750 retry = false;
751 }
752 } while (retry);
753
754 if (err == OK) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700755 sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
756 DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
757 mOpenSessions.push(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800758 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800759 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800760
Adam Stonef0e618d2018-01-17 19:20:41 -0800761 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800762 return err;
763}
764
765status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
766 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800767 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800768
Jeff Tinker319d5f42017-07-26 15:44:33 -0700769 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
770 if (status.isOk()) {
771 if (status == Status::OK) {
772 DrmSessionManager::Instance()->removeSession(sessionId);
773 for (size_t i = 0; i < mOpenSessions.size(); i++) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700774 if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700775 mOpenSessions.removeAt(i);
776 break;
777 }
Jeff Tinker61332812017-05-15 16:53:10 -0700778 }
779 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800780 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800781 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800782 mMetrics.mCloseSessionCounter.Increment(response);
783 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800784 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800785 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700786 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800787}
788
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800789static DrmPlugin::KeyRequestType toKeyRequestType(
790 KeyRequestType keyRequestType) {
791 switch (keyRequestType) {
792 case KeyRequestType::INITIAL:
793 return DrmPlugin::kKeyRequestType_Initial;
794 break;
795 case KeyRequestType::RENEWAL:
796 return DrmPlugin::kKeyRequestType_Renewal;
797 break;
798 case KeyRequestType::RELEASE:
799 return DrmPlugin::kKeyRequestType_Release;
800 break;
801 default:
802 return DrmPlugin::kKeyRequestType_Unknown;
803 break;
804 }
805}
806
807static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
808 KeyRequestType_V1_1 keyRequestType) {
809 switch (keyRequestType) {
810 case KeyRequestType_V1_1::NONE:
811 return DrmPlugin::kKeyRequestType_None;
812 break;
813 case KeyRequestType_V1_1::UPDATE:
814 return DrmPlugin::kKeyRequestType_Update;
815 break;
816 default:
817 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
818 break;
819 }
820}
821
Jeff Tinkera53d6552017-01-20 00:31:46 -0800822status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
823 Vector<uint8_t> const &initData, String8 const &mimeType,
824 DrmPlugin::KeyType keyType, KeyedVector<String8,
825 String8> const &optionalParameters, Vector<uint8_t> &request,
826 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
827 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800828 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800829 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800830
831 DrmSessionManager::Instance()->useSession(sessionId);
832
833 KeyType hKeyType;
834 if (keyType == DrmPlugin::kKeyType_Streaming) {
835 hKeyType = KeyType::STREAMING;
836 } else if (keyType == DrmPlugin::kKeyType_Offline) {
837 hKeyType = KeyType::OFFLINE;
838 } else if (keyType == DrmPlugin::kKeyType_Release) {
839 hKeyType = KeyType::RELEASE;
840 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800841 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800842 return BAD_VALUE;
843 }
844
845 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
846
847 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800848 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800849
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800850 if (mPluginV1_2 != NULL) {
851 hResult = mPluginV1_2->getKeyRequest_1_2(
852 toHidlVec(sessionId), toHidlVec(initData),
853 toHidlString(mimeType), hKeyType, hOptionalParameters,
854 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
855 KeyRequestType_V1_1 hKeyRequestType,
856 const hidl_string& hDefaultUrl) {
857 if (status == Status_V1_2::OK) {
858 request = toVector(hRequest);
859 defaultUrl = toString8(hDefaultUrl);
860 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
861 }
862 err = toStatusT_1_2(status);
863 });
864 } else if (mPluginV1_1 != NULL) {
865 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800866 toHidlVec(sessionId), toHidlVec(initData),
867 toHidlString(mimeType), hKeyType, hOptionalParameters,
868 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800869 KeyRequestType_V1_1 hKeyRequestType,
870 const hidl_string& hDefaultUrl) {
871 if (status == Status::OK) {
872 request = toVector(hRequest);
873 defaultUrl = toString8(hDefaultUrl);
874 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800875 }
876 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800877 });
878 } else {
879 hResult = mPlugin->getKeyRequest(
880 toHidlVec(sessionId), toHidlVec(initData),
881 toHidlString(mimeType), hKeyType, hOptionalParameters,
882 [&](Status status, const hidl_vec<uint8_t>& hRequest,
883 KeyRequestType hKeyRequestType,
884 const hidl_string& hDefaultUrl) {
885 if (status == Status::OK) {
886 request = toVector(hRequest);
887 defaultUrl = toString8(hDefaultUrl);
888 *keyRequestType = toKeyRequestType(hKeyRequestType);
889 }
890 err = toStatusT(status);
891 });
892 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800893
Adam Stonef0e618d2018-01-17 19:20:41 -0800894 err = hResult.isOk() ? err : DEAD_OBJECT;
895 keyRequestTimer.SetAttribute(err);
896 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800897}
898
899status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
900 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
901 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800902 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800903
Jeff Tinker6d998b62017-12-18 14:37:43 -0800904 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800905
906 DrmSessionManager::Instance()->useSession(sessionId);
907
908 status_t err = UNKNOWN_ERROR;
909
910 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
911 toHidlVec(response),
912 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
913 if (status == Status::OK) {
914 keySetId = toVector(hKeySetId);
915 }
916 err = toStatusT(status);
917 }
918 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800919 err = hResult.isOk() ? err : DEAD_OBJECT;
920 keyResponseTimer.SetAttribute(err);
921 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800922}
923
924status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
925 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800926 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800927
Jeff Tinker58ad4752018-02-16 16:51:59 -0800928 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
929 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800930}
931
932status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
933 Vector<uint8_t> const &keySetId) {
934 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800935 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800936
937 DrmSessionManager::Instance()->useSession(sessionId);
938
Jeff Tinker58ad4752018-02-16 16:51:59 -0800939 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
940 toHidlVec(keySetId));
941 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800942}
943
944status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
945 KeyedVector<String8, String8> &infoMap) const {
946 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800947 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800948
949 DrmSessionManager::Instance()->useSession(sessionId);
950
951 ::KeyedVector hInfoMap;
952
953 status_t err = UNKNOWN_ERROR;
954
955 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
956 [&](Status status, const hidl_vec<KeyValue>& map) {
957 if (status == Status::OK) {
958 infoMap = toKeyedVector(map);
959 }
960 err = toStatusT(status);
961 }
962 );
963
964 return hResult.isOk() ? err : DEAD_OBJECT;
965}
966
967status_t DrmHal::getProvisionRequest(String8 const &certType,
968 String8 const &certAuthority, Vector<uint8_t> &request,
969 String8 &defaultUrl) {
970 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800971 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800972
973 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800974 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800975
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800976 if (mPluginV1_2 != NULL) {
977 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
978 toHidlString(certType), toHidlString(certAuthority),
979 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
980 const hidl_string& hDefaultUrl) {
981 if (status == Status_V1_2::OK) {
982 request = toVector(hRequest);
983 defaultUrl = toString8(hDefaultUrl);
984 }
985 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800986 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800987 );
988 } else {
989 Return<void> hResult = mPlugin->getProvisionRequest(
990 toHidlString(certType), toHidlString(certAuthority),
991 [&](Status status, const hidl_vec<uint8_t>& hRequest,
992 const hidl_string& hDefaultUrl) {
993 if (status == Status::OK) {
994 request = toVector(hRequest);
995 defaultUrl = toString8(hDefaultUrl);
996 }
997 err = toStatusT(status);
998 }
999 );
1000 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001001
Adam Stonecea91ce2018-01-22 19:23:28 -08001002 err = hResult.isOk() ? err : DEAD_OBJECT;
1003 mMetrics.mGetProvisionRequestCounter.Increment(err);
1004 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001005}
1006
1007status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001008 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001009 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001010 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001011
1012 status_t err = UNKNOWN_ERROR;
1013
1014 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1015 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1016 const hidl_vec<uint8_t>& hWrappedKey) {
1017 if (status == Status::OK) {
1018 certificate = toVector(hCertificate);
1019 wrappedKey = toVector(hWrappedKey);
1020 }
1021 err = toStatusT(status);
1022 }
1023 );
1024
Adam Stonecea91ce2018-01-22 19:23:28 -08001025 err = hResult.isOk() ? err : DEAD_OBJECT;
1026 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1027 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001028}
1029
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001030status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001031 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001032 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001033
1034 status_t err = UNKNOWN_ERROR;
1035
1036 Return<void> hResult = mPlugin->getSecureStops(
1037 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1038 if (status == Status::OK) {
1039 secureStops = toSecureStops(hSecureStops);
1040 }
1041 err = toStatusT(status);
1042 }
1043 );
1044
1045 return hResult.isOk() ? err : DEAD_OBJECT;
1046}
1047
1048
Jeff Tinker15177d72018-01-25 12:57:55 -08001049status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1050 Mutex::Autolock autoLock(mLock);
1051
1052 if (mInitCheck != OK) {
1053 return mInitCheck;
1054 }
1055
1056 if (mPluginV1_1 == NULL) {
1057 return ERROR_DRM_CANNOT_HANDLE;
1058 }
1059
1060 status_t err = UNKNOWN_ERROR;
1061
1062 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1063 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1064 if (status == Status::OK) {
1065 secureStopIds = toSecureStopIds(hSecureStopIds);
1066 }
1067 err = toStatusT(status);
1068 }
1069 );
1070
1071 return hResult.isOk() ? err : DEAD_OBJECT;
1072}
1073
1074
Jeff Tinkera53d6552017-01-20 00:31:46 -08001075status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1076 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001077 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001078
1079 status_t err = UNKNOWN_ERROR;
1080
1081 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1082 [&](Status status, const SecureStop& hSecureStop) {
1083 if (status == Status::OK) {
1084 secureStop = toVector(hSecureStop.opaqueData);
1085 }
1086 err = toStatusT(status);
1087 }
1088 );
1089
1090 return hResult.isOk() ? err : DEAD_OBJECT;
1091}
1092
1093status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1094 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001095 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001096
Jeff Tinker58ad4752018-02-16 16:51:59 -08001097 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001098 if (mPluginV1_1 != NULL) {
1099 SecureStopRelease secureStopRelease;
1100 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001101 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1102 } else {
1103 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001104 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001105 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001106}
1107
Jeff Tinker15177d72018-01-25 12:57:55 -08001108status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1109 Mutex::Autolock autoLock(mLock);
1110
1111 if (mInitCheck != OK) {
1112 return mInitCheck;
1113 }
1114
1115 if (mPluginV1_1 == NULL) {
1116 return ERROR_DRM_CANNOT_HANDLE;
1117 }
1118
Jeff Tinker58ad4752018-02-16 16:51:59 -08001119 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1120 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001121}
1122
1123status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001124 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001125 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001126
Jeff Tinker58ad4752018-02-16 16:51:59 -08001127 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001128 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001129 status = mPluginV1_1->removeAllSecureStops();
1130 } else {
1131 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001132 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001133 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001134}
1135
Jeff Tinker6d998b62017-12-18 14:37:43 -08001136status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1137 DrmPlugin::HdcpLevel *max) const {
1138 Mutex::Autolock autoLock(mLock);
1139 INIT_CHECK();
1140
1141 if (connected == NULL || max == NULL) {
1142 return BAD_VALUE;
1143 }
1144 status_t err = UNKNOWN_ERROR;
1145
Jeff Tinker6d998b62017-12-18 14:37:43 -08001146 *connected = DrmPlugin::kHdcpLevelUnknown;
1147 *max = DrmPlugin::kHdcpLevelUnknown;
1148
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001149 Return<void> hResult;
1150 if (mPluginV1_2 != NULL) {
1151 hResult = mPluginV1_2->getHdcpLevels_1_2(
1152 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1153 if (status == Status_V1_2::OK) {
1154 *connected = toHdcpLevel(hConnected);
1155 *max = toHdcpLevel(hMax);
1156 }
1157 err = toStatusT_1_2(status);
1158 });
1159 } else if (mPluginV1_1 != NULL) {
1160 hResult = mPluginV1_1->getHdcpLevels(
1161 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1162 if (status == Status::OK) {
1163 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1164 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1165 }
1166 err = toStatusT(status);
1167 });
1168 } else {
1169 return ERROR_DRM_CANNOT_HANDLE;
1170 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001171
1172 return hResult.isOk() ? err : DEAD_OBJECT;
1173}
1174
1175status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1176 Mutex::Autolock autoLock(mLock);
1177 INIT_CHECK();
1178
1179 if (open == NULL || max == NULL) {
1180 return BAD_VALUE;
1181 }
1182 status_t err = UNKNOWN_ERROR;
1183
1184 *open = 0;
1185 *max = 0;
1186
1187 if (mPluginV1_1 == NULL) {
1188 return ERROR_DRM_CANNOT_HANDLE;
1189 }
1190
1191 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1192 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1193 if (status == Status::OK) {
1194 *open = hOpen;
1195 *max = hMax;
1196 }
1197 err = toStatusT(status);
1198 }
1199 );
1200
1201 return hResult.isOk() ? err : DEAD_OBJECT;
1202}
1203
1204status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1205 DrmPlugin::SecurityLevel *level) const {
1206 Mutex::Autolock autoLock(mLock);
1207 INIT_CHECK();
1208
1209 if (level == NULL) {
1210 return BAD_VALUE;
1211 }
1212 status_t err = UNKNOWN_ERROR;
1213
1214 if (mPluginV1_1 == NULL) {
1215 return ERROR_DRM_CANNOT_HANDLE;
1216 }
1217
1218 *level = DrmPlugin::kSecurityLevelUnknown;
1219
1220 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1221 [&](Status status, SecurityLevel hLevel) {
1222 if (status == Status::OK) {
1223 *level = toSecurityLevel(hLevel);
1224 }
1225 err = toStatusT(status);
1226 }
1227 );
1228
1229 return hResult.isOk() ? err : DEAD_OBJECT;
1230}
1231
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001232status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1233 Mutex::Autolock autoLock(mLock);
1234
1235 if (mInitCheck != OK) {
1236 return mInitCheck;
1237 }
1238
1239 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001240 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001241 }
1242
1243 status_t err = UNKNOWN_ERROR;
1244
1245 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1246 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1247 if (status == Status::OK) {
1248 keySetIds = toKeySetIds(hKeySetIds);
1249 }
1250 err = toStatusT(status);
1251 }
1252 );
1253
1254 return hResult.isOk() ? err : DEAD_OBJECT;
1255}
1256
1257status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1258 Mutex::Autolock autoLock(mLock);
1259
1260 if (mInitCheck != OK) {
1261 return mInitCheck;
1262 }
1263
1264 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001265 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001266 }
1267
1268 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1269 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1270}
1271
1272status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1273 DrmPlugin::OfflineLicenseState *licenseState) const {
1274 Mutex::Autolock autoLock(mLock);
1275
1276 if (mInitCheck != OK) {
1277 return mInitCheck;
1278 }
1279
1280 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001281 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001282 }
1283 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1284
1285 status_t err = UNKNOWN_ERROR;
1286
1287 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1288 [&](Status status, OfflineLicenseState hLicenseState) {
1289 if (status == Status::OK) {
1290 *licenseState = toOfflineLicenseState(hLicenseState);
1291 }
1292 err = toStatusT(status);
1293 }
1294 );
1295
1296 return hResult.isOk() ? err : DEAD_OBJECT;
1297}
1298
Jeff Tinkera53d6552017-01-20 00:31:46 -08001299status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1300 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001301 return getPropertyStringInternal(name, value);
1302}
1303
1304status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1305 // This function is internal to the class and should only be called while
1306 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001307 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001308
1309 status_t err = UNKNOWN_ERROR;
1310
1311 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1312 [&](Status status, const hidl_string& hValue) {
1313 if (status == Status::OK) {
1314 value = toString8(hValue);
1315 }
1316 err = toStatusT(status);
1317 }
1318 );
1319
1320 return hResult.isOk() ? err : DEAD_OBJECT;
1321}
1322
1323status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1324 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001325 return getPropertyByteArrayInternal(name, value);
1326}
1327
1328status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1329 // This function is internal to the class and should only be called while
1330 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001331 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001332
1333 status_t err = UNKNOWN_ERROR;
1334
1335 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1336 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1337 if (status == Status::OK) {
1338 value = toVector(hValue);
1339 }
1340 err = toStatusT(status);
1341 }
1342 );
1343
Adam Stonecea91ce2018-01-22 19:23:28 -08001344 err = hResult.isOk() ? err : DEAD_OBJECT;
1345 if (name == kPropertyDeviceUniqueId) {
1346 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1347 }
1348 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001349}
1350
1351status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1352 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001353 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001354
Jeff Tinker58ad4752018-02-16 16:51:59 -08001355 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001356 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001357 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001358}
1359
1360status_t DrmHal::setPropertyByteArray(String8 const &name,
1361 Vector<uint8_t> const &value ) const {
1362 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001363 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001364
Jeff Tinker58ad4752018-02-16 16:51:59 -08001365 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001366 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001367 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001368}
1369
Adam Stone28f27c32018-02-05 15:07:48 -08001370status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1371 if (metrics == nullptr) {
1372 return UNEXPECTED_NULL;
1373 }
1374 mMetrics.Export(metrics);
1375
1376 // Append vendor metrics if they are supported.
1377 if (mPluginV1_1 != NULL) {
1378 String8 vendor;
1379 String8 description;
1380 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1381 || vendor.isEmpty()) {
1382 ALOGE("Get vendor failed or is empty");
1383 vendor = "NONE";
1384 }
1385 if (getPropertyStringInternal(String8("description"), description) != OK
1386 || description.isEmpty()) {
1387 ALOGE("Get description failed or is empty.");
1388 description = "NONE";
1389 }
1390 vendor += ".";
1391 vendor += description;
1392
1393 hidl_vec<DrmMetricGroup> pluginMetrics;
1394 status_t err = UNKNOWN_ERROR;
1395
1396 Return<void> status = mPluginV1_1->getMetrics(
1397 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1398 if (status != Status::OK) {
1399 ALOGV("Error getting plugin metrics: %d", status);
1400 } else {
1401 PersistableBundle pluginBundle;
1402 if (MediaDrmMetrics::HidlMetricsToBundle(
1403 pluginMetrics, &pluginBundle) == OK) {
1404 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1405 }
1406 }
1407 err = toStatusT(status);
1408 });
1409 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001410 }
1411
Adam Stoneab394d12017-12-22 12:34:20 -08001412 return OK;
1413}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001414
1415status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1416 String8 const &algorithm) {
1417 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001418 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001419
1420 DrmSessionManager::Instance()->useSession(sessionId);
1421
Jeff Tinkere6412942018-04-30 17:35:16 -07001422 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001423 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001424 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001425}
1426
1427status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1428 String8 const &algorithm) {
1429 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001430 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001431
1432 DrmSessionManager::Instance()->useSession(sessionId);
1433
Jeff Tinkere6412942018-04-30 17:35:16 -07001434 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001435 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001436 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001437}
1438
1439status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001440 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1441 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001442 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001443 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001444
1445 DrmSessionManager::Instance()->useSession(sessionId);
1446
1447 status_t err = UNKNOWN_ERROR;
1448
1449 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1450 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1451 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1452 if (status == Status::OK) {
1453 output = toVector(hOutput);
1454 }
1455 err = toStatusT(status);
1456 }
1457 );
1458
1459 return hResult.isOk() ? err : DEAD_OBJECT;
1460}
1461
1462status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001463 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1464 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001465 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001466 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001467
1468 DrmSessionManager::Instance()->useSession(sessionId);
1469
1470 status_t err = UNKNOWN_ERROR;
1471
1472 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1473 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1474 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1475 if (status == Status::OK) {
1476 output = toVector(hOutput);
1477 }
1478 err = toStatusT(status);
1479 }
1480 );
1481
1482 return hResult.isOk() ? err : DEAD_OBJECT;
1483}
1484
1485status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001486 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1487 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001488 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001489 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001490
1491 DrmSessionManager::Instance()->useSession(sessionId);
1492
1493 status_t err = UNKNOWN_ERROR;
1494
1495 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1496 toHidlVec(keyId), toHidlVec(message),
1497 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1498 if (status == Status::OK) {
1499 signature = toVector(hSignature);
1500 }
1501 err = toStatusT(status);
1502 }
1503 );
1504
1505 return hResult.isOk() ? err : DEAD_OBJECT;
1506}
1507
1508status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001509 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1510 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001511 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001512 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001513
1514 DrmSessionManager::Instance()->useSession(sessionId);
1515
1516 status_t err = UNKNOWN_ERROR;
1517
1518 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1519 toHidlVec(message), toHidlVec(signature),
1520 [&](Status status, bool hMatch) {
1521 if (status == Status::OK) {
1522 match = hMatch;
1523 } else {
1524 match = false;
1525 }
1526 err = toStatusT(status);
1527 }
1528 );
1529
1530 return hResult.isOk() ? err : DEAD_OBJECT;
1531}
1532
1533status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001534 String8 const &algorithm, Vector<uint8_t> const &message,
1535 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001536 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001537 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001538
1539 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1540 return -EPERM;
1541 }
1542
1543 DrmSessionManager::Instance()->useSession(sessionId);
1544
1545 status_t err = UNKNOWN_ERROR;
1546
1547 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1548 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1549 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1550 if (status == Status::OK) {
1551 signature = toVector(hSignature);
1552 }
1553 err = toStatusT(status);
1554 }
1555 );
1556
1557 return hResult.isOk() ? err : DEAD_OBJECT;
1558}
1559
1560void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1561{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001562 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001563}
1564
1565void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1566{
1567 if (vec.size()) {
1568 obj.writeInt32(vec.size());
1569 obj.write(vec.data(), vec.size());
1570 } else {
1571 obj.writeInt32(0);
1572 }
1573}
1574
Adam Stonefb679e32018-02-07 10:25:48 -08001575void DrmHal::reportFrameworkMetrics() const
1576{
Ray Essick6a305222019-01-28 20:33:18 -08001577 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1578 item->generateSessionID();
1579 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001580 String8 vendor;
1581 String8 description;
1582 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1583 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001584 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001585 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001586 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001587 }
1588 result = getPropertyStringInternal(String8("description"), description);
1589 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001590 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001591 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001592 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001593 }
Adam Stoneab394d12017-12-22 12:34:20 -08001594
Adam Stonefb679e32018-02-07 10:25:48 -08001595 std::string serializedMetrics;
1596 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1597 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001598 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001599 }
Adam Stone32494f52018-02-26 22:53:27 -08001600 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1601 serializedMetrics.size());
1602 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001603 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001604 }
Ray Essick6a305222019-01-28 20:33:18 -08001605 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001606 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001607 }
1608}
1609
1610void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001611{
Adam Stone32494f52018-02-26 22:53:27 -08001612 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001613 String8 vendor;
1614 String8 description;
1615 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1616 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001617 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1618 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1619 metricsVector.size());
1620 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1621 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001622 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001623 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001624 }
1625 }
1626}
1627
Jeff Tinkera53d6552017-01-20 00:31:46 -08001628} // namespace android