blob: e1718eb4c8b836ec73be01ffc53b3c00ad711f54 [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>
33#include <media/drm/DrmAPI.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AString.h>
36#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/MediaErrors.h>
38
39using ::android::hardware::drm::V1_0::EventType;
40using ::android::hardware::drm::V1_0::IDrmFactory;
41using ::android::hardware::drm::V1_0::IDrmPlugin;
42using ::android::hardware::drm::V1_0::KeyedVector;
43using ::android::hardware::drm::V1_0::KeyRequestType;
44using ::android::hardware::drm::V1_0::KeyStatus;
45using ::android::hardware::drm::V1_0::KeyStatusType;
46using ::android::hardware::drm::V1_0::KeyType;
47using ::android::hardware::drm::V1_0::KeyValue;
48using ::android::hardware::drm::V1_0::SecureStop;
49using ::android::hardware::drm::V1_0::Status;
50using ::android::hardware::hidl_array;
51using ::android::hardware::hidl_string;
52using ::android::hardware::hidl_vec;
53using ::android::hardware::Return;
54using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080055using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080056using ::android::sp;
57
58namespace android {
59
60static 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
91
92static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
93 keyedVector) {
94 std::vector<KeyValue> stdKeyedVector;
95 for (size_t i = 0; i < keyedVector.size(); i++) {
96 KeyValue keyValue;
97 keyValue.key = toHidlString(keyedVector.keyAt(i));
98 keyValue.value = toHidlString(keyedVector.valueAt(i));
99 stdKeyedVector.push_back(keyValue);
100 }
101 return ::KeyedVector(stdKeyedVector);
102}
103
104static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
105 hKeyedVector) {
106 KeyedVector<String8, String8> keyedVector;
107 for (size_t i = 0; i < hKeyedVector.size(); i++) {
108 keyedVector.add(toString8(hKeyedVector[i].key),
109 toString8(hKeyedVector[i].value));
110 }
111 return keyedVector;
112}
113
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800114static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800115 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800116 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800117 for (size_t i = 0; i < hSecureStops.size(); i++) {
118 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
119 }
120 return secureStops;
121}
122
123static status_t toStatusT(Status status) {
124 switch (status) {
125 case Status::OK:
126 return OK;
127 break;
128 case Status::ERROR_DRM_NO_LICENSE:
129 return ERROR_DRM_NO_LICENSE;
130 break;
131 case Status::ERROR_DRM_LICENSE_EXPIRED:
132 return ERROR_DRM_LICENSE_EXPIRED;
133 break;
134 case Status::ERROR_DRM_SESSION_NOT_OPENED:
135 return ERROR_DRM_SESSION_NOT_OPENED;
136 break;
137 case Status::ERROR_DRM_CANNOT_HANDLE:
138 return ERROR_DRM_CANNOT_HANDLE;
139 break;
140 case Status::ERROR_DRM_INVALID_STATE:
141 return ERROR_DRM_TAMPER_DETECTED;
142 break;
143 case Status::BAD_VALUE:
144 return BAD_VALUE;
145 break;
146 case Status::ERROR_DRM_NOT_PROVISIONED:
147 return ERROR_DRM_NOT_PROVISIONED;
148 break;
149 case Status::ERROR_DRM_RESOURCE_BUSY:
150 return ERROR_DRM_RESOURCE_BUSY;
151 break;
152 case Status::ERROR_DRM_DEVICE_REVOKED:
153 return ERROR_DRM_DEVICE_REVOKED;
154 break;
155 case Status::ERROR_DRM_UNKNOWN:
156 default:
157 return ERROR_DRM_UNKNOWN;
158 break;
159 }
160}
161
162
163Mutex DrmHal::mLock;
164
165struct DrmSessionClient : public DrmSessionClientInterface {
166 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
167
168 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
169 sp<DrmHal> drm = mDrm.promote();
170 if (drm == NULL) {
171 return true;
172 }
173 status_t err = drm->closeSession(sessionId);
174 if (err != OK) {
175 return false;
176 }
177 drm->sendEvent(EventType::SESSION_RECLAIMED,
178 toHidlVec(sessionId), hidl_vec<uint8_t>());
179 return true;
180 }
181
182protected:
183 virtual ~DrmSessionClient() {}
184
185private:
186 wp<DrmHal> mDrm;
187
188 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
189};
190
191DrmHal::DrmHal()
192 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800193 mFactories(makeDrmFactories()),
194 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800195}
196
197DrmHal::~DrmHal() {
198 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
199}
200
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800201Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
202 Vector<sp<IDrmFactory>> factories;
203
Jeff Tinker593111f2017-05-25 16:00:21 -0700204 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800205
206 if (manager != NULL) {
207 manager->listByInterface(IDrmFactory::descriptor,
208 [&factories](const hidl_vec<hidl_string> &registered) {
209 for (const auto &instance : registered) {
210 auto factory = IDrmFactory::getService(instance);
211 if (factory != NULL) {
212 factories.push_back(factory);
213 ALOGI("makeDrmFactories: factory instance %s is %s",
214 instance.c_str(),
215 factory->isRemote() ? "Remote" : "Not Remote");
216 }
217 }
218 }
219 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800220 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800221
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800222 if (factories.size() == 0) {
223 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700224 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800225 if (passthrough != NULL) {
226 ALOGI("makeDrmFactories: using default drm instance");
227 factories.push_back(passthrough);
228 } else {
229 ALOGE("Failed to find any drm factories");
230 }
231 }
232 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800233}
234
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800235sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
236 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800237
238 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800239 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800240 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800241 if (status != Status::OK) {
242 ALOGE("Failed to make drm plugin");
243 return;
244 }
245 plugin = hPlugin;
246 }
247 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800248 return plugin;
249}
250
251status_t DrmHal::initCheck() const {
252 return mInitCheck;
253}
254
255status_t DrmHal::setListener(const sp<IDrmClient>& listener)
256{
257 Mutex::Autolock lock(mEventLock);
258 if (mListener != NULL){
259 IInterface::asBinder(mListener)->unlinkToDeath(this);
260 }
261 if (listener != NULL) {
262 IInterface::asBinder(listener)->linkToDeath(this);
263 }
264 mListener = listener;
265 return NO_ERROR;
266}
267
268Return<void> DrmHal::sendEvent(EventType hEventType,
269 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
270
271 mEventLock.lock();
272 sp<IDrmClient> listener = mListener;
273 mEventLock.unlock();
274
275 if (listener != NULL) {
276 Parcel obj;
277 writeByteArray(obj, sessionId);
278 writeByteArray(obj, data);
279
280 Mutex::Autolock lock(mNotifyLock);
281 DrmPlugin::EventType eventType;
282 switch(hEventType) {
283 case EventType::PROVISION_REQUIRED:
284 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
285 break;
286 case EventType::KEY_NEEDED:
287 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
288 break;
289 case EventType::KEY_EXPIRED:
290 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
291 break;
292 case EventType::VENDOR_DEFINED:
293 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
294 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700295 case EventType::SESSION_RECLAIMED:
296 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
297 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800298 default:
299 return Void();
300 }
301 listener->notify(eventType, 0, &obj);
302 }
303 return Void();
304}
305
306Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
307 int64_t expiryTimeInMS) {
308
309 mEventLock.lock();
310 sp<IDrmClient> listener = mListener;
311 mEventLock.unlock();
312
313 if (listener != NULL) {
314 Parcel obj;
315 writeByteArray(obj, sessionId);
316 obj.writeInt64(expiryTimeInMS);
317
318 Mutex::Autolock lock(mNotifyLock);
319 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
320 }
321 return Void();
322}
323
324Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
325 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
326
327 mEventLock.lock();
328 sp<IDrmClient> listener = mListener;
329 mEventLock.unlock();
330
331 if (listener != NULL) {
332 Parcel obj;
333 writeByteArray(obj, sessionId);
334
335 size_t nKeys = keyStatusList.size();
336 obj.writeInt32(nKeys);
337 for (size_t i = 0; i < nKeys; ++i) {
338 const KeyStatus &keyStatus = keyStatusList[i];
339 writeByteArray(obj, keyStatus.keyId);
340 uint32_t type;
341 switch(keyStatus.type) {
342 case KeyStatusType::USABLE:
343 type = DrmPlugin::kKeyStatusType_Usable;
344 break;
345 case KeyStatusType::EXPIRED:
346 type = DrmPlugin::kKeyStatusType_Expired;
347 break;
348 case KeyStatusType::OUTPUTNOTALLOWED:
349 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
350 break;
351 case KeyStatusType::STATUSPENDING:
352 type = DrmPlugin::kKeyStatusType_StatusPending;
353 break;
354 case KeyStatusType::INTERNALERROR:
355 default:
356 type = DrmPlugin::kKeyStatusType_InternalError;
357 break;
358 }
359 obj.writeInt32(type);
360 }
361 obj.writeInt32(hasNewUsableKey);
362
363 Mutex::Autolock lock(mNotifyLock);
364 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
365 }
366 return Void();
367}
368
369bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
370 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800371
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800372 for (size_t i = 0; i < mFactories.size(); i++) {
373 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
374 if (mimeType != "") {
375 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
376 return true;
377 }
378 } else {
379 return true;
380 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800381 }
382 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800383 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800384}
385
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800386status_t DrmHal::createPlugin(const uint8_t uuid[16],
387 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800388 Mutex::Autolock autoLock(mLock);
389
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800390 for (size_t i = 0; i < mFactories.size(); i++) {
391 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
392 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
393 }
394 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800395
396 if (mPlugin == NULL) {
397 mInitCheck = ERROR_UNSUPPORTED;
398 } else {
399 mInitCheck = OK;
400 mPlugin->setListener(this);
401 }
402
403 return mInitCheck;
404}
405
406status_t DrmHal::destroyPlugin() {
407 Mutex::Autolock autoLock(mLock);
408
409 if (mInitCheck != OK) {
410 return mInitCheck;
411 }
412
413 setListener(NULL);
Jeff Tinkerf53d9662017-05-08 19:25:57 -0700414 mPlugin->setListener(NULL);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800415 mPlugin.clear();
416
417 return OK;
418}
419
420status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
421 Mutex::Autolock autoLock(mLock);
422
423 if (mInitCheck != OK) {
424 return mInitCheck;
425 }
426
427 status_t err = UNKNOWN_ERROR;
428
429 bool retry = true;
430 do {
431 hidl_vec<uint8_t> hSessionId;
432
433 Return<void> hResult = mPlugin->openSession(
434 [&](Status status, const hidl_vec<uint8_t>& id) {
435 if (status == Status::OK) {
436 sessionId = toVector(id);
437 }
438 err = toStatusT(status);
439 }
440 );
441
442 if (!hResult.isOk()) {
443 err = DEAD_OBJECT;
444 }
445
446 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
447 mLock.unlock();
448 // reclaimSession may call back to closeSession, since mLock is
449 // shared between Drm instances, we should unlock here to avoid
450 // deadlock.
451 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
452 mLock.lock();
453 } else {
454 retry = false;
455 }
456 } while (retry);
457
458 if (err == OK) {
459 DrmSessionManager::Instance()->addSession(getCallingPid(),
460 mDrmSessionClient, sessionId);
461 }
462 return err;
463}
464
465status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
466 Mutex::Autolock autoLock(mLock);
467
468 if (mInitCheck != OK) {
469 return mInitCheck;
470 }
471
472 Status status = mPlugin->closeSession(toHidlVec(sessionId));
473 if (status == Status::OK) {
474 DrmSessionManager::Instance()->removeSession(sessionId);
475 }
476 return toStatusT(status);
477}
478
479status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
480 Vector<uint8_t> const &initData, String8 const &mimeType,
481 DrmPlugin::KeyType keyType, KeyedVector<String8,
482 String8> const &optionalParameters, Vector<uint8_t> &request,
483 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
484 Mutex::Autolock autoLock(mLock);
485
486 if (mInitCheck != OK) {
487 return mInitCheck;
488 }
489
490 DrmSessionManager::Instance()->useSession(sessionId);
491
492 KeyType hKeyType;
493 if (keyType == DrmPlugin::kKeyType_Streaming) {
494 hKeyType = KeyType::STREAMING;
495 } else if (keyType == DrmPlugin::kKeyType_Offline) {
496 hKeyType = KeyType::OFFLINE;
497 } else if (keyType == DrmPlugin::kKeyType_Release) {
498 hKeyType = KeyType::RELEASE;
499 } else {
500 return BAD_VALUE;
501 }
502
503 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
504
505 status_t err = UNKNOWN_ERROR;
506
507 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
508 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
509 [&](Status status, const hidl_vec<uint8_t>& hRequest,
510 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
511
512 if (status == Status::OK) {
513 request = toVector(hRequest);
514 defaultUrl = toString8(hDefaultUrl);
515
516 switch (hKeyRequestType) {
517 case KeyRequestType::INITIAL:
518 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
519 break;
520 case KeyRequestType::RENEWAL:
521 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
522 break;
523 case KeyRequestType::RELEASE:
524 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
525 break;
526 default:
527 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
528 break;
529 }
530 err = toStatusT(status);
531 }
532 });
533
534 return hResult.isOk() ? err : DEAD_OBJECT;
535}
536
537status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
538 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
539 Mutex::Autolock autoLock(mLock);
540
541 if (mInitCheck != OK) {
542 return mInitCheck;
543 }
544
545 DrmSessionManager::Instance()->useSession(sessionId);
546
547 status_t err = UNKNOWN_ERROR;
548
549 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
550 toHidlVec(response),
551 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
552 if (status == Status::OK) {
553 keySetId = toVector(hKeySetId);
554 }
555 err = toStatusT(status);
556 }
557 );
558
559 return hResult.isOk() ? err : DEAD_OBJECT;
560}
561
562status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
563 Mutex::Autolock autoLock(mLock);
564
565 if (mInitCheck != OK) {
566 return mInitCheck;
567 }
568
569 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
570}
571
572status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
573 Vector<uint8_t> const &keySetId) {
574 Mutex::Autolock autoLock(mLock);
575
576 if (mInitCheck != OK) {
577 return mInitCheck;
578 }
579
580 DrmSessionManager::Instance()->useSession(sessionId);
581
582 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
583 toHidlVec(keySetId)));
584}
585
586status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
587 KeyedVector<String8, String8> &infoMap) const {
588 Mutex::Autolock autoLock(mLock);
589
590 if (mInitCheck != OK) {
591 return mInitCheck;
592 }
593
594 DrmSessionManager::Instance()->useSession(sessionId);
595
596 ::KeyedVector hInfoMap;
597
598 status_t err = UNKNOWN_ERROR;
599
600 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
601 [&](Status status, const hidl_vec<KeyValue>& map) {
602 if (status == Status::OK) {
603 infoMap = toKeyedVector(map);
604 }
605 err = toStatusT(status);
606 }
607 );
608
609 return hResult.isOk() ? err : DEAD_OBJECT;
610}
611
612status_t DrmHal::getProvisionRequest(String8 const &certType,
613 String8 const &certAuthority, Vector<uint8_t> &request,
614 String8 &defaultUrl) {
615 Mutex::Autolock autoLock(mLock);
616
617 if (mInitCheck != OK) {
618 return mInitCheck;
619 }
620
621 status_t err = UNKNOWN_ERROR;
622
623 Return<void> hResult = mPlugin->getProvisionRequest(
624 toHidlString(certType), toHidlString(certAuthority),
625 [&](Status status, const hidl_vec<uint8_t>& hRequest,
626 const hidl_string& hDefaultUrl) {
627 if (status == Status::OK) {
628 request = toVector(hRequest);
629 defaultUrl = toString8(hDefaultUrl);
630 }
631 err = toStatusT(status);
632 }
633 );
634
635 return hResult.isOk() ? err : DEAD_OBJECT;
636}
637
638status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800639 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800640 Mutex::Autolock autoLock(mLock);
641
642 if (mInitCheck != OK) {
643 return mInitCheck;
644 }
645
646 status_t err = UNKNOWN_ERROR;
647
648 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
649 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
650 const hidl_vec<uint8_t>& hWrappedKey) {
651 if (status == Status::OK) {
652 certificate = toVector(hCertificate);
653 wrappedKey = toVector(hWrappedKey);
654 }
655 err = toStatusT(status);
656 }
657 );
658
659 return hResult.isOk() ? err : DEAD_OBJECT;
660}
661
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800662status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800663 Mutex::Autolock autoLock(mLock);
664
665 if (mInitCheck != OK) {
666 return mInitCheck;
667 }
668
669 status_t err = UNKNOWN_ERROR;
670
671 Return<void> hResult = mPlugin->getSecureStops(
672 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
673 if (status == Status::OK) {
674 secureStops = toSecureStops(hSecureStops);
675 }
676 err = toStatusT(status);
677 }
678 );
679
680 return hResult.isOk() ? err : DEAD_OBJECT;
681}
682
683
684status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
685 Mutex::Autolock autoLock(mLock);
686
687 if (mInitCheck != OK) {
688 return mInitCheck;
689 }
690
691 status_t err = UNKNOWN_ERROR;
692
693 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
694 [&](Status status, const SecureStop& hSecureStop) {
695 if (status == Status::OK) {
696 secureStop = toVector(hSecureStop.opaqueData);
697 }
698 err = toStatusT(status);
699 }
700 );
701
702 return hResult.isOk() ? err : DEAD_OBJECT;
703}
704
705status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
706 Mutex::Autolock autoLock(mLock);
707
708 if (mInitCheck != OK) {
709 return mInitCheck;
710 }
711
712 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
713}
714
715status_t DrmHal::releaseAllSecureStops() {
716 Mutex::Autolock autoLock(mLock);
717
718 if (mInitCheck != OK) {
719 return mInitCheck;
720 }
721
722 return toStatusT(mPlugin->releaseAllSecureStops());
723}
724
725status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
726 Mutex::Autolock autoLock(mLock);
727
728 if (mInitCheck != OK) {
729 return mInitCheck;
730 }
731
732 status_t err = UNKNOWN_ERROR;
733
734 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
735 [&](Status status, const hidl_string& hValue) {
736 if (status == Status::OK) {
737 value = toString8(hValue);
738 }
739 err = toStatusT(status);
740 }
741 );
742
743 return hResult.isOk() ? err : DEAD_OBJECT;
744}
745
746status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
747 Mutex::Autolock autoLock(mLock);
748
749 if (mInitCheck != OK) {
750 return mInitCheck;
751 }
752
753 status_t err = UNKNOWN_ERROR;
754
755 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
756 [&](Status status, const hidl_vec<uint8_t>& hValue) {
757 if (status == Status::OK) {
758 value = toVector(hValue);
759 }
760 err = toStatusT(status);
761 }
762 );
763
764 return hResult.isOk() ? err : DEAD_OBJECT;
765}
766
767status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
768 Mutex::Autolock autoLock(mLock);
769
770 if (mInitCheck != OK) {
771 return mInitCheck;
772 }
773
774 Status status = mPlugin->setPropertyString(toHidlString(name),
775 toHidlString(value));
776 return toStatusT(status);
777}
778
779status_t DrmHal::setPropertyByteArray(String8 const &name,
780 Vector<uint8_t> const &value ) const {
781 Mutex::Autolock autoLock(mLock);
782
783 if (mInitCheck != OK) {
784 return mInitCheck;
785 }
786
787 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
788 toHidlVec(value));
789 return toStatusT(status);
790}
791
792
793status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
794 String8 const &algorithm) {
795 Mutex::Autolock autoLock(mLock);
796
797 if (mInitCheck != OK) {
798 return mInitCheck;
799 }
800
801 DrmSessionManager::Instance()->useSession(sessionId);
802
803 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
804 toHidlString(algorithm));
805 return toStatusT(status);
806}
807
808status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
809 String8 const &algorithm) {
810 Mutex::Autolock autoLock(mLock);
811
812 if (mInitCheck != OK) {
813 return mInitCheck;
814 }
815
816 DrmSessionManager::Instance()->useSession(sessionId);
817
818 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
819 toHidlString(algorithm));
820 return toStatusT(status);
821}
822
823status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800824 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
825 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800826 Mutex::Autolock autoLock(mLock);
827
828 if (mInitCheck != OK) {
829 return mInitCheck;
830 }
831
832 DrmSessionManager::Instance()->useSession(sessionId);
833
834 status_t err = UNKNOWN_ERROR;
835
836 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
837 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
838 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
839 if (status == Status::OK) {
840 output = toVector(hOutput);
841 }
842 err = toStatusT(status);
843 }
844 );
845
846 return hResult.isOk() ? err : DEAD_OBJECT;
847}
848
849status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800850 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
851 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800852 Mutex::Autolock autoLock(mLock);
853
854 if (mInitCheck != OK) {
855 return mInitCheck;
856 }
857
858 DrmSessionManager::Instance()->useSession(sessionId);
859
860 status_t err = UNKNOWN_ERROR;
861
862 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
863 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
864 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
865 if (status == Status::OK) {
866 output = toVector(hOutput);
867 }
868 err = toStatusT(status);
869 }
870 );
871
872 return hResult.isOk() ? err : DEAD_OBJECT;
873}
874
875status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800876 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
877 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800878 Mutex::Autolock autoLock(mLock);
879
880 if (mInitCheck != OK) {
881 return mInitCheck;
882 }
883
884 DrmSessionManager::Instance()->useSession(sessionId);
885
886 status_t err = UNKNOWN_ERROR;
887
888 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
889 toHidlVec(keyId), toHidlVec(message),
890 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
891 if (status == Status::OK) {
892 signature = toVector(hSignature);
893 }
894 err = toStatusT(status);
895 }
896 );
897
898 return hResult.isOk() ? err : DEAD_OBJECT;
899}
900
901status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800902 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
903 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800904 Mutex::Autolock autoLock(mLock);
905
906 if (mInitCheck != OK) {
907 return mInitCheck;
908 }
909
910 DrmSessionManager::Instance()->useSession(sessionId);
911
912 status_t err = UNKNOWN_ERROR;
913
914 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
915 toHidlVec(message), toHidlVec(signature),
916 [&](Status status, bool hMatch) {
917 if (status == Status::OK) {
918 match = hMatch;
919 } else {
920 match = false;
921 }
922 err = toStatusT(status);
923 }
924 );
925
926 return hResult.isOk() ? err : DEAD_OBJECT;
927}
928
929status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800930 String8 const &algorithm, Vector<uint8_t> const &message,
931 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932 Mutex::Autolock autoLock(mLock);
933
934 if (mInitCheck != OK) {
935 return mInitCheck;
936 }
937
938 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
939 return -EPERM;
940 }
941
942 DrmSessionManager::Instance()->useSession(sessionId);
943
944 status_t err = UNKNOWN_ERROR;
945
946 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
947 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
948 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
949 if (status == Status::OK) {
950 signature = toVector(hSignature);
951 }
952 err = toStatusT(status);
953 }
954 );
955
956 return hResult.isOk() ? err : DEAD_OBJECT;
957}
958
959void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
960{
961 mEventLock.lock();
962 mListener.clear();
963 mEventLock.unlock();
964
965 Mutex::Autolock autoLock(mLock);
966 mPlugin.clear();
967}
968
969void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
970{
971 if (vec.size()) {
972 obj.writeInt32(vec.size());
973 obj.write(vec.data(), vec.size());
974 } else {
975 obj.writeInt32(0);
976 }
977}
978
979} // namespace android