blob: 9fc7d04fb3943a24d5b3f27abb29124ee3f50e06 [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"
19#include <utils/Log.h>
20
21#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080023
24#include <android/hardware/drm/1.0/IDrmFactory.h>
25#include <android/hardware/drm/1.0/IDrmPlugin.h>
26#include <android/hardware/drm/1.0/types.h>
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080027#include <android/hidl/manager/1.0/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070028#include <hidl/ServiceManagement.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080029
30#include <media/DrmHal.h>
31#include <media/DrmSessionClientInterface.h>
32#include <media/DrmSessionManager.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070033#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080034#include <media/drm/DrmAPI.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AString.h>
37#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/MediaErrors.h>
39
Jeff Tinker6d998b62017-12-18 14:37:43 -080040using drm::V1_0::KeyedVector;
41using drm::V1_0::KeyRequestType;
42using drm::V1_0::KeyStatusType;
43using drm::V1_0::KeyType;
44using drm::V1_0::KeyValue;
45using drm::V1_1::HdcpLevel;;
46using drm::V1_0::SecureStop;
47using drm::V1_1::SecurityLevel;
48using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080049using ::android::hardware::hidl_array;
50using ::android::hardware::hidl_string;
51using ::android::hardware::hidl_vec;
52using ::android::hardware::Return;
53using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080054using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080055using ::android::sp;
56
57namespace android {
58
Jeff Tinker6d998b62017-12-18 14:37:43 -080059#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
60
Jeff Tinkera53d6552017-01-20 00:31:46 -080061static inline int getCallingPid() {
62 return IPCThreadState::self()->getCallingPid();
63}
64
65static bool checkPermission(const char* permissionString) {
66 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
67 bool ok = checkCallingPermission(String16(permissionString));
68 if (!ok) ALOGE("Request requires %s", permissionString);
69 return ok;
70}
71
72static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
73 Vector<uint8_t> vector;
74 vector.appendArray(vec.data(), vec.size());
75 return *const_cast<const Vector<uint8_t> *>(&vector);
76}
77
78static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
79 hidl_vec<uint8_t> vec;
80 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
81 return vec;
82}
83
84static String8 toString8(const hidl_string &string) {
85 return String8(string.c_str());
86}
87
88static hidl_string toHidlString(const String8& string) {
89 return hidl_string(string.string());
90}
91
Jeff Tinker6d998b62017-12-18 14:37:43 -080092static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
93 switch(level) {
94 case SecurityLevel::SW_SECURE_CRYPTO:
95 return DrmPlugin::kSecurityLevelSwSecureCrypto;
96 case SecurityLevel::SW_SECURE_DECODE:
97 return DrmPlugin::kSecurityLevelSwSecureDecode;
98 case SecurityLevel::HW_SECURE_CRYPTO:
99 return DrmPlugin::kSecurityLevelHwSecureCrypto;
100 case SecurityLevel::HW_SECURE_DECODE:
101 return DrmPlugin::kSecurityLevelHwSecureDecode;
102 case SecurityLevel::HW_SECURE_ALL:
103 return DrmPlugin::kSecurityLevelHwSecureAll;
104 default:
105 return DrmPlugin::kSecurityLevelUnknown;
106 }
107}
108
109static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
110 switch(level) {
111 case HdcpLevel::HDCP_NONE:
112 return DrmPlugin::kHdcpNone;
113 case HdcpLevel::HDCP_V1:
114 return DrmPlugin::kHdcpV1;
115 case HdcpLevel::HDCP_V2:
116 return DrmPlugin::kHdcpV2;
117 case HdcpLevel::HDCP_V2_1:
118 return DrmPlugin::kHdcpV2_1;
119 case HdcpLevel::HDCP_V2_2:
120 return DrmPlugin::kHdcpV2_2;
121 case HdcpLevel::HDCP_NO_OUTPUT:
122 return DrmPlugin::kHdcpNoOutput;
123 default:
124 return DrmPlugin::kHdcpLevelUnknown;
125 }
126}
127
Jeff Tinkera53d6552017-01-20 00:31:46 -0800128
129static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
130 keyedVector) {
131 std::vector<KeyValue> stdKeyedVector;
132 for (size_t i = 0; i < keyedVector.size(); i++) {
133 KeyValue keyValue;
134 keyValue.key = toHidlString(keyedVector.keyAt(i));
135 keyValue.value = toHidlString(keyedVector.valueAt(i));
136 stdKeyedVector.push_back(keyValue);
137 }
138 return ::KeyedVector(stdKeyedVector);
139}
140
141static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
142 hKeyedVector) {
143 KeyedVector<String8, String8> keyedVector;
144 for (size_t i = 0; i < hKeyedVector.size(); i++) {
145 keyedVector.add(toString8(hKeyedVector[i].key),
146 toString8(hKeyedVector[i].value));
147 }
148 return keyedVector;
149}
150
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800151static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800152 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800153 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800154 for (size_t i = 0; i < hSecureStops.size(); i++) {
155 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
156 }
157 return secureStops;
158}
159
160static status_t toStatusT(Status status) {
161 switch (status) {
162 case Status::OK:
163 return OK;
164 break;
165 case Status::ERROR_DRM_NO_LICENSE:
166 return ERROR_DRM_NO_LICENSE;
167 break;
168 case Status::ERROR_DRM_LICENSE_EXPIRED:
169 return ERROR_DRM_LICENSE_EXPIRED;
170 break;
171 case Status::ERROR_DRM_SESSION_NOT_OPENED:
172 return ERROR_DRM_SESSION_NOT_OPENED;
173 break;
174 case Status::ERROR_DRM_CANNOT_HANDLE:
175 return ERROR_DRM_CANNOT_HANDLE;
176 break;
177 case Status::ERROR_DRM_INVALID_STATE:
178 return ERROR_DRM_TAMPER_DETECTED;
179 break;
180 case Status::BAD_VALUE:
181 return BAD_VALUE;
182 break;
183 case Status::ERROR_DRM_NOT_PROVISIONED:
184 return ERROR_DRM_NOT_PROVISIONED;
185 break;
186 case Status::ERROR_DRM_RESOURCE_BUSY:
187 return ERROR_DRM_RESOURCE_BUSY;
188 break;
189 case Status::ERROR_DRM_DEVICE_REVOKED:
190 return ERROR_DRM_DEVICE_REVOKED;
191 break;
192 case Status::ERROR_DRM_UNKNOWN:
193 default:
194 return ERROR_DRM_UNKNOWN;
195 break;
196 }
197}
198
199
200Mutex DrmHal::mLock;
201
202struct DrmSessionClient : public DrmSessionClientInterface {
203 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
204
205 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
206 sp<DrmHal> drm = mDrm.promote();
207 if (drm == NULL) {
208 return true;
209 }
210 status_t err = drm->closeSession(sessionId);
211 if (err != OK) {
212 return false;
213 }
214 drm->sendEvent(EventType::SESSION_RECLAIMED,
215 toHidlVec(sessionId), hidl_vec<uint8_t>());
216 return true;
217 }
218
219protected:
220 virtual ~DrmSessionClient() {}
221
222private:
223 wp<DrmHal> mDrm;
224
225 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
226};
227
228DrmHal::DrmHal()
229 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800230 mFactories(makeDrmFactories()),
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800231 mOpenSessionCounter("/drm/mediadrm/open_session", "status"),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800232 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800233}
234
Jeff Tinker61332812017-05-15 16:53:10 -0700235void DrmHal::closeOpenSessions() {
236 if (mPlugin != NULL) {
237 for (size_t i = 0; i < mOpenSessions.size(); i++) {
238 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
239 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
240 }
241 }
242 mOpenSessions.clear();
243}
244
Jeff Tinkera53d6552017-01-20 00:31:46 -0800245DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700246 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800247 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
248}
249
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800250Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
251 Vector<sp<IDrmFactory>> factories;
252
Jeff Tinker593111f2017-05-25 16:00:21 -0700253 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800254
255 if (manager != NULL) {
256 manager->listByInterface(IDrmFactory::descriptor,
257 [&factories](const hidl_vec<hidl_string> &registered) {
258 for (const auto &instance : registered) {
259 auto factory = IDrmFactory::getService(instance);
260 if (factory != NULL) {
261 factories.push_back(factory);
262 ALOGI("makeDrmFactories: factory instance %s is %s",
263 instance.c_str(),
264 factory->isRemote() ? "Remote" : "Not Remote");
265 }
266 }
267 }
268 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800269 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800270
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800271 if (factories.size() == 0) {
272 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700273 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800274 if (passthrough != NULL) {
275 ALOGI("makeDrmFactories: using default drm instance");
276 factories.push_back(passthrough);
277 } else {
278 ALOGE("Failed to find any drm factories");
279 }
280 }
281 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800282}
283
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800284sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
285 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800286
287 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800288 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800289 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800290 if (status != Status::OK) {
291 ALOGE("Failed to make drm plugin");
292 return;
293 }
294 plugin = hPlugin;
295 }
296 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700297
298 if (!hResult.isOk()) {
299 ALOGE("createPlugin remote call failed");
300 }
301
Jeff Tinkera53d6552017-01-20 00:31:46 -0800302 return plugin;
303}
304
305status_t DrmHal::initCheck() const {
306 return mInitCheck;
307}
308
309status_t DrmHal::setListener(const sp<IDrmClient>& listener)
310{
311 Mutex::Autolock lock(mEventLock);
312 if (mListener != NULL){
313 IInterface::asBinder(mListener)->unlinkToDeath(this);
314 }
315 if (listener != NULL) {
316 IInterface::asBinder(listener)->linkToDeath(this);
317 }
318 mListener = listener;
319 return NO_ERROR;
320}
321
322Return<void> DrmHal::sendEvent(EventType hEventType,
323 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
324
325 mEventLock.lock();
326 sp<IDrmClient> listener = mListener;
327 mEventLock.unlock();
328
329 if (listener != NULL) {
330 Parcel obj;
331 writeByteArray(obj, sessionId);
332 writeByteArray(obj, data);
333
334 Mutex::Autolock lock(mNotifyLock);
335 DrmPlugin::EventType eventType;
336 switch(hEventType) {
337 case EventType::PROVISION_REQUIRED:
338 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
339 break;
340 case EventType::KEY_NEEDED:
341 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
342 break;
343 case EventType::KEY_EXPIRED:
344 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
345 break;
346 case EventType::VENDOR_DEFINED:
347 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
348 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700349 case EventType::SESSION_RECLAIMED:
350 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
351 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800352 default:
353 return Void();
354 }
355 listener->notify(eventType, 0, &obj);
356 }
357 return Void();
358}
359
360Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
361 int64_t expiryTimeInMS) {
362
363 mEventLock.lock();
364 sp<IDrmClient> listener = mListener;
365 mEventLock.unlock();
366
367 if (listener != NULL) {
368 Parcel obj;
369 writeByteArray(obj, sessionId);
370 obj.writeInt64(expiryTimeInMS);
371
372 Mutex::Autolock lock(mNotifyLock);
373 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
374 }
375 return Void();
376}
377
378Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
379 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
380
381 mEventLock.lock();
382 sp<IDrmClient> listener = mListener;
383 mEventLock.unlock();
384
385 if (listener != NULL) {
386 Parcel obj;
387 writeByteArray(obj, sessionId);
388
389 size_t nKeys = keyStatusList.size();
390 obj.writeInt32(nKeys);
391 for (size_t i = 0; i < nKeys; ++i) {
392 const KeyStatus &keyStatus = keyStatusList[i];
393 writeByteArray(obj, keyStatus.keyId);
394 uint32_t type;
395 switch(keyStatus.type) {
396 case KeyStatusType::USABLE:
397 type = DrmPlugin::kKeyStatusType_Usable;
398 break;
399 case KeyStatusType::EXPIRED:
400 type = DrmPlugin::kKeyStatusType_Expired;
401 break;
402 case KeyStatusType::OUTPUTNOTALLOWED:
403 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
404 break;
405 case KeyStatusType::STATUSPENDING:
406 type = DrmPlugin::kKeyStatusType_StatusPending;
407 break;
408 case KeyStatusType::INTERNALERROR:
409 default:
410 type = DrmPlugin::kKeyStatusType_InternalError;
411 break;
412 }
413 obj.writeInt32(type);
414 }
415 obj.writeInt32(hasNewUsableKey);
416
417 Mutex::Autolock lock(mNotifyLock);
418 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
419 }
420 return Void();
421}
422
423bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
424 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800425
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800426 for (size_t i = 0; i < mFactories.size(); i++) {
427 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
428 if (mimeType != "") {
429 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
430 return true;
431 }
432 } else {
433 return true;
434 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800435 }
436 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800437 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800438}
439
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800440status_t DrmHal::createPlugin(const uint8_t uuid[16],
441 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800442 Mutex::Autolock autoLock(mLock);
443
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800444 for (size_t i = 0; i < mFactories.size(); i++) {
445 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
446 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800447 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800448 }
449 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800450
451 if (mPlugin == NULL) {
452 mInitCheck = ERROR_UNSUPPORTED;
453 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700454 if (!mPlugin->setListener(this).isOk()) {
455 mInitCheck = DEAD_OBJECT;
456 } else {
457 mInitCheck = OK;
458 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800459 }
460
461 return mInitCheck;
462}
463
464status_t DrmHal::destroyPlugin() {
465 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800466 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800467
Jeff Tinker61332812017-05-15 16:53:10 -0700468 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700469 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700471 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800472
Jeff Tinker319d5f42017-07-26 15:44:33 -0700473 if (mPlugin != NULL) {
474 if (!mPlugin->setListener(NULL).isOk()) {
475 mInitCheck = DEAD_OBJECT;
476 }
477 }
478 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800479 return OK;
480}
481
482status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
483 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800484 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800485
486 status_t err = UNKNOWN_ERROR;
487
488 bool retry = true;
489 do {
490 hidl_vec<uint8_t> hSessionId;
491
492 Return<void> hResult = mPlugin->openSession(
493 [&](Status status, const hidl_vec<uint8_t>& id) {
494 if (status == Status::OK) {
495 sessionId = toVector(id);
496 }
497 err = toStatusT(status);
498 }
499 );
500
501 if (!hResult.isOk()) {
502 err = DEAD_OBJECT;
503 }
504
505 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
506 mLock.unlock();
507 // reclaimSession may call back to closeSession, since mLock is
508 // shared between Drm instances, we should unlock here to avoid
509 // deadlock.
510 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
511 mLock.lock();
512 } else {
513 retry = false;
514 }
515 } while (retry);
516
517 if (err == OK) {
518 DrmSessionManager::Instance()->addSession(getCallingPid(),
519 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700520 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800521 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800522
523 mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800524 return err;
525}
526
527status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
528 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800529 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800530
Jeff Tinker319d5f42017-07-26 15:44:33 -0700531 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
532 if (status.isOk()) {
533 if (status == Status::OK) {
534 DrmSessionManager::Instance()->removeSession(sessionId);
535 for (size_t i = 0; i < mOpenSessions.size(); i++) {
536 if (mOpenSessions[i] == sessionId) {
537 mOpenSessions.removeAt(i);
538 break;
539 }
Jeff Tinker61332812017-05-15 16:53:10 -0700540 }
541 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700542 reportMetrics();
543 return toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800544 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700545 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800546}
547
548status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
549 Vector<uint8_t> const &initData, String8 const &mimeType,
550 DrmPlugin::KeyType keyType, KeyedVector<String8,
551 String8> const &optionalParameters, Vector<uint8_t> &request,
552 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
553 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800554 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800555
556 DrmSessionManager::Instance()->useSession(sessionId);
557
558 KeyType hKeyType;
559 if (keyType == DrmPlugin::kKeyType_Streaming) {
560 hKeyType = KeyType::STREAMING;
561 } else if (keyType == DrmPlugin::kKeyType_Offline) {
562 hKeyType = KeyType::OFFLINE;
563 } else if (keyType == DrmPlugin::kKeyType_Release) {
564 hKeyType = KeyType::RELEASE;
565 } else {
566 return BAD_VALUE;
567 }
568
569 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
570
571 status_t err = UNKNOWN_ERROR;
572
573 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
574 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
575 [&](Status status, const hidl_vec<uint8_t>& hRequest,
576 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
577
578 if (status == Status::OK) {
579 request = toVector(hRequest);
580 defaultUrl = toString8(hDefaultUrl);
581
582 switch (hKeyRequestType) {
583 case KeyRequestType::INITIAL:
584 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
585 break;
586 case KeyRequestType::RENEWAL:
587 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
588 break;
589 case KeyRequestType::RELEASE:
590 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
591 break;
592 default:
593 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
594 break;
595 }
596 err = toStatusT(status);
597 }
598 });
599
600 return hResult.isOk() ? err : DEAD_OBJECT;
601}
602
603status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
604 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
605 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800606 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800607
608 DrmSessionManager::Instance()->useSession(sessionId);
609
610 status_t err = UNKNOWN_ERROR;
611
612 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
613 toHidlVec(response),
614 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
615 if (status == Status::OK) {
616 keySetId = toVector(hKeySetId);
617 }
618 err = toStatusT(status);
619 }
620 );
621
622 return hResult.isOk() ? err : DEAD_OBJECT;
623}
624
625status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
626 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800627 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800628
629 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
630}
631
632status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
633 Vector<uint8_t> const &keySetId) {
634 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800635 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800636
637 DrmSessionManager::Instance()->useSession(sessionId);
638
639 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
640 toHidlVec(keySetId)));
641}
642
643status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
644 KeyedVector<String8, String8> &infoMap) const {
645 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800646 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800647
648 DrmSessionManager::Instance()->useSession(sessionId);
649
650 ::KeyedVector hInfoMap;
651
652 status_t err = UNKNOWN_ERROR;
653
654 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
655 [&](Status status, const hidl_vec<KeyValue>& map) {
656 if (status == Status::OK) {
657 infoMap = toKeyedVector(map);
658 }
659 err = toStatusT(status);
660 }
661 );
662
663 return hResult.isOk() ? err : DEAD_OBJECT;
664}
665
666status_t DrmHal::getProvisionRequest(String8 const &certType,
667 String8 const &certAuthority, Vector<uint8_t> &request,
668 String8 &defaultUrl) {
669 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800670 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800671
672 status_t err = UNKNOWN_ERROR;
673
674 Return<void> hResult = mPlugin->getProvisionRequest(
675 toHidlString(certType), toHidlString(certAuthority),
676 [&](Status status, const hidl_vec<uint8_t>& hRequest,
677 const hidl_string& hDefaultUrl) {
678 if (status == Status::OK) {
679 request = toVector(hRequest);
680 defaultUrl = toString8(hDefaultUrl);
681 }
682 err = toStatusT(status);
683 }
684 );
685
686 return hResult.isOk() ? err : DEAD_OBJECT;
687}
688
689status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800690 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800691 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800692 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800693
694 status_t err = UNKNOWN_ERROR;
695
696 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
697 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
698 const hidl_vec<uint8_t>& hWrappedKey) {
699 if (status == Status::OK) {
700 certificate = toVector(hCertificate);
701 wrappedKey = toVector(hWrappedKey);
702 }
703 err = toStatusT(status);
704 }
705 );
706
707 return hResult.isOk() ? err : DEAD_OBJECT;
708}
709
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800710status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800711 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800712 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800713
714 status_t err = UNKNOWN_ERROR;
715
716 Return<void> hResult = mPlugin->getSecureStops(
717 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
718 if (status == Status::OK) {
719 secureStops = toSecureStops(hSecureStops);
720 }
721 err = toStatusT(status);
722 }
723 );
724
725 return hResult.isOk() ? err : DEAD_OBJECT;
726}
727
728
729status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
730 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800731 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800732
733 status_t err = UNKNOWN_ERROR;
734
735 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
736 [&](Status status, const SecureStop& hSecureStop) {
737 if (status == Status::OK) {
738 secureStop = toVector(hSecureStop.opaqueData);
739 }
740 err = toStatusT(status);
741 }
742 );
743
744 return hResult.isOk() ? err : DEAD_OBJECT;
745}
746
747status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
748 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800749 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800750
751 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
752}
753
754status_t DrmHal::releaseAllSecureStops() {
755 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800756 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800757
758 return toStatusT(mPlugin->releaseAllSecureStops());
759}
760
Jeff Tinker6d998b62017-12-18 14:37:43 -0800761status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
762 DrmPlugin::HdcpLevel *max) const {
763 Mutex::Autolock autoLock(mLock);
764 INIT_CHECK();
765
766 if (connected == NULL || max == NULL) {
767 return BAD_VALUE;
768 }
769 status_t err = UNKNOWN_ERROR;
770
771 if (mPluginV1_1 == NULL) {
772 return ERROR_DRM_CANNOT_HANDLE;
773 }
774
775 *connected = DrmPlugin::kHdcpLevelUnknown;
776 *max = DrmPlugin::kHdcpLevelUnknown;
777
778 Return<void> hResult = mPluginV1_1->getHdcpLevels(
779 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
780 if (status == Status::OK) {
781 *connected = toHdcpLevel(hConnected);
782 *max = toHdcpLevel(hMax);
783 }
784 err = toStatusT(status);
785 }
786 );
787
788 return hResult.isOk() ? err : DEAD_OBJECT;
789}
790
791status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
792 Mutex::Autolock autoLock(mLock);
793 INIT_CHECK();
794
795 if (open == NULL || max == NULL) {
796 return BAD_VALUE;
797 }
798 status_t err = UNKNOWN_ERROR;
799
800 *open = 0;
801 *max = 0;
802
803 if (mPluginV1_1 == NULL) {
804 return ERROR_DRM_CANNOT_HANDLE;
805 }
806
807 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
808 [&](Status status, uint32_t hOpen, uint32_t hMax) {
809 if (status == Status::OK) {
810 *open = hOpen;
811 *max = hMax;
812 }
813 err = toStatusT(status);
814 }
815 );
816
817 return hResult.isOk() ? err : DEAD_OBJECT;
818}
819
820status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
821 DrmPlugin::SecurityLevel *level) const {
822 Mutex::Autolock autoLock(mLock);
823 INIT_CHECK();
824
825 if (level == NULL) {
826 return BAD_VALUE;
827 }
828 status_t err = UNKNOWN_ERROR;
829
830 if (mPluginV1_1 == NULL) {
831 return ERROR_DRM_CANNOT_HANDLE;
832 }
833
834 *level = DrmPlugin::kSecurityLevelUnknown;
835
836 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
837 [&](Status status, SecurityLevel hLevel) {
838 if (status == Status::OK) {
839 *level = toSecurityLevel(hLevel);
840 }
841 err = toStatusT(status);
842 }
843 );
844
845 return hResult.isOk() ? err : DEAD_OBJECT;
846}
847
848status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
849 const DrmPlugin::SecurityLevel& level) {
850 Mutex::Autolock autoLock(mLock);
851 INIT_CHECK();
852
853 if (mPluginV1_1 == NULL) {
854 return ERROR_DRM_CANNOT_HANDLE;
855 }
856
857 SecurityLevel hSecurityLevel;
858
859 switch(level) {
860 case DrmPlugin::kSecurityLevelSwSecureCrypto:
861 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
862 break;
863 case DrmPlugin::kSecurityLevelSwSecureDecode:
864 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
865 break;
866 case DrmPlugin::kSecurityLevelHwSecureCrypto:
867 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
868 break;
869 case DrmPlugin::kSecurityLevelHwSecureDecode:
870 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
871 break;
872 case DrmPlugin::kSecurityLevelHwSecureAll:
873 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
874 break;
875 default:
876 return ERROR_DRM_CANNOT_HANDLE;
877 }
878
879 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
880 hSecurityLevel);
881 return toStatusT(status);
882}
883
Jeff Tinkera53d6552017-01-20 00:31:46 -0800884status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
885 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700886 return getPropertyStringInternal(name, value);
887}
888
889status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
890 // This function is internal to the class and should only be called while
891 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800892 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800893
894 status_t err = UNKNOWN_ERROR;
895
896 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
897 [&](Status status, const hidl_string& hValue) {
898 if (status == Status::OK) {
899 value = toString8(hValue);
900 }
901 err = toStatusT(status);
902 }
903 );
904
905 return hResult.isOk() ? err : DEAD_OBJECT;
906}
907
908status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
909 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700910 return getPropertyByteArrayInternal(name, value);
911}
912
913status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
914 // This function is internal to the class and should only be called while
915 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800916 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800917
918 status_t err = UNKNOWN_ERROR;
919
920 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
921 [&](Status status, const hidl_vec<uint8_t>& hValue) {
922 if (status == Status::OK) {
923 value = toVector(hValue);
924 }
925 err = toStatusT(status);
926 }
927 );
928
929 return hResult.isOk() ? err : DEAD_OBJECT;
930}
931
932status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
933 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800934 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800935
Jeff Tinker6d998b62017-12-18 14:37:43 -0800936 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937 toHidlString(value));
938 return toStatusT(status);
939}
940
941status_t DrmHal::setPropertyByteArray(String8 const &name,
942 Vector<uint8_t> const &value ) const {
943 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800944 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800945
946 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
947 toHidlVec(value));
948 return toStatusT(status);
949}
950
Adam Stoneab394d12017-12-22 12:34:20 -0800951status_t DrmHal::getMetrics(MediaAnalyticsItem* metrics) {
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800952 // TODO: Move mOpenSessionCounter and suffixes to a separate class
953 // that manages the collection of metrics and exporting them.
954 std::string success_count_name =
955 mOpenSessionCounter.metric_name() + "/ok/count";
956 std::string error_count_name =
957 mOpenSessionCounter.metric_name() + "/error/count";
958 mOpenSessionCounter.ExportValues(
959 [&] (status_t status, int64_t value) {
960 if (status == OK) {
961 metrics->setInt64(success_count_name.c_str(), value);
962 } else {
963 int64_t total_errors(0);
964 metrics->getInt64(error_count_name.c_str(), &total_errors);
965 metrics->setInt64(error_count_name.c_str(),
966 total_errors + value);
967 // TODO: Add support for exporting the list of error values.
968 // This probably needs to be added to MediaAnalyticsItem.
969 }
970 });
Adam Stoneab394d12017-12-22 12:34:20 -0800971 return OK;
972}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800973
974status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
975 String8 const &algorithm) {
976 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800977 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800978
979 DrmSessionManager::Instance()->useSession(sessionId);
980
981 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
982 toHidlString(algorithm));
983 return toStatusT(status);
984}
985
986status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
987 String8 const &algorithm) {
988 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800989 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800990
991 DrmSessionManager::Instance()->useSession(sessionId);
992
993 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
994 toHidlString(algorithm));
995 return toStatusT(status);
996}
997
998status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800999 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1000 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001001 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001002 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001003
1004 DrmSessionManager::Instance()->useSession(sessionId);
1005
1006 status_t err = UNKNOWN_ERROR;
1007
1008 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1009 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1010 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1011 if (status == Status::OK) {
1012 output = toVector(hOutput);
1013 }
1014 err = toStatusT(status);
1015 }
1016 );
1017
1018 return hResult.isOk() ? err : DEAD_OBJECT;
1019}
1020
1021status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001022 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1023 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001024 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001025 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001026
1027 DrmSessionManager::Instance()->useSession(sessionId);
1028
1029 status_t err = UNKNOWN_ERROR;
1030
1031 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1032 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1033 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1034 if (status == Status::OK) {
1035 output = toVector(hOutput);
1036 }
1037 err = toStatusT(status);
1038 }
1039 );
1040
1041 return hResult.isOk() ? err : DEAD_OBJECT;
1042}
1043
1044status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001045 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1046 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001047 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001048 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001049
1050 DrmSessionManager::Instance()->useSession(sessionId);
1051
1052 status_t err = UNKNOWN_ERROR;
1053
1054 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1055 toHidlVec(keyId), toHidlVec(message),
1056 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1057 if (status == Status::OK) {
1058 signature = toVector(hSignature);
1059 }
1060 err = toStatusT(status);
1061 }
1062 );
1063
1064 return hResult.isOk() ? err : DEAD_OBJECT;
1065}
1066
1067status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001068 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1069 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001070 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001071 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001072
1073 DrmSessionManager::Instance()->useSession(sessionId);
1074
1075 status_t err = UNKNOWN_ERROR;
1076
1077 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1078 toHidlVec(message), toHidlVec(signature),
1079 [&](Status status, bool hMatch) {
1080 if (status == Status::OK) {
1081 match = hMatch;
1082 } else {
1083 match = false;
1084 }
1085 err = toStatusT(status);
1086 }
1087 );
1088
1089 return hResult.isOk() ? err : DEAD_OBJECT;
1090}
1091
1092status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001093 String8 const &algorithm, Vector<uint8_t> const &message,
1094 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001095 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001096 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001097
1098 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1099 return -EPERM;
1100 }
1101
1102 DrmSessionManager::Instance()->useSession(sessionId);
1103
1104 status_t err = UNKNOWN_ERROR;
1105
1106 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1107 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1108 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1109 if (status == Status::OK) {
1110 signature = toVector(hSignature);
1111 }
1112 err = toStatusT(status);
1113 }
1114 );
1115
1116 return hResult.isOk() ? err : DEAD_OBJECT;
1117}
1118
1119void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1120{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001121 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001122 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001123 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001124 mInitCheck = NO_INIT;
1125
Jeff Tinker70367f52017-06-16 12:41:33 -07001126 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001127 if (!mPlugin->setListener(NULL).isOk()) {
1128 mInitCheck = DEAD_OBJECT;
1129 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001130 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001131 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001132}
1133
1134void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1135{
1136 if (vec.size()) {
1137 obj.writeInt32(vec.size());
1138 obj.write(vec.data(), vec.size());
1139 } else {
1140 obj.writeInt32(0);
1141 }
1142}
1143
Adam Stoneab394d12017-12-22 12:34:20 -08001144
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001145void DrmHal::reportMetrics() const
1146{
1147 Vector<uint8_t> metrics;
1148 String8 vendor;
1149 String8 description;
1150 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1151 getPropertyStringInternal(String8("description"), description) == OK &&
1152 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1153 status_t res = android::reportDrmPluginMetrics(
1154 metrics, vendor, description);
1155 if (res != OK) {
1156 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1157 }
1158 }
1159}
1160
Jeff Tinkera53d6552017-01-20 00:31:46 -08001161} // namespace android