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