blob: 074489a93f22dfee77fc7c4a2f94b38c337a0d23 [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 Tinkerf0e89b02017-08-07 15:58:41 -0700248
249 if (!hResult.isOk()) {
250 ALOGE("createPlugin remote call failed");
251 }
252
Jeff Tinkera53d6552017-01-20 00:31:46 -0800253 return plugin;
254}
255
256status_t DrmHal::initCheck() const {
257 return mInitCheck;
258}
259
260status_t DrmHal::setListener(const sp<IDrmClient>& listener)
261{
262 Mutex::Autolock lock(mEventLock);
263 if (mListener != NULL){
264 IInterface::asBinder(mListener)->unlinkToDeath(this);
265 }
266 if (listener != NULL) {
267 IInterface::asBinder(listener)->linkToDeath(this);
268 }
269 mListener = listener;
270 return NO_ERROR;
271}
272
273Return<void> DrmHal::sendEvent(EventType hEventType,
274 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
275
276 mEventLock.lock();
277 sp<IDrmClient> listener = mListener;
278 mEventLock.unlock();
279
280 if (listener != NULL) {
281 Parcel obj;
282 writeByteArray(obj, sessionId);
283 writeByteArray(obj, data);
284
285 Mutex::Autolock lock(mNotifyLock);
286 DrmPlugin::EventType eventType;
287 switch(hEventType) {
288 case EventType::PROVISION_REQUIRED:
289 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
290 break;
291 case EventType::KEY_NEEDED:
292 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
293 break;
294 case EventType::KEY_EXPIRED:
295 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
296 break;
297 case EventType::VENDOR_DEFINED:
298 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
299 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700300 case EventType::SESSION_RECLAIMED:
301 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
302 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800303 default:
304 return Void();
305 }
306 listener->notify(eventType, 0, &obj);
307 }
308 return Void();
309}
310
311Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
312 int64_t expiryTimeInMS) {
313
314 mEventLock.lock();
315 sp<IDrmClient> listener = mListener;
316 mEventLock.unlock();
317
318 if (listener != NULL) {
319 Parcel obj;
320 writeByteArray(obj, sessionId);
321 obj.writeInt64(expiryTimeInMS);
322
323 Mutex::Autolock lock(mNotifyLock);
324 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
325 }
326 return Void();
327}
328
329Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
330 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
331
332 mEventLock.lock();
333 sp<IDrmClient> listener = mListener;
334 mEventLock.unlock();
335
336 if (listener != NULL) {
337 Parcel obj;
338 writeByteArray(obj, sessionId);
339
340 size_t nKeys = keyStatusList.size();
341 obj.writeInt32(nKeys);
342 for (size_t i = 0; i < nKeys; ++i) {
343 const KeyStatus &keyStatus = keyStatusList[i];
344 writeByteArray(obj, keyStatus.keyId);
345 uint32_t type;
346 switch(keyStatus.type) {
347 case KeyStatusType::USABLE:
348 type = DrmPlugin::kKeyStatusType_Usable;
349 break;
350 case KeyStatusType::EXPIRED:
351 type = DrmPlugin::kKeyStatusType_Expired;
352 break;
353 case KeyStatusType::OUTPUTNOTALLOWED:
354 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
355 break;
356 case KeyStatusType::STATUSPENDING:
357 type = DrmPlugin::kKeyStatusType_StatusPending;
358 break;
359 case KeyStatusType::INTERNALERROR:
360 default:
361 type = DrmPlugin::kKeyStatusType_InternalError;
362 break;
363 }
364 obj.writeInt32(type);
365 }
366 obj.writeInt32(hasNewUsableKey);
367
368 Mutex::Autolock lock(mNotifyLock);
369 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
370 }
371 return Void();
372}
373
374bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
375 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800376
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800377 for (size_t i = 0; i < mFactories.size(); i++) {
378 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
379 if (mimeType != "") {
380 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
381 return true;
382 }
383 } else {
384 return true;
385 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800386 }
387 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800388 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800389}
390
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800391status_t DrmHal::createPlugin(const uint8_t uuid[16],
392 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800393 Mutex::Autolock autoLock(mLock);
394
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800395 for (size_t i = 0; i < mFactories.size(); i++) {
396 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
397 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
398 }
399 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800400
401 if (mPlugin == NULL) {
402 mInitCheck = ERROR_UNSUPPORTED;
403 } else {
Jeff Tinker81b06822017-07-26 15:44:33 -0700404 if (!mPlugin->setListener(this).isOk()) {
405 mInitCheck = DEAD_OBJECT;
406 } else {
407 mInitCheck = OK;
408 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800409 }
410
411 return mInitCheck;
412}
413
414status_t DrmHal::destroyPlugin() {
415 Mutex::Autolock autoLock(mLock);
416
417 if (mInitCheck != OK) {
418 return mInitCheck;
419 }
420
421 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700422 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800423
Jeff Tinker81b06822017-07-26 15:44:33 -0700424 if (mPlugin != NULL) {
425 if (!mPlugin->setListener(NULL).isOk()) {
426 mInitCheck = DEAD_OBJECT;
427 }
428 }
429 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800430 return OK;
431}
432
433status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
434 Mutex::Autolock autoLock(mLock);
435
436 if (mInitCheck != OK) {
437 return mInitCheck;
438 }
439
440 status_t err = UNKNOWN_ERROR;
441
442 bool retry = true;
443 do {
444 hidl_vec<uint8_t> hSessionId;
445
446 Return<void> hResult = mPlugin->openSession(
447 [&](Status status, const hidl_vec<uint8_t>& id) {
448 if (status == Status::OK) {
449 sessionId = toVector(id);
450 }
451 err = toStatusT(status);
452 }
453 );
454
455 if (!hResult.isOk()) {
456 err = DEAD_OBJECT;
457 }
458
459 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
460 mLock.unlock();
461 // reclaimSession may call back to closeSession, since mLock is
462 // shared between Drm instances, we should unlock here to avoid
463 // deadlock.
464 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
465 mLock.lock();
466 } else {
467 retry = false;
468 }
469 } while (retry);
470
471 if (err == OK) {
472 DrmSessionManager::Instance()->addSession(getCallingPid(),
473 mDrmSessionClient, sessionId);
474 }
475 return err;
476}
477
478status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
479 Mutex::Autolock autoLock(mLock);
480
481 if (mInitCheck != OK) {
482 return mInitCheck;
483 }
484
Jeff Tinker81b06822017-07-26 15:44:33 -0700485 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
486 if (status.isOk()) {
487 if (status == Status::OK) {
488 DrmSessionManager::Instance()->removeSession(sessionId);
489 }
490 return toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800491 }
Jeff Tinker81b06822017-07-26 15:44:33 -0700492 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800493}
494
495status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
496 Vector<uint8_t> const &initData, String8 const &mimeType,
497 DrmPlugin::KeyType keyType, KeyedVector<String8,
498 String8> const &optionalParameters, Vector<uint8_t> &request,
499 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
500 Mutex::Autolock autoLock(mLock);
501
502 if (mInitCheck != OK) {
503 return mInitCheck;
504 }
505
506 DrmSessionManager::Instance()->useSession(sessionId);
507
508 KeyType hKeyType;
509 if (keyType == DrmPlugin::kKeyType_Streaming) {
510 hKeyType = KeyType::STREAMING;
511 } else if (keyType == DrmPlugin::kKeyType_Offline) {
512 hKeyType = KeyType::OFFLINE;
513 } else if (keyType == DrmPlugin::kKeyType_Release) {
514 hKeyType = KeyType::RELEASE;
515 } else {
516 return BAD_VALUE;
517 }
518
519 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
520
521 status_t err = UNKNOWN_ERROR;
522
523 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
524 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
525 [&](Status status, const hidl_vec<uint8_t>& hRequest,
526 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
527
528 if (status == Status::OK) {
529 request = toVector(hRequest);
530 defaultUrl = toString8(hDefaultUrl);
531
532 switch (hKeyRequestType) {
533 case KeyRequestType::INITIAL:
534 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
535 break;
536 case KeyRequestType::RENEWAL:
537 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
538 break;
539 case KeyRequestType::RELEASE:
540 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
541 break;
542 default:
543 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
544 break;
545 }
546 err = toStatusT(status);
547 }
548 });
549
550 return hResult.isOk() ? err : DEAD_OBJECT;
551}
552
553status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
554 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
555 Mutex::Autolock autoLock(mLock);
556
557 if (mInitCheck != OK) {
558 return mInitCheck;
559 }
560
561 DrmSessionManager::Instance()->useSession(sessionId);
562
563 status_t err = UNKNOWN_ERROR;
564
565 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
566 toHidlVec(response),
567 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
568 if (status == Status::OK) {
569 keySetId = toVector(hKeySetId);
570 }
571 err = toStatusT(status);
572 }
573 );
574
575 return hResult.isOk() ? err : DEAD_OBJECT;
576}
577
578status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
579 Mutex::Autolock autoLock(mLock);
580
581 if (mInitCheck != OK) {
582 return mInitCheck;
583 }
584
585 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
586}
587
588status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
589 Vector<uint8_t> const &keySetId) {
590 Mutex::Autolock autoLock(mLock);
591
592 if (mInitCheck != OK) {
593 return mInitCheck;
594 }
595
596 DrmSessionManager::Instance()->useSession(sessionId);
597
598 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
599 toHidlVec(keySetId)));
600}
601
602status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
603 KeyedVector<String8, String8> &infoMap) const {
604 Mutex::Autolock autoLock(mLock);
605
606 if (mInitCheck != OK) {
607 return mInitCheck;
608 }
609
610 DrmSessionManager::Instance()->useSession(sessionId);
611
612 ::KeyedVector hInfoMap;
613
614 status_t err = UNKNOWN_ERROR;
615
616 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
617 [&](Status status, const hidl_vec<KeyValue>& map) {
618 if (status == Status::OK) {
619 infoMap = toKeyedVector(map);
620 }
621 err = toStatusT(status);
622 }
623 );
624
625 return hResult.isOk() ? err : DEAD_OBJECT;
626}
627
628status_t DrmHal::getProvisionRequest(String8 const &certType,
629 String8 const &certAuthority, Vector<uint8_t> &request,
630 String8 &defaultUrl) {
631 Mutex::Autolock autoLock(mLock);
632
633 if (mInitCheck != OK) {
634 return mInitCheck;
635 }
636
637 status_t err = UNKNOWN_ERROR;
638
639 Return<void> hResult = mPlugin->getProvisionRequest(
640 toHidlString(certType), toHidlString(certAuthority),
641 [&](Status status, const hidl_vec<uint8_t>& hRequest,
642 const hidl_string& hDefaultUrl) {
643 if (status == Status::OK) {
644 request = toVector(hRequest);
645 defaultUrl = toString8(hDefaultUrl);
646 }
647 err = toStatusT(status);
648 }
649 );
650
651 return hResult.isOk() ? err : DEAD_OBJECT;
652}
653
654status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800655 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800656 Mutex::Autolock autoLock(mLock);
657
658 if (mInitCheck != OK) {
659 return mInitCheck;
660 }
661
662 status_t err = UNKNOWN_ERROR;
663
664 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
665 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
666 const hidl_vec<uint8_t>& hWrappedKey) {
667 if (status == Status::OK) {
668 certificate = toVector(hCertificate);
669 wrappedKey = toVector(hWrappedKey);
670 }
671 err = toStatusT(status);
672 }
673 );
674
675 return hResult.isOk() ? err : DEAD_OBJECT;
676}
677
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800678status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800679 Mutex::Autolock autoLock(mLock);
680
681 if (mInitCheck != OK) {
682 return mInitCheck;
683 }
684
685 status_t err = UNKNOWN_ERROR;
686
687 Return<void> hResult = mPlugin->getSecureStops(
688 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
689 if (status == Status::OK) {
690 secureStops = toSecureStops(hSecureStops);
691 }
692 err = toStatusT(status);
693 }
694 );
695
696 return hResult.isOk() ? err : DEAD_OBJECT;
697}
698
699
700status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
701 Mutex::Autolock autoLock(mLock);
702
703 if (mInitCheck != OK) {
704 return mInitCheck;
705 }
706
707 status_t err = UNKNOWN_ERROR;
708
709 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
710 [&](Status status, const SecureStop& hSecureStop) {
711 if (status == Status::OK) {
712 secureStop = toVector(hSecureStop.opaqueData);
713 }
714 err = toStatusT(status);
715 }
716 );
717
718 return hResult.isOk() ? err : DEAD_OBJECT;
719}
720
721status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
722 Mutex::Autolock autoLock(mLock);
723
724 if (mInitCheck != OK) {
725 return mInitCheck;
726 }
727
728 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
729}
730
731status_t DrmHal::releaseAllSecureStops() {
732 Mutex::Autolock autoLock(mLock);
733
734 if (mInitCheck != OK) {
735 return mInitCheck;
736 }
737
738 return toStatusT(mPlugin->releaseAllSecureStops());
739}
740
741status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
742 Mutex::Autolock autoLock(mLock);
743
744 if (mInitCheck != OK) {
745 return mInitCheck;
746 }
747
748 status_t err = UNKNOWN_ERROR;
749
750 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
751 [&](Status status, const hidl_string& hValue) {
752 if (status == Status::OK) {
753 value = toString8(hValue);
754 }
755 err = toStatusT(status);
756 }
757 );
758
759 return hResult.isOk() ? err : DEAD_OBJECT;
760}
761
762status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
763 Mutex::Autolock autoLock(mLock);
764
765 if (mInitCheck != OK) {
766 return mInitCheck;
767 }
768
769 status_t err = UNKNOWN_ERROR;
770
771 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
772 [&](Status status, const hidl_vec<uint8_t>& hValue) {
773 if (status == Status::OK) {
774 value = toVector(hValue);
775 }
776 err = toStatusT(status);
777 }
778 );
779
780 return hResult.isOk() ? err : DEAD_OBJECT;
781}
782
783status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
784 Mutex::Autolock autoLock(mLock);
785
786 if (mInitCheck != OK) {
787 return mInitCheck;
788 }
789
790 Status status = mPlugin->setPropertyString(toHidlString(name),
791 toHidlString(value));
792 return toStatusT(status);
793}
794
795status_t DrmHal::setPropertyByteArray(String8 const &name,
796 Vector<uint8_t> const &value ) const {
797 Mutex::Autolock autoLock(mLock);
798
799 if (mInitCheck != OK) {
800 return mInitCheck;
801 }
802
803 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
804 toHidlVec(value));
805 return toStatusT(status);
806}
807
808
809status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
810 String8 const &algorithm) {
811 Mutex::Autolock autoLock(mLock);
812
813 if (mInitCheck != OK) {
814 return mInitCheck;
815 }
816
817 DrmSessionManager::Instance()->useSession(sessionId);
818
819 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
820 toHidlString(algorithm));
821 return toStatusT(status);
822}
823
824status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
825 String8 const &algorithm) {
826 Mutex::Autolock autoLock(mLock);
827
828 if (mInitCheck != OK) {
829 return mInitCheck;
830 }
831
832 DrmSessionManager::Instance()->useSession(sessionId);
833
834 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
835 toHidlString(algorithm));
836 return toStatusT(status);
837}
838
839status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800840 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
841 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800842 Mutex::Autolock autoLock(mLock);
843
844 if (mInitCheck != OK) {
845 return mInitCheck;
846 }
847
848 DrmSessionManager::Instance()->useSession(sessionId);
849
850 status_t err = UNKNOWN_ERROR;
851
852 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
853 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
854 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
855 if (status == Status::OK) {
856 output = toVector(hOutput);
857 }
858 err = toStatusT(status);
859 }
860 );
861
862 return hResult.isOk() ? err : DEAD_OBJECT;
863}
864
865status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800866 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
867 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800868 Mutex::Autolock autoLock(mLock);
869
870 if (mInitCheck != OK) {
871 return mInitCheck;
872 }
873
874 DrmSessionManager::Instance()->useSession(sessionId);
875
876 status_t err = UNKNOWN_ERROR;
877
878 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
879 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
880 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
881 if (status == Status::OK) {
882 output = toVector(hOutput);
883 }
884 err = toStatusT(status);
885 }
886 );
887
888 return hResult.isOk() ? err : DEAD_OBJECT;
889}
890
891status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800892 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
893 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800894 Mutex::Autolock autoLock(mLock);
895
896 if (mInitCheck != OK) {
897 return mInitCheck;
898 }
899
900 DrmSessionManager::Instance()->useSession(sessionId);
901
902 status_t err = UNKNOWN_ERROR;
903
904 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
905 toHidlVec(keyId), toHidlVec(message),
906 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
907 if (status == Status::OK) {
908 signature = toVector(hSignature);
909 }
910 err = toStatusT(status);
911 }
912 );
913
914 return hResult.isOk() ? err : DEAD_OBJECT;
915}
916
917status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800918 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
919 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800920 Mutex::Autolock autoLock(mLock);
921
922 if (mInitCheck != OK) {
923 return mInitCheck;
924 }
925
926 DrmSessionManager::Instance()->useSession(sessionId);
927
928 status_t err = UNKNOWN_ERROR;
929
930 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
931 toHidlVec(message), toHidlVec(signature),
932 [&](Status status, bool hMatch) {
933 if (status == Status::OK) {
934 match = hMatch;
935 } else {
936 match = false;
937 }
938 err = toStatusT(status);
939 }
940 );
941
942 return hResult.isOk() ? err : DEAD_OBJECT;
943}
944
945status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800946 String8 const &algorithm, Vector<uint8_t> const &message,
947 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800948 Mutex::Autolock autoLock(mLock);
949
950 if (mInitCheck != OK) {
951 return mInitCheck;
952 }
953
954 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
955 return -EPERM;
956 }
957
958 DrmSessionManager::Instance()->useSession(sessionId);
959
960 status_t err = UNKNOWN_ERROR;
961
962 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
963 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
964 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
965 if (status == Status::OK) {
966 signature = toVector(hSignature);
967 }
968 err = toStatusT(status);
969 }
970 );
971
972 return hResult.isOk() ? err : DEAD_OBJECT;
973}
974
975void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
976{
Jeff Tinkera53d6552017-01-20 00:31:46 -0800977 Mutex::Autolock autoLock(mLock);
Jeff Tinker81b06822017-07-26 15:44:33 -0700978
Jeff Tinker3e289162017-06-01 11:13:53 -0700979 setListener(NULL);
Jeff Tinker81b06822017-07-26 15:44:33 -0700980 mInitCheck = NO_INIT;
981
Jeff Tinker70367f52017-06-16 12:41:33 -0700982 if (mPlugin != NULL) {
Jeff Tinker81b06822017-07-26 15:44:33 -0700983 if (!mPlugin->setListener(NULL).isOk()) {
984 mInitCheck = DEAD_OBJECT;
985 }
Jeff Tinker70367f52017-06-16 12:41:33 -0700986 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800987 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800988}
989
990void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
991{
992 if (vec.size()) {
993 obj.writeInt32(vec.size());
994 obj.write(vec.data(), vec.size());
995 } else {
996 obj.writeInt32(0);
997 }
998}
999
1000} // namespace android