blob: e51ec4da726bb00e5b1e22ae5ab76b0c9b44aaf1 [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;
Jeff Tinker6d998b62017-12-18 14:37:43 -080041using drm::V1_0::KeyStatusType;
42using drm::V1_0::KeyType;
43using drm::V1_0::KeyValue;
44using drm::V1_1::HdcpLevel;;
45using drm::V1_0::SecureStop;
46using drm::V1_1::SecurityLevel;
47using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080048using ::android::hardware::hidl_array;
49using ::android::hardware::hidl_string;
50using ::android::hardware::hidl_vec;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080053using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080054using ::android::sp;
55
56namespace android {
57
Jeff Tinker6d998b62017-12-18 14:37:43 -080058#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
59
Jeff Tinkera53d6552017-01-20 00:31:46 -080060static inline int getCallingPid() {
61 return IPCThreadState::self()->getCallingPid();
62}
63
64static bool checkPermission(const char* permissionString) {
65 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
66 bool ok = checkCallingPermission(String16(permissionString));
67 if (!ok) ALOGE("Request requires %s", permissionString);
68 return ok;
69}
70
71static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
72 Vector<uint8_t> vector;
73 vector.appendArray(vec.data(), vec.size());
74 return *const_cast<const Vector<uint8_t> *>(&vector);
75}
76
77static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
78 hidl_vec<uint8_t> vec;
79 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
80 return vec;
81}
82
83static String8 toString8(const hidl_string &string) {
84 return String8(string.c_str());
85}
86
87static hidl_string toHidlString(const String8& string) {
88 return hidl_string(string.string());
89}
90
Jeff Tinker6d998b62017-12-18 14:37:43 -080091static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
92 switch(level) {
93 case SecurityLevel::SW_SECURE_CRYPTO:
94 return DrmPlugin::kSecurityLevelSwSecureCrypto;
95 case SecurityLevel::SW_SECURE_DECODE:
96 return DrmPlugin::kSecurityLevelSwSecureDecode;
97 case SecurityLevel::HW_SECURE_CRYPTO:
98 return DrmPlugin::kSecurityLevelHwSecureCrypto;
99 case SecurityLevel::HW_SECURE_DECODE:
100 return DrmPlugin::kSecurityLevelHwSecureDecode;
101 case SecurityLevel::HW_SECURE_ALL:
102 return DrmPlugin::kSecurityLevelHwSecureAll;
103 default:
104 return DrmPlugin::kSecurityLevelUnknown;
105 }
106}
107
108static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
109 switch(level) {
110 case HdcpLevel::HDCP_NONE:
111 return DrmPlugin::kHdcpNone;
112 case HdcpLevel::HDCP_V1:
113 return DrmPlugin::kHdcpV1;
114 case HdcpLevel::HDCP_V2:
115 return DrmPlugin::kHdcpV2;
116 case HdcpLevel::HDCP_V2_1:
117 return DrmPlugin::kHdcpV2_1;
118 case HdcpLevel::HDCP_V2_2:
119 return DrmPlugin::kHdcpV2_2;
120 case HdcpLevel::HDCP_NO_OUTPUT:
121 return DrmPlugin::kHdcpNoOutput;
122 default:
123 return DrmPlugin::kHdcpLevelUnknown;
124 }
125}
126
Jeff Tinkera53d6552017-01-20 00:31:46 -0800127
128static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
129 keyedVector) {
130 std::vector<KeyValue> stdKeyedVector;
131 for (size_t i = 0; i < keyedVector.size(); i++) {
132 KeyValue keyValue;
133 keyValue.key = toHidlString(keyedVector.keyAt(i));
134 keyValue.value = toHidlString(keyedVector.valueAt(i));
135 stdKeyedVector.push_back(keyValue);
136 }
137 return ::KeyedVector(stdKeyedVector);
138}
139
140static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
141 hKeyedVector) {
142 KeyedVector<String8, String8> keyedVector;
143 for (size_t i = 0; i < hKeyedVector.size(); i++) {
144 keyedVector.add(toString8(hKeyedVector[i].key),
145 toString8(hKeyedVector[i].value));
146 }
147 return keyedVector;
148}
149
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800150static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800151 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800152 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800153 for (size_t i = 0; i < hSecureStops.size(); i++) {
154 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
155 }
156 return secureStops;
157}
158
159static status_t toStatusT(Status status) {
160 switch (status) {
161 case Status::OK:
162 return OK;
163 break;
164 case Status::ERROR_DRM_NO_LICENSE:
165 return ERROR_DRM_NO_LICENSE;
166 break;
167 case Status::ERROR_DRM_LICENSE_EXPIRED:
168 return ERROR_DRM_LICENSE_EXPIRED;
169 break;
170 case Status::ERROR_DRM_SESSION_NOT_OPENED:
171 return ERROR_DRM_SESSION_NOT_OPENED;
172 break;
173 case Status::ERROR_DRM_CANNOT_HANDLE:
174 return ERROR_DRM_CANNOT_HANDLE;
175 break;
176 case Status::ERROR_DRM_INVALID_STATE:
177 return ERROR_DRM_TAMPER_DETECTED;
178 break;
179 case Status::BAD_VALUE:
180 return BAD_VALUE;
181 break;
182 case Status::ERROR_DRM_NOT_PROVISIONED:
183 return ERROR_DRM_NOT_PROVISIONED;
184 break;
185 case Status::ERROR_DRM_RESOURCE_BUSY:
186 return ERROR_DRM_RESOURCE_BUSY;
187 break;
188 case Status::ERROR_DRM_DEVICE_REVOKED:
189 return ERROR_DRM_DEVICE_REVOKED;
190 break;
191 case Status::ERROR_DRM_UNKNOWN:
192 default:
193 return ERROR_DRM_UNKNOWN;
194 break;
195 }
196}
197
198
199Mutex DrmHal::mLock;
200
201struct DrmSessionClient : public DrmSessionClientInterface {
202 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
203
204 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
205 sp<DrmHal> drm = mDrm.promote();
206 if (drm == NULL) {
207 return true;
208 }
209 status_t err = drm->closeSession(sessionId);
210 if (err != OK) {
211 return false;
212 }
213 drm->sendEvent(EventType::SESSION_RECLAIMED,
214 toHidlVec(sessionId), hidl_vec<uint8_t>());
215 return true;
216 }
217
218protected:
219 virtual ~DrmSessionClient() {}
220
221private:
222 wp<DrmHal> mDrm;
223
224 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
225};
226
227DrmHal::DrmHal()
228 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800229 mFactories(makeDrmFactories()),
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800230 mOpenSessionCounter("/drm/mediadrm/open_session", "status"),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800231 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800232}
233
Jeff Tinker61332812017-05-15 16:53:10 -0700234void DrmHal::closeOpenSessions() {
235 if (mPlugin != NULL) {
236 for (size_t i = 0; i < mOpenSessions.size(); i++) {
237 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
238 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
239 }
240 }
241 mOpenSessions.clear();
242}
243
Jeff Tinkera53d6552017-01-20 00:31:46 -0800244DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700245 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800246 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
247}
248
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800249Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
250 Vector<sp<IDrmFactory>> factories;
251
Jeff Tinker593111f2017-05-25 16:00:21 -0700252 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800253
254 if (manager != NULL) {
255 manager->listByInterface(IDrmFactory::descriptor,
256 [&factories](const hidl_vec<hidl_string> &registered) {
257 for (const auto &instance : registered) {
258 auto factory = IDrmFactory::getService(instance);
259 if (factory != NULL) {
260 factories.push_back(factory);
261 ALOGI("makeDrmFactories: factory instance %s is %s",
262 instance.c_str(),
263 factory->isRemote() ? "Remote" : "Not Remote");
264 }
265 }
266 }
267 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800268 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800269
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800270 if (factories.size() == 0) {
271 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700272 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800273 if (passthrough != NULL) {
274 ALOGI("makeDrmFactories: using default drm instance");
275 factories.push_back(passthrough);
276 } else {
277 ALOGE("Failed to find any drm factories");
278 }
279 }
280 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800281}
282
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800283sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
284 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800285
286 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800287 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800288 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800289 if (status != Status::OK) {
290 ALOGE("Failed to make drm plugin");
291 return;
292 }
293 plugin = hPlugin;
294 }
295 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700296
297 if (!hResult.isOk()) {
298 ALOGE("createPlugin remote call failed");
299 }
300
Jeff Tinkera53d6552017-01-20 00:31:46 -0800301 return plugin;
302}
303
304status_t DrmHal::initCheck() const {
305 return mInitCheck;
306}
307
308status_t DrmHal::setListener(const sp<IDrmClient>& listener)
309{
310 Mutex::Autolock lock(mEventLock);
311 if (mListener != NULL){
312 IInterface::asBinder(mListener)->unlinkToDeath(this);
313 }
314 if (listener != NULL) {
315 IInterface::asBinder(listener)->linkToDeath(this);
316 }
317 mListener = listener;
318 return NO_ERROR;
319}
320
321Return<void> DrmHal::sendEvent(EventType hEventType,
322 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
323
324 mEventLock.lock();
325 sp<IDrmClient> listener = mListener;
326 mEventLock.unlock();
327
328 if (listener != NULL) {
329 Parcel obj;
330 writeByteArray(obj, sessionId);
331 writeByteArray(obj, data);
332
333 Mutex::Autolock lock(mNotifyLock);
334 DrmPlugin::EventType eventType;
335 switch(hEventType) {
336 case EventType::PROVISION_REQUIRED:
337 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
338 break;
339 case EventType::KEY_NEEDED:
340 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
341 break;
342 case EventType::KEY_EXPIRED:
343 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
344 break;
345 case EventType::VENDOR_DEFINED:
346 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
347 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700348 case EventType::SESSION_RECLAIMED:
349 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
350 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800351 default:
352 return Void();
353 }
354 listener->notify(eventType, 0, &obj);
355 }
356 return Void();
357}
358
359Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
360 int64_t expiryTimeInMS) {
361
362 mEventLock.lock();
363 sp<IDrmClient> listener = mListener;
364 mEventLock.unlock();
365
366 if (listener != NULL) {
367 Parcel obj;
368 writeByteArray(obj, sessionId);
369 obj.writeInt64(expiryTimeInMS);
370
371 Mutex::Autolock lock(mNotifyLock);
372 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
373 }
374 return Void();
375}
376
377Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
378 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
379
380 mEventLock.lock();
381 sp<IDrmClient> listener = mListener;
382 mEventLock.unlock();
383
384 if (listener != NULL) {
385 Parcel obj;
386 writeByteArray(obj, sessionId);
387
388 size_t nKeys = keyStatusList.size();
389 obj.writeInt32(nKeys);
390 for (size_t i = 0; i < nKeys; ++i) {
391 const KeyStatus &keyStatus = keyStatusList[i];
392 writeByteArray(obj, keyStatus.keyId);
393 uint32_t type;
394 switch(keyStatus.type) {
395 case KeyStatusType::USABLE:
396 type = DrmPlugin::kKeyStatusType_Usable;
397 break;
398 case KeyStatusType::EXPIRED:
399 type = DrmPlugin::kKeyStatusType_Expired;
400 break;
401 case KeyStatusType::OUTPUTNOTALLOWED:
402 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
403 break;
404 case KeyStatusType::STATUSPENDING:
405 type = DrmPlugin::kKeyStatusType_StatusPending;
406 break;
407 case KeyStatusType::INTERNALERROR:
408 default:
409 type = DrmPlugin::kKeyStatusType_InternalError;
410 break;
411 }
412 obj.writeInt32(type);
413 }
414 obj.writeInt32(hasNewUsableKey);
415
416 Mutex::Autolock lock(mNotifyLock);
417 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
418 }
419 return Void();
420}
421
422bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
423 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800425 for (size_t i = 0; i < mFactories.size(); i++) {
426 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
427 if (mimeType != "") {
428 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
429 return true;
430 }
431 } else {
432 return true;
433 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800434 }
435 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800436 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437}
438
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800439status_t DrmHal::createPlugin(const uint8_t uuid[16],
440 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800441 Mutex::Autolock autoLock(mLock);
442
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800443 for (size_t i = 0; i < mFactories.size(); i++) {
444 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
445 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800446 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800447 }
448 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800449
450 if (mPlugin == NULL) {
451 mInitCheck = ERROR_UNSUPPORTED;
452 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700453 if (!mPlugin->setListener(this).isOk()) {
454 mInitCheck = DEAD_OBJECT;
455 } else {
456 mInitCheck = OK;
457 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800458 }
459
460 return mInitCheck;
461}
462
463status_t DrmHal::destroyPlugin() {
464 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800465 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800466
Jeff Tinker61332812017-05-15 16:53:10 -0700467 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700468 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800469 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700470 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800471
Jeff Tinker319d5f42017-07-26 15:44:33 -0700472 if (mPlugin != NULL) {
473 if (!mPlugin->setListener(NULL).isOk()) {
474 mInitCheck = DEAD_OBJECT;
475 }
476 }
477 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800478 return OK;
479}
480
481status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
482 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800483 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800484
485 status_t err = UNKNOWN_ERROR;
486
487 bool retry = true;
488 do {
489 hidl_vec<uint8_t> hSessionId;
490
491 Return<void> hResult = mPlugin->openSession(
492 [&](Status status, const hidl_vec<uint8_t>& id) {
493 if (status == Status::OK) {
494 sessionId = toVector(id);
495 }
496 err = toStatusT(status);
497 }
498 );
499
500 if (!hResult.isOk()) {
501 err = DEAD_OBJECT;
502 }
503
504 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
505 mLock.unlock();
506 // reclaimSession may call back to closeSession, since mLock is
507 // shared between Drm instances, we should unlock here to avoid
508 // deadlock.
509 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
510 mLock.lock();
511 } else {
512 retry = false;
513 }
514 } while (retry);
515
516 if (err == OK) {
517 DrmSessionManager::Instance()->addSession(getCallingPid(),
518 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700519 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800520 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800521
522 mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800523 return err;
524}
525
526status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
527 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800528 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800529
Jeff Tinker319d5f42017-07-26 15:44:33 -0700530 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
531 if (status.isOk()) {
532 if (status == Status::OK) {
533 DrmSessionManager::Instance()->removeSession(sessionId);
534 for (size_t i = 0; i < mOpenSessions.size(); i++) {
535 if (mOpenSessions[i] == sessionId) {
536 mOpenSessions.removeAt(i);
537 break;
538 }
Jeff Tinker61332812017-05-15 16:53:10 -0700539 }
540 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700541 reportMetrics();
542 return toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800543 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700544 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800545}
546
547status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
548 Vector<uint8_t> const &initData, String8 const &mimeType,
549 DrmPlugin::KeyType keyType, KeyedVector<String8,
550 String8> const &optionalParameters, Vector<uint8_t> &request,
551 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
552 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800553 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800554
555 DrmSessionManager::Instance()->useSession(sessionId);
556
557 KeyType hKeyType;
558 if (keyType == DrmPlugin::kKeyType_Streaming) {
559 hKeyType = KeyType::STREAMING;
560 } else if (keyType == DrmPlugin::kKeyType_Offline) {
561 hKeyType = KeyType::OFFLINE;
562 } else if (keyType == DrmPlugin::kKeyType_Release) {
563 hKeyType = KeyType::RELEASE;
564 } else {
565 return BAD_VALUE;
566 }
567
568 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
569
570 status_t err = UNKNOWN_ERROR;
571
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800572 if (mPluginV1_1 != NULL) {
573 Return<void> hResult =
574 mPluginV1_1->getKeyRequest_1_1(
575 toHidlVec(sessionId), toHidlVec(initData),
576 toHidlString(mimeType), hKeyType, hOptionalParameters,
577 [&](Status status, const hidl_vec<uint8_t>& hRequest,
578 drm::V1_1::KeyRequestType hKeyRequestType,
579 const hidl_string& hDefaultUrl) {
580
581 if (status == Status::OK) {
582 request = toVector(hRequest);
583 defaultUrl = toString8(hDefaultUrl);
584
585 switch (hKeyRequestType) {
586 case drm::V1_1::KeyRequestType::INITIAL:
587 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
588 break;
589 case drm::V1_1::KeyRequestType::RENEWAL:
590 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
591 break;
592 case drm::V1_1::KeyRequestType::RELEASE:
593 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
594 break;
595 case drm::V1_1::KeyRequestType::NONE:
596 *keyRequestType = DrmPlugin::kKeyRequestType_None;
597 break;
598 case drm::V1_1::KeyRequestType::UPDATE:
599 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
600 break;
601 default:
602 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
603 break;
604 }
605 err = toStatusT(status);
606 }
607 });
608 return hResult.isOk() ? err : DEAD_OBJECT;
609 }
610
Jeff Tinkera53d6552017-01-20 00:31:46 -0800611 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
612 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
613 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800614 drm::V1_0::KeyRequestType hKeyRequestType,
615 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800616
617 if (status == Status::OK) {
618 request = toVector(hRequest);
619 defaultUrl = toString8(hDefaultUrl);
620
621 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800622 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800623 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
624 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800625 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800626 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
627 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800628 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800629 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
630 break;
631 default:
632 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
633 break;
634 }
635 err = toStatusT(status);
636 }
637 });
638
639 return hResult.isOk() ? err : DEAD_OBJECT;
640}
641
642status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
643 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
644 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800645 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800646
647 DrmSessionManager::Instance()->useSession(sessionId);
648
649 status_t err = UNKNOWN_ERROR;
650
651 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
652 toHidlVec(response),
653 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
654 if (status == Status::OK) {
655 keySetId = toVector(hKeySetId);
656 }
657 err = toStatusT(status);
658 }
659 );
660
661 return hResult.isOk() ? err : DEAD_OBJECT;
662}
663
664status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
665 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800666 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800667
668 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
669}
670
671status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
672 Vector<uint8_t> const &keySetId) {
673 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800674 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800675
676 DrmSessionManager::Instance()->useSession(sessionId);
677
678 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
679 toHidlVec(keySetId)));
680}
681
682status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
683 KeyedVector<String8, String8> &infoMap) const {
684 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800685 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800686
687 DrmSessionManager::Instance()->useSession(sessionId);
688
689 ::KeyedVector hInfoMap;
690
691 status_t err = UNKNOWN_ERROR;
692
693 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
694 [&](Status status, const hidl_vec<KeyValue>& map) {
695 if (status == Status::OK) {
696 infoMap = toKeyedVector(map);
697 }
698 err = toStatusT(status);
699 }
700 );
701
702 return hResult.isOk() ? err : DEAD_OBJECT;
703}
704
705status_t DrmHal::getProvisionRequest(String8 const &certType,
706 String8 const &certAuthority, Vector<uint8_t> &request,
707 String8 &defaultUrl) {
708 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800709 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800710
711 status_t err = UNKNOWN_ERROR;
712
713 Return<void> hResult = mPlugin->getProvisionRequest(
714 toHidlString(certType), toHidlString(certAuthority),
715 [&](Status status, const hidl_vec<uint8_t>& hRequest,
716 const hidl_string& hDefaultUrl) {
717 if (status == Status::OK) {
718 request = toVector(hRequest);
719 defaultUrl = toString8(hDefaultUrl);
720 }
721 err = toStatusT(status);
722 }
723 );
724
725 return hResult.isOk() ? err : DEAD_OBJECT;
726}
727
728status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800729 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800730 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->provideProvisionResponse(toHidlVec(response),
736 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
737 const hidl_vec<uint8_t>& hWrappedKey) {
738 if (status == Status::OK) {
739 certificate = toVector(hCertificate);
740 wrappedKey = toVector(hWrappedKey);
741 }
742 err = toStatusT(status);
743 }
744 );
745
746 return hResult.isOk() ? err : DEAD_OBJECT;
747}
748
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800749status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800750 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800751 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800752
753 status_t err = UNKNOWN_ERROR;
754
755 Return<void> hResult = mPlugin->getSecureStops(
756 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
757 if (status == Status::OK) {
758 secureStops = toSecureStops(hSecureStops);
759 }
760 err = toStatusT(status);
761 }
762 );
763
764 return hResult.isOk() ? err : DEAD_OBJECT;
765}
766
767
768status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
769 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800770 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800771
772 status_t err = UNKNOWN_ERROR;
773
774 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
775 [&](Status status, const SecureStop& hSecureStop) {
776 if (status == Status::OK) {
777 secureStop = toVector(hSecureStop.opaqueData);
778 }
779 err = toStatusT(status);
780 }
781 );
782
783 return hResult.isOk() ? err : DEAD_OBJECT;
784}
785
786status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
787 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800788 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800789
790 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
791}
792
793status_t DrmHal::releaseAllSecureStops() {
794 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800795 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800796
797 return toStatusT(mPlugin->releaseAllSecureStops());
798}
799
Jeff Tinker6d998b62017-12-18 14:37:43 -0800800status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
801 DrmPlugin::HdcpLevel *max) const {
802 Mutex::Autolock autoLock(mLock);
803 INIT_CHECK();
804
805 if (connected == NULL || max == NULL) {
806 return BAD_VALUE;
807 }
808 status_t err = UNKNOWN_ERROR;
809
810 if (mPluginV1_1 == NULL) {
811 return ERROR_DRM_CANNOT_HANDLE;
812 }
813
814 *connected = DrmPlugin::kHdcpLevelUnknown;
815 *max = DrmPlugin::kHdcpLevelUnknown;
816
817 Return<void> hResult = mPluginV1_1->getHdcpLevels(
818 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
819 if (status == Status::OK) {
820 *connected = toHdcpLevel(hConnected);
821 *max = toHdcpLevel(hMax);
822 }
823 err = toStatusT(status);
824 }
825 );
826
827 return hResult.isOk() ? err : DEAD_OBJECT;
828}
829
830status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
831 Mutex::Autolock autoLock(mLock);
832 INIT_CHECK();
833
834 if (open == NULL || max == NULL) {
835 return BAD_VALUE;
836 }
837 status_t err = UNKNOWN_ERROR;
838
839 *open = 0;
840 *max = 0;
841
842 if (mPluginV1_1 == NULL) {
843 return ERROR_DRM_CANNOT_HANDLE;
844 }
845
846 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
847 [&](Status status, uint32_t hOpen, uint32_t hMax) {
848 if (status == Status::OK) {
849 *open = hOpen;
850 *max = hMax;
851 }
852 err = toStatusT(status);
853 }
854 );
855
856 return hResult.isOk() ? err : DEAD_OBJECT;
857}
858
859status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
860 DrmPlugin::SecurityLevel *level) const {
861 Mutex::Autolock autoLock(mLock);
862 INIT_CHECK();
863
864 if (level == NULL) {
865 return BAD_VALUE;
866 }
867 status_t err = UNKNOWN_ERROR;
868
869 if (mPluginV1_1 == NULL) {
870 return ERROR_DRM_CANNOT_HANDLE;
871 }
872
873 *level = DrmPlugin::kSecurityLevelUnknown;
874
875 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
876 [&](Status status, SecurityLevel hLevel) {
877 if (status == Status::OK) {
878 *level = toSecurityLevel(hLevel);
879 }
880 err = toStatusT(status);
881 }
882 );
883
884 return hResult.isOk() ? err : DEAD_OBJECT;
885}
886
887status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
888 const DrmPlugin::SecurityLevel& level) {
889 Mutex::Autolock autoLock(mLock);
890 INIT_CHECK();
891
892 if (mPluginV1_1 == NULL) {
893 return ERROR_DRM_CANNOT_HANDLE;
894 }
895
896 SecurityLevel hSecurityLevel;
897
898 switch(level) {
899 case DrmPlugin::kSecurityLevelSwSecureCrypto:
900 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
901 break;
902 case DrmPlugin::kSecurityLevelSwSecureDecode:
903 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
904 break;
905 case DrmPlugin::kSecurityLevelHwSecureCrypto:
906 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
907 break;
908 case DrmPlugin::kSecurityLevelHwSecureDecode:
909 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
910 break;
911 case DrmPlugin::kSecurityLevelHwSecureAll:
912 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
913 break;
914 default:
915 return ERROR_DRM_CANNOT_HANDLE;
916 }
917
918 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
919 hSecurityLevel);
920 return toStatusT(status);
921}
922
Jeff Tinkera53d6552017-01-20 00:31:46 -0800923status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
924 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700925 return getPropertyStringInternal(name, value);
926}
927
928status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
929 // This function is internal to the class and should only be called while
930 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800931 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932
933 status_t err = UNKNOWN_ERROR;
934
935 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
936 [&](Status status, const hidl_string& hValue) {
937 if (status == Status::OK) {
938 value = toString8(hValue);
939 }
940 err = toStatusT(status);
941 }
942 );
943
944 return hResult.isOk() ? err : DEAD_OBJECT;
945}
946
947status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
948 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700949 return getPropertyByteArrayInternal(name, value);
950}
951
952status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
953 // This function is internal to the class and should only be called while
954 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800955 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800956
957 status_t err = UNKNOWN_ERROR;
958
959 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
960 [&](Status status, const hidl_vec<uint8_t>& hValue) {
961 if (status == Status::OK) {
962 value = toVector(hValue);
963 }
964 err = toStatusT(status);
965 }
966 );
967
968 return hResult.isOk() ? err : DEAD_OBJECT;
969}
970
971status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
972 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800973 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800974
Jeff Tinker6d998b62017-12-18 14:37:43 -0800975 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800976 toHidlString(value));
977 return toStatusT(status);
978}
979
980status_t DrmHal::setPropertyByteArray(String8 const &name,
981 Vector<uint8_t> const &value ) const {
982 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800983 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800984
985 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
986 toHidlVec(value));
987 return toStatusT(status);
988}
989
Adam Stoneab394d12017-12-22 12:34:20 -0800990status_t DrmHal::getMetrics(MediaAnalyticsItem* metrics) {
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800991 // TODO: Move mOpenSessionCounter and suffixes to a separate class
992 // that manages the collection of metrics and exporting them.
993 std::string success_count_name =
994 mOpenSessionCounter.metric_name() + "/ok/count";
995 std::string error_count_name =
996 mOpenSessionCounter.metric_name() + "/error/count";
997 mOpenSessionCounter.ExportValues(
998 [&] (status_t status, int64_t value) {
999 if (status == OK) {
1000 metrics->setInt64(success_count_name.c_str(), value);
1001 } else {
1002 int64_t total_errors(0);
1003 metrics->getInt64(error_count_name.c_str(), &total_errors);
1004 metrics->setInt64(error_count_name.c_str(),
1005 total_errors + value);
1006 // TODO: Add support for exporting the list of error values.
1007 // This probably needs to be added to MediaAnalyticsItem.
1008 }
1009 });
Adam Stoneab394d12017-12-22 12:34:20 -08001010 return OK;
1011}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001012
1013status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1014 String8 const &algorithm) {
1015 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001016 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001017
1018 DrmSessionManager::Instance()->useSession(sessionId);
1019
1020 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1021 toHidlString(algorithm));
1022 return toStatusT(status);
1023}
1024
1025status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1026 String8 const &algorithm) {
1027 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001028 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001029
1030 DrmSessionManager::Instance()->useSession(sessionId);
1031
1032 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1033 toHidlString(algorithm));
1034 return toStatusT(status);
1035}
1036
1037status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001038 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1039 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001040 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001041 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001042
1043 DrmSessionManager::Instance()->useSession(sessionId);
1044
1045 status_t err = UNKNOWN_ERROR;
1046
1047 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1048 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1049 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1050 if (status == Status::OK) {
1051 output = toVector(hOutput);
1052 }
1053 err = toStatusT(status);
1054 }
1055 );
1056
1057 return hResult.isOk() ? err : DEAD_OBJECT;
1058}
1059
1060status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001061 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1062 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001063 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001064 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001065
1066 DrmSessionManager::Instance()->useSession(sessionId);
1067
1068 status_t err = UNKNOWN_ERROR;
1069
1070 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1071 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1072 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1073 if (status == Status::OK) {
1074 output = toVector(hOutput);
1075 }
1076 err = toStatusT(status);
1077 }
1078 );
1079
1080 return hResult.isOk() ? err : DEAD_OBJECT;
1081}
1082
1083status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001084 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1085 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001086 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001087 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001088
1089 DrmSessionManager::Instance()->useSession(sessionId);
1090
1091 status_t err = UNKNOWN_ERROR;
1092
1093 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1094 toHidlVec(keyId), toHidlVec(message),
1095 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1096 if (status == Status::OK) {
1097 signature = toVector(hSignature);
1098 }
1099 err = toStatusT(status);
1100 }
1101 );
1102
1103 return hResult.isOk() ? err : DEAD_OBJECT;
1104}
1105
1106status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001107 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1108 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001109 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001110 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001111
1112 DrmSessionManager::Instance()->useSession(sessionId);
1113
1114 status_t err = UNKNOWN_ERROR;
1115
1116 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1117 toHidlVec(message), toHidlVec(signature),
1118 [&](Status status, bool hMatch) {
1119 if (status == Status::OK) {
1120 match = hMatch;
1121 } else {
1122 match = false;
1123 }
1124 err = toStatusT(status);
1125 }
1126 );
1127
1128 return hResult.isOk() ? err : DEAD_OBJECT;
1129}
1130
1131status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001132 String8 const &algorithm, Vector<uint8_t> const &message,
1133 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001134 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001135 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001136
1137 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1138 return -EPERM;
1139 }
1140
1141 DrmSessionManager::Instance()->useSession(sessionId);
1142
1143 status_t err = UNKNOWN_ERROR;
1144
1145 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1146 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1147 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1148 if (status == Status::OK) {
1149 signature = toVector(hSignature);
1150 }
1151 err = toStatusT(status);
1152 }
1153 );
1154
1155 return hResult.isOk() ? err : DEAD_OBJECT;
1156}
1157
1158void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1159{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001160 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001161 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001162 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001163 mInitCheck = NO_INIT;
1164
Jeff Tinker70367f52017-06-16 12:41:33 -07001165 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001166 if (!mPlugin->setListener(NULL).isOk()) {
1167 mInitCheck = DEAD_OBJECT;
1168 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001169 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001170 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001171}
1172
1173void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1174{
1175 if (vec.size()) {
1176 obj.writeInt32(vec.size());
1177 obj.write(vec.data(), vec.size());
1178 } else {
1179 obj.writeInt32(0);
1180 }
1181}
1182
Adam Stoneab394d12017-12-22 12:34:20 -08001183
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001184void DrmHal::reportMetrics() const
1185{
1186 Vector<uint8_t> metrics;
1187 String8 vendor;
1188 String8 description;
1189 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1190 getPropertyStringInternal(String8("description"), description) == OK &&
1191 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1192 status_t res = android::reportDrmPluginMetrics(
1193 metrics, vendor, description);
1194 if (res != OK) {
1195 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1196 }
1197 }
1198}
1199
Jeff Tinkera53d6552017-01-20 00:31:46 -08001200} // namespace android