blob: 731b8d0170fb0dda1efa24a5892a77c6c6588b54 [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 Tinker6d998b62017-12-18 14:37:43 -080042using drm::V1_0::KeyStatusType;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080043using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080044using drm::V1_0::KeyType;
45using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080047using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070049using drm::V1_1::HdcpLevel;
50using drm::V1_1::SecureStopRelease;
51using drm::V1_1::SecurityLevel;
52using drm::V1_2::KeySetId;
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 -0800296
297Mutex DrmHal::mLock;
298
299struct DrmSessionClient : public DrmSessionClientInterface {
300 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
301
302 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
303 sp<DrmHal> drm = mDrm.promote();
304 if (drm == NULL) {
305 return true;
306 }
307 status_t err = drm->closeSession(sessionId);
308 if (err != OK) {
309 return false;
310 }
311 drm->sendEvent(EventType::SESSION_RECLAIMED,
312 toHidlVec(sessionId), hidl_vec<uint8_t>());
313 return true;
314 }
315
316protected:
317 virtual ~DrmSessionClient() {}
318
319private:
320 wp<DrmHal> mDrm;
321
322 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
323};
324
325DrmHal::DrmHal()
326 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800327 mFactories(makeDrmFactories()),
328 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800329}
330
Jeff Tinker61332812017-05-15 16:53:10 -0700331void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800332 Mutex::Autolock autoLock(mLock);
333 auto openSessions = mOpenSessions;
334 for (size_t i = 0; i < openSessions.size(); i++) {
335 mLock.unlock();
336 closeSession(openSessions[i]);
337 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700338 }
339 mOpenSessions.clear();
340}
341
Jeff Tinkera53d6552017-01-20 00:31:46 -0800342DrmHal::~DrmHal() {
343 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
344}
345
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800346void DrmHal::cleanup() {
347 closeOpenSessions();
348
349 Mutex::Autolock autoLock(mLock);
350 reportPluginMetrics();
351 reportFrameworkMetrics();
352
353 setListener(NULL);
354 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800355 if (mPluginV1_2 != NULL) {
356 if (!mPluginV1_2->setListener(NULL).isOk()) {
357 mInitCheck = DEAD_OBJECT;
358 }
359 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800360 if (!mPlugin->setListener(NULL).isOk()) {
361 mInitCheck = DEAD_OBJECT;
362 }
363 }
364 mPlugin.clear();
365 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700366 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800367}
368
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800369Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
370 Vector<sp<IDrmFactory>> factories;
371
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800372 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800373
374 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800375 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800376 [&factories](const hidl_vec<hidl_string> &registered) {
377 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000378 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800379 if (factory != NULL) {
380 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000381 }
382 }
383 }
384 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800385 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000386 [&factories](const hidl_vec<hidl_string> &registered) {
387 for (const auto &instance : registered) {
388 auto factory = drm::V1_1::IDrmFactory::getService(instance);
389 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000390 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800391 }
392 }
393 }
394 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700395 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700396 [&factories](const hidl_vec<hidl_string> &registered) {
397 for (const auto &instance : registered) {
398 auto factory = drm::V1_2::IDrmFactory::getService(instance);
399 if (factory != NULL) {
400 factories.push_back(factory);
401 }
402 }
403 }
404 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800405 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800406
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800407 if (factories.size() == 0) {
408 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700409 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800410 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000411 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800412 factories.push_back(passthrough);
413 } else {
414 ALOGE("Failed to find any drm factories");
415 }
416 }
417 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800418}
419
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800420sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
421 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800422 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800423 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424
425 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800426 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800427 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800428 if (status != Status::OK) {
429 ALOGE("Failed to make drm plugin");
430 return;
431 }
432 plugin = hPlugin;
433 }
434 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700435
436 if (!hResult.isOk()) {
437 ALOGE("createPlugin remote call failed");
438 }
439
Jeff Tinkera53d6552017-01-20 00:31:46 -0800440 return plugin;
441}
442
443status_t DrmHal::initCheck() const {
444 return mInitCheck;
445}
446
447status_t DrmHal::setListener(const sp<IDrmClient>& listener)
448{
449 Mutex::Autolock lock(mEventLock);
450 if (mListener != NULL){
451 IInterface::asBinder(mListener)->unlinkToDeath(this);
452 }
453 if (listener != NULL) {
454 IInterface::asBinder(listener)->linkToDeath(this);
455 }
456 mListener = listener;
457 return NO_ERROR;
458}
459
460Return<void> DrmHal::sendEvent(EventType hEventType,
461 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800462 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800463
464 mEventLock.lock();
465 sp<IDrmClient> listener = mListener;
466 mEventLock.unlock();
467
468 if (listener != NULL) {
469 Parcel obj;
470 writeByteArray(obj, sessionId);
471 writeByteArray(obj, data);
472
473 Mutex::Autolock lock(mNotifyLock);
474 DrmPlugin::EventType eventType;
475 switch(hEventType) {
476 case EventType::PROVISION_REQUIRED:
477 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
478 break;
479 case EventType::KEY_NEEDED:
480 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
481 break;
482 case EventType::KEY_EXPIRED:
483 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
484 break;
485 case EventType::VENDOR_DEFINED:
486 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
487 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700488 case EventType::SESSION_RECLAIMED:
489 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
490 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800491 default:
492 return Void();
493 }
494 listener->notify(eventType, 0, &obj);
495 }
496 return Void();
497}
498
499Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
500 int64_t expiryTimeInMS) {
501
502 mEventLock.lock();
503 sp<IDrmClient> listener = mListener;
504 mEventLock.unlock();
505
506 if (listener != NULL) {
507 Parcel obj;
508 writeByteArray(obj, sessionId);
509 obj.writeInt64(expiryTimeInMS);
510
511 Mutex::Autolock lock(mNotifyLock);
512 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
513 }
514 return Void();
515}
516
517Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
518 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
519
520 mEventLock.lock();
521 sp<IDrmClient> listener = mListener;
522 mEventLock.unlock();
523
524 if (listener != NULL) {
525 Parcel obj;
526 writeByteArray(obj, sessionId);
527
528 size_t nKeys = keyStatusList.size();
529 obj.writeInt32(nKeys);
530 for (size_t i = 0; i < nKeys; ++i) {
531 const KeyStatus &keyStatus = keyStatusList[i];
532 writeByteArray(obj, keyStatus.keyId);
533 uint32_t type;
534 switch(keyStatus.type) {
535 case KeyStatusType::USABLE:
536 type = DrmPlugin::kKeyStatusType_Usable;
537 break;
538 case KeyStatusType::EXPIRED:
539 type = DrmPlugin::kKeyStatusType_Expired;
540 break;
541 case KeyStatusType::OUTPUTNOTALLOWED:
542 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
543 break;
544 case KeyStatusType::STATUSPENDING:
545 type = DrmPlugin::kKeyStatusType_StatusPending;
546 break;
547 case KeyStatusType::INTERNALERROR:
548 default:
549 type = DrmPlugin::kKeyStatusType_InternalError;
550 break;
551 }
552 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800553 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800554 }
555 obj.writeInt32(hasNewUsableKey);
556
557 Mutex::Autolock lock(mNotifyLock);
558 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800559 } else {
560 // There's no listener. But we still want to count the key change
561 // events.
562 size_t nKeys = keyStatusList.size();
563 for (size_t i = 0; i < nKeys; i++) {
564 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
565 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800566 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800567
Jeff Tinkera53d6552017-01-20 00:31:46 -0800568 return Void();
569}
570
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800571Return<void> DrmHal::sendSessionLostState(
572 const hidl_vec<uint8_t>& sessionId) {
573
574 mEventLock.lock();
575 sp<IDrmClient> listener = mListener;
576 mEventLock.unlock();
577
578 if (listener != NULL) {
579 Parcel obj;
580 writeByteArray(obj, sessionId);
581 Mutex::Autolock lock(mNotifyLock);
582 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
583 }
584 return Void();
585}
586
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800587status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
588 const uint8_t uuid[16],
589 const String8 &mimeType,
590 DrmPlugin::SecurityLevel level,
591 bool *isSupported) {
592 *isSupported = false;
593
594 // handle default value cases
595 if (level == DrmPlugin::kSecurityLevelUnknown) {
596 if (mimeType == "") {
597 // isCryptoSchemeSupported(uuid)
598 *isSupported = true;
599 } else {
600 // isCryptoSchemeSupported(uuid, mimeType)
601 *isSupported = factory->isContentTypeSupported(mimeType.string());
602 }
603 return OK;
604 } else if (mimeType == "") {
605 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800606 }
607
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800608 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
609 if (factoryV1_2 == NULL) {
610 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800611 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800612 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
613 mimeType.string(), toHidlSecurityLevel(level));
614 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800615 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800616}
617
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800618status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
619 const String8 &mimeType,
620 DrmPlugin::SecurityLevel level,
621 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800622 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800623 *isSupported = false;
624 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
625 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
626 return matchMimeTypeAndSecurityLevel(mFactories[i],
627 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800628 }
629 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800630 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800631}
632
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800633status_t DrmHal::createPlugin(const uint8_t uuid[16],
634 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800635 Mutex::Autolock autoLock(mLock);
636
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800637 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800638 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800639 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
640 if (plugin != NULL) {
641 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800642 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700643 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800644 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800645 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800646 }
647 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800648
649 if (mPlugin == NULL) {
650 mInitCheck = ERROR_UNSUPPORTED;
651 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800652 mInitCheck = OK;
653 if (mPluginV1_2 != NULL) {
654 if (!mPluginV1_2->setListener(this).isOk()) {
655 mInitCheck = DEAD_OBJECT;
656 }
657 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700658 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800659 }
660 if (mInitCheck != OK) {
661 mPlugin.clear();
662 mPluginV1_1.clear();
663 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700664 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800665 }
666
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800667
Jeff Tinkera53d6552017-01-20 00:31:46 -0800668 return mInitCheck;
669}
670
671status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800672 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800673 return OK;
674}
675
Jeff Tinker41d279a2018-02-11 19:52:08 +0000676status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
677 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800678 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800679 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800680
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800681 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000682 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000683
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800684 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000685 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800686 } else {
687 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
688 return ERROR_DRM_CANNOT_HANDLE;
689 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000690 }
691
692 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800693 bool retry = true;
694 do {
695 hidl_vec<uint8_t> hSessionId;
696
Jeff Tinker41d279a2018-02-11 19:52:08 +0000697 Return<void> hResult;
698 if (mPluginV1_1 == NULL || !setSecurityLevel) {
699 hResult = mPlugin->openSession(
700 [&](Status status,const hidl_vec<uint8_t>& id) {
701 if (status == Status::OK) {
702 sessionId = toVector(id);
703 }
704 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800705 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000706 );
707 } else {
708 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
709 [&](Status status, const hidl_vec<uint8_t>& id) {
710 if (status == Status::OK) {
711 sessionId = toVector(id);
712 }
713 err = toStatusT(status);
714 }
715 );
716 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800717
718 if (!hResult.isOk()) {
719 err = DEAD_OBJECT;
720 }
721
722 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
723 mLock.unlock();
724 // reclaimSession may call back to closeSession, since mLock is
725 // shared between Drm instances, we should unlock here to avoid
726 // deadlock.
727 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
728 mLock.lock();
729 } else {
730 retry = false;
731 }
732 } while (retry);
733
734 if (err == OK) {
735 DrmSessionManager::Instance()->addSession(getCallingPid(),
736 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700737 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800738 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800739 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800740
Adam Stonef0e618d2018-01-17 19:20:41 -0800741 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800742 return err;
743}
744
745status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
746 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800747 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800748
Jeff Tinker319d5f42017-07-26 15:44:33 -0700749 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
750 if (status.isOk()) {
751 if (status == Status::OK) {
752 DrmSessionManager::Instance()->removeSession(sessionId);
753 for (size_t i = 0; i < mOpenSessions.size(); i++) {
754 if (mOpenSessions[i] == sessionId) {
755 mOpenSessions.removeAt(i);
756 break;
757 }
Jeff Tinker61332812017-05-15 16:53:10 -0700758 }
759 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800760 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800761 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800762 mMetrics.mCloseSessionCounter.Increment(response);
763 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800764 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800765 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700766 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800767}
768
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800769static DrmPlugin::KeyRequestType toKeyRequestType(
770 KeyRequestType keyRequestType) {
771 switch (keyRequestType) {
772 case KeyRequestType::INITIAL:
773 return DrmPlugin::kKeyRequestType_Initial;
774 break;
775 case KeyRequestType::RENEWAL:
776 return DrmPlugin::kKeyRequestType_Renewal;
777 break;
778 case KeyRequestType::RELEASE:
779 return DrmPlugin::kKeyRequestType_Release;
780 break;
781 default:
782 return DrmPlugin::kKeyRequestType_Unknown;
783 break;
784 }
785}
786
787static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
788 KeyRequestType_V1_1 keyRequestType) {
789 switch (keyRequestType) {
790 case KeyRequestType_V1_1::NONE:
791 return DrmPlugin::kKeyRequestType_None;
792 break;
793 case KeyRequestType_V1_1::UPDATE:
794 return DrmPlugin::kKeyRequestType_Update;
795 break;
796 default:
797 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
798 break;
799 }
800}
801
Jeff Tinkera53d6552017-01-20 00:31:46 -0800802status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
803 Vector<uint8_t> const &initData, String8 const &mimeType,
804 DrmPlugin::KeyType keyType, KeyedVector<String8,
805 String8> const &optionalParameters, Vector<uint8_t> &request,
806 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
807 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800808 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800809 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800810
811 DrmSessionManager::Instance()->useSession(sessionId);
812
813 KeyType hKeyType;
814 if (keyType == DrmPlugin::kKeyType_Streaming) {
815 hKeyType = KeyType::STREAMING;
816 } else if (keyType == DrmPlugin::kKeyType_Offline) {
817 hKeyType = KeyType::OFFLINE;
818 } else if (keyType == DrmPlugin::kKeyType_Release) {
819 hKeyType = KeyType::RELEASE;
820 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800821 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800822 return BAD_VALUE;
823 }
824
825 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
826
827 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800828 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800829
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800830 if (mPluginV1_2 != NULL) {
831 hResult = mPluginV1_2->getKeyRequest_1_2(
832 toHidlVec(sessionId), toHidlVec(initData),
833 toHidlString(mimeType), hKeyType, hOptionalParameters,
834 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
835 KeyRequestType_V1_1 hKeyRequestType,
836 const hidl_string& hDefaultUrl) {
837 if (status == Status_V1_2::OK) {
838 request = toVector(hRequest);
839 defaultUrl = toString8(hDefaultUrl);
840 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
841 }
842 err = toStatusT_1_2(status);
843 });
844 } else if (mPluginV1_1 != NULL) {
845 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800846 toHidlVec(sessionId), toHidlVec(initData),
847 toHidlString(mimeType), hKeyType, hOptionalParameters,
848 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800849 KeyRequestType_V1_1 hKeyRequestType,
850 const hidl_string& hDefaultUrl) {
851 if (status == Status::OK) {
852 request = toVector(hRequest);
853 defaultUrl = toString8(hDefaultUrl);
854 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800855 }
856 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800857 });
858 } else {
859 hResult = mPlugin->getKeyRequest(
860 toHidlVec(sessionId), toHidlVec(initData),
861 toHidlString(mimeType), hKeyType, hOptionalParameters,
862 [&](Status status, const hidl_vec<uint8_t>& hRequest,
863 KeyRequestType hKeyRequestType,
864 const hidl_string& hDefaultUrl) {
865 if (status == Status::OK) {
866 request = toVector(hRequest);
867 defaultUrl = toString8(hDefaultUrl);
868 *keyRequestType = toKeyRequestType(hKeyRequestType);
869 }
870 err = toStatusT(status);
871 });
872 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800873
Adam Stonef0e618d2018-01-17 19:20:41 -0800874 err = hResult.isOk() ? err : DEAD_OBJECT;
875 keyRequestTimer.SetAttribute(err);
876 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800877}
878
879status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
880 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
881 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800882 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800883
Jeff Tinker6d998b62017-12-18 14:37:43 -0800884 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800885
886 DrmSessionManager::Instance()->useSession(sessionId);
887
888 status_t err = UNKNOWN_ERROR;
889
890 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
891 toHidlVec(response),
892 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
893 if (status == Status::OK) {
894 keySetId = toVector(hKeySetId);
895 }
896 err = toStatusT(status);
897 }
898 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800899 err = hResult.isOk() ? err : DEAD_OBJECT;
900 keyResponseTimer.SetAttribute(err);
901 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800902}
903
904status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
905 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800906 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800907
Jeff Tinker58ad4752018-02-16 16:51:59 -0800908 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
909 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800910}
911
912status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
913 Vector<uint8_t> const &keySetId) {
914 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800915 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800916
917 DrmSessionManager::Instance()->useSession(sessionId);
918
Jeff Tinker58ad4752018-02-16 16:51:59 -0800919 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
920 toHidlVec(keySetId));
921 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800922}
923
924status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
925 KeyedVector<String8, String8> &infoMap) const {
926 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800927 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800928
929 DrmSessionManager::Instance()->useSession(sessionId);
930
931 ::KeyedVector hInfoMap;
932
933 status_t err = UNKNOWN_ERROR;
934
935 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
936 [&](Status status, const hidl_vec<KeyValue>& map) {
937 if (status == Status::OK) {
938 infoMap = toKeyedVector(map);
939 }
940 err = toStatusT(status);
941 }
942 );
943
944 return hResult.isOk() ? err : DEAD_OBJECT;
945}
946
947status_t DrmHal::getProvisionRequest(String8 const &certType,
948 String8 const &certAuthority, Vector<uint8_t> &request,
949 String8 &defaultUrl) {
950 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800951 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800952
953 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800954 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800955
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800956 if (mPluginV1_2 != NULL) {
957 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
958 toHidlString(certType), toHidlString(certAuthority),
959 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
960 const hidl_string& hDefaultUrl) {
961 if (status == Status_V1_2::OK) {
962 request = toVector(hRequest);
963 defaultUrl = toString8(hDefaultUrl);
964 }
965 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800966 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800967 );
968 } else {
969 Return<void> hResult = mPlugin->getProvisionRequest(
970 toHidlString(certType), toHidlString(certAuthority),
971 [&](Status status, const hidl_vec<uint8_t>& hRequest,
972 const hidl_string& hDefaultUrl) {
973 if (status == Status::OK) {
974 request = toVector(hRequest);
975 defaultUrl = toString8(hDefaultUrl);
976 }
977 err = toStatusT(status);
978 }
979 );
980 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800981
Adam Stonecea91ce2018-01-22 19:23:28 -0800982 err = hResult.isOk() ? err : DEAD_OBJECT;
983 mMetrics.mGetProvisionRequestCounter.Increment(err);
984 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800985}
986
987status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800988 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800989 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800990 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800991
992 status_t err = UNKNOWN_ERROR;
993
994 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
995 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
996 const hidl_vec<uint8_t>& hWrappedKey) {
997 if (status == Status::OK) {
998 certificate = toVector(hCertificate);
999 wrappedKey = toVector(hWrappedKey);
1000 }
1001 err = toStatusT(status);
1002 }
1003 );
1004
Adam Stonecea91ce2018-01-22 19:23:28 -08001005 err = hResult.isOk() ? err : DEAD_OBJECT;
1006 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1007 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001008}
1009
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001010status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001011 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001012 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001013
1014 status_t err = UNKNOWN_ERROR;
1015
1016 Return<void> hResult = mPlugin->getSecureStops(
1017 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1018 if (status == Status::OK) {
1019 secureStops = toSecureStops(hSecureStops);
1020 }
1021 err = toStatusT(status);
1022 }
1023 );
1024
1025 return hResult.isOk() ? err : DEAD_OBJECT;
1026}
1027
1028
Jeff Tinker15177d72018-01-25 12:57:55 -08001029status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1030 Mutex::Autolock autoLock(mLock);
1031
1032 if (mInitCheck != OK) {
1033 return mInitCheck;
1034 }
1035
1036 if (mPluginV1_1 == NULL) {
1037 return ERROR_DRM_CANNOT_HANDLE;
1038 }
1039
1040 status_t err = UNKNOWN_ERROR;
1041
1042 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1043 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1044 if (status == Status::OK) {
1045 secureStopIds = toSecureStopIds(hSecureStopIds);
1046 }
1047 err = toStatusT(status);
1048 }
1049 );
1050
1051 return hResult.isOk() ? err : DEAD_OBJECT;
1052}
1053
1054
Jeff Tinkera53d6552017-01-20 00:31:46 -08001055status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1056 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001057 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001058
1059 status_t err = UNKNOWN_ERROR;
1060
1061 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1062 [&](Status status, const SecureStop& hSecureStop) {
1063 if (status == Status::OK) {
1064 secureStop = toVector(hSecureStop.opaqueData);
1065 }
1066 err = toStatusT(status);
1067 }
1068 );
1069
1070 return hResult.isOk() ? err : DEAD_OBJECT;
1071}
1072
1073status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1074 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001075 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001076
Jeff Tinker58ad4752018-02-16 16:51:59 -08001077 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001078 if (mPluginV1_1 != NULL) {
1079 SecureStopRelease secureStopRelease;
1080 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001081 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1082 } else {
1083 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001084 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001085 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001086}
1087
Jeff Tinker15177d72018-01-25 12:57:55 -08001088status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1089 Mutex::Autolock autoLock(mLock);
1090
1091 if (mInitCheck != OK) {
1092 return mInitCheck;
1093 }
1094
1095 if (mPluginV1_1 == NULL) {
1096 return ERROR_DRM_CANNOT_HANDLE;
1097 }
1098
Jeff Tinker58ad4752018-02-16 16:51:59 -08001099 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1100 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001101}
1102
1103status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001104 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001105 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001106
Jeff Tinker58ad4752018-02-16 16:51:59 -08001107 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001108 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001109 status = mPluginV1_1->removeAllSecureStops();
1110 } else {
1111 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001112 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001113 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001114}
1115
Jeff Tinker6d998b62017-12-18 14:37:43 -08001116status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1117 DrmPlugin::HdcpLevel *max) const {
1118 Mutex::Autolock autoLock(mLock);
1119 INIT_CHECK();
1120
1121 if (connected == NULL || max == NULL) {
1122 return BAD_VALUE;
1123 }
1124 status_t err = UNKNOWN_ERROR;
1125
Jeff Tinker6d998b62017-12-18 14:37:43 -08001126 *connected = DrmPlugin::kHdcpLevelUnknown;
1127 *max = DrmPlugin::kHdcpLevelUnknown;
1128
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001129 Return<void> hResult;
1130 if (mPluginV1_2 != NULL) {
1131 hResult = mPluginV1_2->getHdcpLevels_1_2(
1132 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1133 if (status == Status_V1_2::OK) {
1134 *connected = toHdcpLevel(hConnected);
1135 *max = toHdcpLevel(hMax);
1136 }
1137 err = toStatusT_1_2(status);
1138 });
1139 } else if (mPluginV1_1 != NULL) {
1140 hResult = mPluginV1_1->getHdcpLevels(
1141 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1142 if (status == Status::OK) {
1143 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1144 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1145 }
1146 err = toStatusT(status);
1147 });
1148 } else {
1149 return ERROR_DRM_CANNOT_HANDLE;
1150 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001151
1152 return hResult.isOk() ? err : DEAD_OBJECT;
1153}
1154
1155status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1156 Mutex::Autolock autoLock(mLock);
1157 INIT_CHECK();
1158
1159 if (open == NULL || max == NULL) {
1160 return BAD_VALUE;
1161 }
1162 status_t err = UNKNOWN_ERROR;
1163
1164 *open = 0;
1165 *max = 0;
1166
1167 if (mPluginV1_1 == NULL) {
1168 return ERROR_DRM_CANNOT_HANDLE;
1169 }
1170
1171 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1172 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1173 if (status == Status::OK) {
1174 *open = hOpen;
1175 *max = hMax;
1176 }
1177 err = toStatusT(status);
1178 }
1179 );
1180
1181 return hResult.isOk() ? err : DEAD_OBJECT;
1182}
1183
1184status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1185 DrmPlugin::SecurityLevel *level) const {
1186 Mutex::Autolock autoLock(mLock);
1187 INIT_CHECK();
1188
1189 if (level == NULL) {
1190 return BAD_VALUE;
1191 }
1192 status_t err = UNKNOWN_ERROR;
1193
1194 if (mPluginV1_1 == NULL) {
1195 return ERROR_DRM_CANNOT_HANDLE;
1196 }
1197
1198 *level = DrmPlugin::kSecurityLevelUnknown;
1199
1200 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1201 [&](Status status, SecurityLevel hLevel) {
1202 if (status == Status::OK) {
1203 *level = toSecurityLevel(hLevel);
1204 }
1205 err = toStatusT(status);
1206 }
1207 );
1208
1209 return hResult.isOk() ? err : DEAD_OBJECT;
1210}
1211
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001212status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1213 Mutex::Autolock autoLock(mLock);
1214
1215 if (mInitCheck != OK) {
1216 return mInitCheck;
1217 }
1218
1219 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001220 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001221 }
1222
1223 status_t err = UNKNOWN_ERROR;
1224
1225 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1226 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1227 if (status == Status::OK) {
1228 keySetIds = toKeySetIds(hKeySetIds);
1229 }
1230 err = toStatusT(status);
1231 }
1232 );
1233
1234 return hResult.isOk() ? err : DEAD_OBJECT;
1235}
1236
1237status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1238 Mutex::Autolock autoLock(mLock);
1239
1240 if (mInitCheck != OK) {
1241 return mInitCheck;
1242 }
1243
1244 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001245 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001246 }
1247
1248 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1249 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1250}
1251
1252status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1253 DrmPlugin::OfflineLicenseState *licenseState) const {
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 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1264
1265 status_t err = UNKNOWN_ERROR;
1266
1267 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1268 [&](Status status, OfflineLicenseState hLicenseState) {
1269 if (status == Status::OK) {
1270 *licenseState = toOfflineLicenseState(hLicenseState);
1271 }
1272 err = toStatusT(status);
1273 }
1274 );
1275
1276 return hResult.isOk() ? err : DEAD_OBJECT;
1277}
1278
Jeff Tinkera53d6552017-01-20 00:31:46 -08001279status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1280 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001281 return getPropertyStringInternal(name, value);
1282}
1283
1284status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1285 // This function is internal to the class and should only be called while
1286 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001287 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001288
1289 status_t err = UNKNOWN_ERROR;
1290
1291 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1292 [&](Status status, const hidl_string& hValue) {
1293 if (status == Status::OK) {
1294 value = toString8(hValue);
1295 }
1296 err = toStatusT(status);
1297 }
1298 );
1299
1300 return hResult.isOk() ? err : DEAD_OBJECT;
1301}
1302
1303status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1304 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001305 return getPropertyByteArrayInternal(name, value);
1306}
1307
1308status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1309 // This function is internal to the class and should only be called while
1310 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001311 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001312
1313 status_t err = UNKNOWN_ERROR;
1314
1315 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1316 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1317 if (status == Status::OK) {
1318 value = toVector(hValue);
1319 }
1320 err = toStatusT(status);
1321 }
1322 );
1323
Adam Stonecea91ce2018-01-22 19:23:28 -08001324 err = hResult.isOk() ? err : DEAD_OBJECT;
1325 if (name == kPropertyDeviceUniqueId) {
1326 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1327 }
1328 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001329}
1330
1331status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1332 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001333 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001334
Jeff Tinker58ad4752018-02-16 16:51:59 -08001335 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001336 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001337 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001338}
1339
1340status_t DrmHal::setPropertyByteArray(String8 const &name,
1341 Vector<uint8_t> const &value ) const {
1342 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001343 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001344
Jeff Tinker58ad4752018-02-16 16:51:59 -08001345 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001346 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001347 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001348}
1349
Adam Stone28f27c32018-02-05 15:07:48 -08001350status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1351 if (metrics == nullptr) {
1352 return UNEXPECTED_NULL;
1353 }
1354 mMetrics.Export(metrics);
1355
1356 // Append vendor metrics if they are supported.
1357 if (mPluginV1_1 != NULL) {
1358 String8 vendor;
1359 String8 description;
1360 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1361 || vendor.isEmpty()) {
1362 ALOGE("Get vendor failed or is empty");
1363 vendor = "NONE";
1364 }
1365 if (getPropertyStringInternal(String8("description"), description) != OK
1366 || description.isEmpty()) {
1367 ALOGE("Get description failed or is empty.");
1368 description = "NONE";
1369 }
1370 vendor += ".";
1371 vendor += description;
1372
1373 hidl_vec<DrmMetricGroup> pluginMetrics;
1374 status_t err = UNKNOWN_ERROR;
1375
1376 Return<void> status = mPluginV1_1->getMetrics(
1377 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1378 if (status != Status::OK) {
1379 ALOGV("Error getting plugin metrics: %d", status);
1380 } else {
1381 PersistableBundle pluginBundle;
1382 if (MediaDrmMetrics::HidlMetricsToBundle(
1383 pluginMetrics, &pluginBundle) == OK) {
1384 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1385 }
1386 }
1387 err = toStatusT(status);
1388 });
1389 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001390 }
1391
Adam Stoneab394d12017-12-22 12:34:20 -08001392 return OK;
1393}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001394
1395status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1396 String8 const &algorithm) {
1397 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001398 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001399
1400 DrmSessionManager::Instance()->useSession(sessionId);
1401
Jeff Tinkere6412942018-04-30 17:35:16 -07001402 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001403 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001404 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001405}
1406
1407status_t DrmHal::setMacAlgorithm(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->setMacAlgorithm(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::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001420 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1421 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001422 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001423 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001424
1425 DrmSessionManager::Instance()->useSession(sessionId);
1426
1427 status_t err = UNKNOWN_ERROR;
1428
1429 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1430 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1431 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1432 if (status == Status::OK) {
1433 output = toVector(hOutput);
1434 }
1435 err = toStatusT(status);
1436 }
1437 );
1438
1439 return hResult.isOk() ? err : DEAD_OBJECT;
1440}
1441
1442status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001443 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1444 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001445 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001446 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001447
1448 DrmSessionManager::Instance()->useSession(sessionId);
1449
1450 status_t err = UNKNOWN_ERROR;
1451
1452 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1453 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1454 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1455 if (status == Status::OK) {
1456 output = toVector(hOutput);
1457 }
1458 err = toStatusT(status);
1459 }
1460 );
1461
1462 return hResult.isOk() ? err : DEAD_OBJECT;
1463}
1464
1465status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001466 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1467 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001468 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001469 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001470
1471 DrmSessionManager::Instance()->useSession(sessionId);
1472
1473 status_t err = UNKNOWN_ERROR;
1474
1475 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1476 toHidlVec(keyId), toHidlVec(message),
1477 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1478 if (status == Status::OK) {
1479 signature = toVector(hSignature);
1480 }
1481 err = toStatusT(status);
1482 }
1483 );
1484
1485 return hResult.isOk() ? err : DEAD_OBJECT;
1486}
1487
1488status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001489 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1490 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001491 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001492 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001493
1494 DrmSessionManager::Instance()->useSession(sessionId);
1495
1496 status_t err = UNKNOWN_ERROR;
1497
1498 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1499 toHidlVec(message), toHidlVec(signature),
1500 [&](Status status, bool hMatch) {
1501 if (status == Status::OK) {
1502 match = hMatch;
1503 } else {
1504 match = false;
1505 }
1506 err = toStatusT(status);
1507 }
1508 );
1509
1510 return hResult.isOk() ? err : DEAD_OBJECT;
1511}
1512
1513status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001514 String8 const &algorithm, Vector<uint8_t> const &message,
1515 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001516 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001517 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001518
1519 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1520 return -EPERM;
1521 }
1522
1523 DrmSessionManager::Instance()->useSession(sessionId);
1524
1525 status_t err = UNKNOWN_ERROR;
1526
1527 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1528 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1529 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1530 if (status == Status::OK) {
1531 signature = toVector(hSignature);
1532 }
1533 err = toStatusT(status);
1534 }
1535 );
1536
1537 return hResult.isOk() ? err : DEAD_OBJECT;
1538}
1539
1540void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1541{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001542 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001543}
1544
1545void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1546{
1547 if (vec.size()) {
1548 obj.writeInt32(vec.size());
1549 obj.write(vec.data(), vec.size());
1550 } else {
1551 obj.writeInt32(0);
1552 }
1553}
1554
Adam Stonefb679e32018-02-07 10:25:48 -08001555void DrmHal::reportFrameworkMetrics() const
1556{
Ray Essick6a305222019-01-28 20:33:18 -08001557 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1558 item->generateSessionID();
1559 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001560 String8 vendor;
1561 String8 description;
1562 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1563 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001564 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001565 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001566 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001567 }
1568 result = getPropertyStringInternal(String8("description"), description);
1569 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001570 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001571 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001572 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001573 }
Adam Stoneab394d12017-12-22 12:34:20 -08001574
Adam Stonefb679e32018-02-07 10:25:48 -08001575 std::string serializedMetrics;
1576 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1577 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001578 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001579 }
Adam Stone32494f52018-02-26 22:53:27 -08001580 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1581 serializedMetrics.size());
1582 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001583 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001584 }
Ray Essick6a305222019-01-28 20:33:18 -08001585 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001586 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001587 }
1588}
1589
1590void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001591{
Adam Stone32494f52018-02-26 22:53:27 -08001592 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001593 String8 vendor;
1594 String8 description;
1595 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1596 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001597 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1598 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1599 metricsVector.size());
1600 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1601 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001602 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001603 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001604 }
1605 }
1606}
1607
Jeff Tinkera53d6552017-01-20 00:31:46 -08001608} // namespace android