blob: 3596f128bcd4a70f91c07da13bd12ed08910b9d1 [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);
413 mPlugin.clear();
414
415 return OK;
416}
417
418status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
419 Mutex::Autolock autoLock(mLock);
420
421 if (mInitCheck != OK) {
422 return mInitCheck;
423 }
424
425 status_t err = UNKNOWN_ERROR;
426
427 bool retry = true;
428 do {
429 hidl_vec<uint8_t> hSessionId;
430
431 Return<void> hResult = mPlugin->openSession(
432 [&](Status status, const hidl_vec<uint8_t>& id) {
433 if (status == Status::OK) {
434 sessionId = toVector(id);
435 }
436 err = toStatusT(status);
437 }
438 );
439
440 if (!hResult.isOk()) {
441 err = DEAD_OBJECT;
442 }
443
444 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
445 mLock.unlock();
446 // reclaimSession may call back to closeSession, since mLock is
447 // shared between Drm instances, we should unlock here to avoid
448 // deadlock.
449 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
450 mLock.lock();
451 } else {
452 retry = false;
453 }
454 } while (retry);
455
456 if (err == OK) {
457 DrmSessionManager::Instance()->addSession(getCallingPid(),
458 mDrmSessionClient, sessionId);
459 }
460 return err;
461}
462
463status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
464 Mutex::Autolock autoLock(mLock);
465
466 if (mInitCheck != OK) {
467 return mInitCheck;
468 }
469
470 Status status = mPlugin->closeSession(toHidlVec(sessionId));
471 if (status == Status::OK) {
472 DrmSessionManager::Instance()->removeSession(sessionId);
473 }
474 return toStatusT(status);
475}
476
477status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
478 Vector<uint8_t> const &initData, String8 const &mimeType,
479 DrmPlugin::KeyType keyType, KeyedVector<String8,
480 String8> const &optionalParameters, Vector<uint8_t> &request,
481 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
482 Mutex::Autolock autoLock(mLock);
483
484 if (mInitCheck != OK) {
485 return mInitCheck;
486 }
487
488 DrmSessionManager::Instance()->useSession(sessionId);
489
490 KeyType hKeyType;
491 if (keyType == DrmPlugin::kKeyType_Streaming) {
492 hKeyType = KeyType::STREAMING;
493 } else if (keyType == DrmPlugin::kKeyType_Offline) {
494 hKeyType = KeyType::OFFLINE;
495 } else if (keyType == DrmPlugin::kKeyType_Release) {
496 hKeyType = KeyType::RELEASE;
497 } else {
498 return BAD_VALUE;
499 }
500
501 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
502
503 status_t err = UNKNOWN_ERROR;
504
505 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
506 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
507 [&](Status status, const hidl_vec<uint8_t>& hRequest,
508 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
509
510 if (status == Status::OK) {
511 request = toVector(hRequest);
512 defaultUrl = toString8(hDefaultUrl);
513
514 switch (hKeyRequestType) {
515 case KeyRequestType::INITIAL:
516 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
517 break;
518 case KeyRequestType::RENEWAL:
519 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
520 break;
521 case KeyRequestType::RELEASE:
522 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
523 break;
524 default:
525 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
526 break;
527 }
528 err = toStatusT(status);
529 }
530 });
531
532 return hResult.isOk() ? err : DEAD_OBJECT;
533}
534
535status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
536 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
537 Mutex::Autolock autoLock(mLock);
538
539 if (mInitCheck != OK) {
540 return mInitCheck;
541 }
542
543 DrmSessionManager::Instance()->useSession(sessionId);
544
545 status_t err = UNKNOWN_ERROR;
546
547 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
548 toHidlVec(response),
549 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
550 if (status == Status::OK) {
551 keySetId = toVector(hKeySetId);
552 }
553 err = toStatusT(status);
554 }
555 );
556
557 return hResult.isOk() ? err : DEAD_OBJECT;
558}
559
560status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
561 Mutex::Autolock autoLock(mLock);
562
563 if (mInitCheck != OK) {
564 return mInitCheck;
565 }
566
567 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
568}
569
570status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
571 Vector<uint8_t> const &keySetId) {
572 Mutex::Autolock autoLock(mLock);
573
574 if (mInitCheck != OK) {
575 return mInitCheck;
576 }
577
578 DrmSessionManager::Instance()->useSession(sessionId);
579
580 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
581 toHidlVec(keySetId)));
582}
583
584status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
585 KeyedVector<String8, String8> &infoMap) const {
586 Mutex::Autolock autoLock(mLock);
587
588 if (mInitCheck != OK) {
589 return mInitCheck;
590 }
591
592 DrmSessionManager::Instance()->useSession(sessionId);
593
594 ::KeyedVector hInfoMap;
595
596 status_t err = UNKNOWN_ERROR;
597
598 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
599 [&](Status status, const hidl_vec<KeyValue>& map) {
600 if (status == Status::OK) {
601 infoMap = toKeyedVector(map);
602 }
603 err = toStatusT(status);
604 }
605 );
606
607 return hResult.isOk() ? err : DEAD_OBJECT;
608}
609
610status_t DrmHal::getProvisionRequest(String8 const &certType,
611 String8 const &certAuthority, Vector<uint8_t> &request,
612 String8 &defaultUrl) {
613 Mutex::Autolock autoLock(mLock);
614
615 if (mInitCheck != OK) {
616 return mInitCheck;
617 }
618
619 status_t err = UNKNOWN_ERROR;
620
621 Return<void> hResult = mPlugin->getProvisionRequest(
622 toHidlString(certType), toHidlString(certAuthority),
623 [&](Status status, const hidl_vec<uint8_t>& hRequest,
624 const hidl_string& hDefaultUrl) {
625 if (status == Status::OK) {
626 request = toVector(hRequest);
627 defaultUrl = toString8(hDefaultUrl);
628 }
629 err = toStatusT(status);
630 }
631 );
632
633 return hResult.isOk() ? err : DEAD_OBJECT;
634}
635
636status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800637 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800638 Mutex::Autolock autoLock(mLock);
639
640 if (mInitCheck != OK) {
641 return mInitCheck;
642 }
643
644 status_t err = UNKNOWN_ERROR;
645
646 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
647 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
648 const hidl_vec<uint8_t>& hWrappedKey) {
649 if (status == Status::OK) {
650 certificate = toVector(hCertificate);
651 wrappedKey = toVector(hWrappedKey);
652 }
653 err = toStatusT(status);
654 }
655 );
656
657 return hResult.isOk() ? err : DEAD_OBJECT;
658}
659
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800660status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800661 Mutex::Autolock autoLock(mLock);
662
663 if (mInitCheck != OK) {
664 return mInitCheck;
665 }
666
667 status_t err = UNKNOWN_ERROR;
668
669 Return<void> hResult = mPlugin->getSecureStops(
670 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
671 if (status == Status::OK) {
672 secureStops = toSecureStops(hSecureStops);
673 }
674 err = toStatusT(status);
675 }
676 );
677
678 return hResult.isOk() ? err : DEAD_OBJECT;
679}
680
681
682status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
683 Mutex::Autolock autoLock(mLock);
684
685 if (mInitCheck != OK) {
686 return mInitCheck;
687 }
688
689 status_t err = UNKNOWN_ERROR;
690
691 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
692 [&](Status status, const SecureStop& hSecureStop) {
693 if (status == Status::OK) {
694 secureStop = toVector(hSecureStop.opaqueData);
695 }
696 err = toStatusT(status);
697 }
698 );
699
700 return hResult.isOk() ? err : DEAD_OBJECT;
701}
702
703status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
704 Mutex::Autolock autoLock(mLock);
705
706 if (mInitCheck != OK) {
707 return mInitCheck;
708 }
709
710 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
711}
712
713status_t DrmHal::releaseAllSecureStops() {
714 Mutex::Autolock autoLock(mLock);
715
716 if (mInitCheck != OK) {
717 return mInitCheck;
718 }
719
720 return toStatusT(mPlugin->releaseAllSecureStops());
721}
722
723status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
724 Mutex::Autolock autoLock(mLock);
725
726 if (mInitCheck != OK) {
727 return mInitCheck;
728 }
729
730 status_t err = UNKNOWN_ERROR;
731
732 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
733 [&](Status status, const hidl_string& hValue) {
734 if (status == Status::OK) {
735 value = toString8(hValue);
736 }
737 err = toStatusT(status);
738 }
739 );
740
741 return hResult.isOk() ? err : DEAD_OBJECT;
742}
743
744status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
745 Mutex::Autolock autoLock(mLock);
746
747 if (mInitCheck != OK) {
748 return mInitCheck;
749 }
750
751 status_t err = UNKNOWN_ERROR;
752
753 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
754 [&](Status status, const hidl_vec<uint8_t>& hValue) {
755 if (status == Status::OK) {
756 value = toVector(hValue);
757 }
758 err = toStatusT(status);
759 }
760 );
761
762 return hResult.isOk() ? err : DEAD_OBJECT;
763}
764
765status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
766 Mutex::Autolock autoLock(mLock);
767
768 if (mInitCheck != OK) {
769 return mInitCheck;
770 }
771
772 Status status = mPlugin->setPropertyString(toHidlString(name),
773 toHidlString(value));
774 return toStatusT(status);
775}
776
777status_t DrmHal::setPropertyByteArray(String8 const &name,
778 Vector<uint8_t> const &value ) const {
779 Mutex::Autolock autoLock(mLock);
780
781 if (mInitCheck != OK) {
782 return mInitCheck;
783 }
784
785 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
786 toHidlVec(value));
787 return toStatusT(status);
788}
789
790
791status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
792 String8 const &algorithm) {
793 Mutex::Autolock autoLock(mLock);
794
795 if (mInitCheck != OK) {
796 return mInitCheck;
797 }
798
799 DrmSessionManager::Instance()->useSession(sessionId);
800
801 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
802 toHidlString(algorithm));
803 return toStatusT(status);
804}
805
806status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
807 String8 const &algorithm) {
808 Mutex::Autolock autoLock(mLock);
809
810 if (mInitCheck != OK) {
811 return mInitCheck;
812 }
813
814 DrmSessionManager::Instance()->useSession(sessionId);
815
816 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
817 toHidlString(algorithm));
818 return toStatusT(status);
819}
820
821status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800822 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
823 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800824 Mutex::Autolock autoLock(mLock);
825
826 if (mInitCheck != OK) {
827 return mInitCheck;
828 }
829
830 DrmSessionManager::Instance()->useSession(sessionId);
831
832 status_t err = UNKNOWN_ERROR;
833
834 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
835 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
836 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
837 if (status == Status::OK) {
838 output = toVector(hOutput);
839 }
840 err = toStatusT(status);
841 }
842 );
843
844 return hResult.isOk() ? err : DEAD_OBJECT;
845}
846
847status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800848 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
849 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800850 Mutex::Autolock autoLock(mLock);
851
852 if (mInitCheck != OK) {
853 return mInitCheck;
854 }
855
856 DrmSessionManager::Instance()->useSession(sessionId);
857
858 status_t err = UNKNOWN_ERROR;
859
860 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
861 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
862 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
863 if (status == Status::OK) {
864 output = toVector(hOutput);
865 }
866 err = toStatusT(status);
867 }
868 );
869
870 return hResult.isOk() ? err : DEAD_OBJECT;
871}
872
873status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800874 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
875 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800876 Mutex::Autolock autoLock(mLock);
877
878 if (mInitCheck != OK) {
879 return mInitCheck;
880 }
881
882 DrmSessionManager::Instance()->useSession(sessionId);
883
884 status_t err = UNKNOWN_ERROR;
885
886 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
887 toHidlVec(keyId), toHidlVec(message),
888 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
889 if (status == Status::OK) {
890 signature = toVector(hSignature);
891 }
892 err = toStatusT(status);
893 }
894 );
895
896 return hResult.isOk() ? err : DEAD_OBJECT;
897}
898
899status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800900 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
901 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800902 Mutex::Autolock autoLock(mLock);
903
904 if (mInitCheck != OK) {
905 return mInitCheck;
906 }
907
908 DrmSessionManager::Instance()->useSession(sessionId);
909
910 status_t err = UNKNOWN_ERROR;
911
912 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
913 toHidlVec(message), toHidlVec(signature),
914 [&](Status status, bool hMatch) {
915 if (status == Status::OK) {
916 match = hMatch;
917 } else {
918 match = false;
919 }
920 err = toStatusT(status);
921 }
922 );
923
924 return hResult.isOk() ? err : DEAD_OBJECT;
925}
926
927status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800928 String8 const &algorithm, Vector<uint8_t> const &message,
929 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800930 Mutex::Autolock autoLock(mLock);
931
932 if (mInitCheck != OK) {
933 return mInitCheck;
934 }
935
936 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
937 return -EPERM;
938 }
939
940 DrmSessionManager::Instance()->useSession(sessionId);
941
942 status_t err = UNKNOWN_ERROR;
943
944 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
945 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
946 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
947 if (status == Status::OK) {
948 signature = toVector(hSignature);
949 }
950 err = toStatusT(status);
951 }
952 );
953
954 return hResult.isOk() ? err : DEAD_OBJECT;
955}
956
957void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
958{
959 mEventLock.lock();
960 mListener.clear();
961 mEventLock.unlock();
962
963 Mutex::Autolock autoLock(mLock);
964 mPlugin.clear();
965}
966
967void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
968{
969 if (vec.size()) {
970 obj.writeInt32(vec.size());
971 obj.write(vec.data(), vec.size());
972 } else {
973 obj.writeInt32(0);
974 }
975}
976
977} // namespace android