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