blob: 6d54fa5452dc63171330b9366dda14b317566274 [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
Jeff Tinker61332812017-05-15 16:53:10 -0700197void DrmHal::closeOpenSessions() {
198 if (mPlugin != NULL) {
199 for (size_t i = 0; i < mOpenSessions.size(); i++) {
200 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
201 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
202 }
203 }
204 mOpenSessions.clear();
205}
206
Jeff Tinkera53d6552017-01-20 00:31:46 -0800207DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700208 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800209 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
210}
211
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800212Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
213 Vector<sp<IDrmFactory>> factories;
214
Jeff Tinker593111f2017-05-25 16:00:21 -0700215 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800216
217 if (manager != NULL) {
218 manager->listByInterface(IDrmFactory::descriptor,
219 [&factories](const hidl_vec<hidl_string> &registered) {
220 for (const auto &instance : registered) {
221 auto factory = IDrmFactory::getService(instance);
222 if (factory != NULL) {
223 factories.push_back(factory);
224 ALOGI("makeDrmFactories: factory instance %s is %s",
225 instance.c_str(),
226 factory->isRemote() ? "Remote" : "Not Remote");
227 }
228 }
229 }
230 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800231 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800232
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800233 if (factories.size() == 0) {
234 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700235 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800236 if (passthrough != NULL) {
237 ALOGI("makeDrmFactories: using default drm instance");
238 factories.push_back(passthrough);
239 } else {
240 ALOGE("Failed to find any drm factories");
241 }
242 }
243 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800244}
245
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800246sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
247 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800248
249 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800250 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800251 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800252 if (status != Status::OK) {
253 ALOGE("Failed to make drm plugin");
254 return;
255 }
256 plugin = hPlugin;
257 }
258 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800259 return plugin;
260}
261
262status_t DrmHal::initCheck() const {
263 return mInitCheck;
264}
265
266status_t DrmHal::setListener(const sp<IDrmClient>& listener)
267{
268 Mutex::Autolock lock(mEventLock);
269 if (mListener != NULL){
270 IInterface::asBinder(mListener)->unlinkToDeath(this);
271 }
272 if (listener != NULL) {
273 IInterface::asBinder(listener)->linkToDeath(this);
274 }
275 mListener = listener;
276 return NO_ERROR;
277}
278
279Return<void> DrmHal::sendEvent(EventType hEventType,
280 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
281
282 mEventLock.lock();
283 sp<IDrmClient> listener = mListener;
284 mEventLock.unlock();
285
286 if (listener != NULL) {
287 Parcel obj;
288 writeByteArray(obj, sessionId);
289 writeByteArray(obj, data);
290
291 Mutex::Autolock lock(mNotifyLock);
292 DrmPlugin::EventType eventType;
293 switch(hEventType) {
294 case EventType::PROVISION_REQUIRED:
295 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
296 break;
297 case EventType::KEY_NEEDED:
298 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
299 break;
300 case EventType::KEY_EXPIRED:
301 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
302 break;
303 case EventType::VENDOR_DEFINED:
304 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
305 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700306 case EventType::SESSION_RECLAIMED:
307 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
308 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800309 default:
310 return Void();
311 }
312 listener->notify(eventType, 0, &obj);
313 }
314 return Void();
315}
316
317Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
318 int64_t expiryTimeInMS) {
319
320 mEventLock.lock();
321 sp<IDrmClient> listener = mListener;
322 mEventLock.unlock();
323
324 if (listener != NULL) {
325 Parcel obj;
326 writeByteArray(obj, sessionId);
327 obj.writeInt64(expiryTimeInMS);
328
329 Mutex::Autolock lock(mNotifyLock);
330 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
331 }
332 return Void();
333}
334
335Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
336 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
337
338 mEventLock.lock();
339 sp<IDrmClient> listener = mListener;
340 mEventLock.unlock();
341
342 if (listener != NULL) {
343 Parcel obj;
344 writeByteArray(obj, sessionId);
345
346 size_t nKeys = keyStatusList.size();
347 obj.writeInt32(nKeys);
348 for (size_t i = 0; i < nKeys; ++i) {
349 const KeyStatus &keyStatus = keyStatusList[i];
350 writeByteArray(obj, keyStatus.keyId);
351 uint32_t type;
352 switch(keyStatus.type) {
353 case KeyStatusType::USABLE:
354 type = DrmPlugin::kKeyStatusType_Usable;
355 break;
356 case KeyStatusType::EXPIRED:
357 type = DrmPlugin::kKeyStatusType_Expired;
358 break;
359 case KeyStatusType::OUTPUTNOTALLOWED:
360 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
361 break;
362 case KeyStatusType::STATUSPENDING:
363 type = DrmPlugin::kKeyStatusType_StatusPending;
364 break;
365 case KeyStatusType::INTERNALERROR:
366 default:
367 type = DrmPlugin::kKeyStatusType_InternalError;
368 break;
369 }
370 obj.writeInt32(type);
371 }
372 obj.writeInt32(hasNewUsableKey);
373
374 Mutex::Autolock lock(mNotifyLock);
375 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
376 }
377 return Void();
378}
379
380bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
381 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800382
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800383 for (size_t i = 0; i < mFactories.size(); i++) {
384 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
385 if (mimeType != "") {
386 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
387 return true;
388 }
389 } else {
390 return true;
391 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800392 }
393 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800394 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800395}
396
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800397status_t DrmHal::createPlugin(const uint8_t uuid[16],
398 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800399 Mutex::Autolock autoLock(mLock);
400
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800401 for (size_t i = 0; i < mFactories.size(); i++) {
402 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
403 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
404 }
405 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800406
407 if (mPlugin == NULL) {
408 mInitCheck = ERROR_UNSUPPORTED;
409 } else {
410 mInitCheck = OK;
411 mPlugin->setListener(this);
412 }
413
414 return mInitCheck;
415}
416
417status_t DrmHal::destroyPlugin() {
418 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800419 if (mInitCheck != OK) {
420 return mInitCheck;
421 }
422
Jeff Tinker61332812017-05-15 16:53:10 -0700423 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700425 if (mPlugin != NULL) {
426 mPlugin->setListener(NULL);
427 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800428 mPlugin.clear();
Jeff Tinker70367f52017-06-16 12:41:33 -0700429 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800430
431 return OK;
432}
433
434status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
435 Mutex::Autolock autoLock(mLock);
436
437 if (mInitCheck != OK) {
438 return mInitCheck;
439 }
440
441 status_t err = UNKNOWN_ERROR;
442
443 bool retry = true;
444 do {
445 hidl_vec<uint8_t> hSessionId;
446
447 Return<void> hResult = mPlugin->openSession(
448 [&](Status status, const hidl_vec<uint8_t>& id) {
449 if (status == Status::OK) {
450 sessionId = toVector(id);
451 }
452 err = toStatusT(status);
453 }
454 );
455
456 if (!hResult.isOk()) {
457 err = DEAD_OBJECT;
458 }
459
460 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
461 mLock.unlock();
462 // reclaimSession may call back to closeSession, since mLock is
463 // shared between Drm instances, we should unlock here to avoid
464 // deadlock.
465 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
466 mLock.lock();
467 } else {
468 retry = false;
469 }
470 } while (retry);
471
472 if (err == OK) {
473 DrmSessionManager::Instance()->addSession(getCallingPid(),
474 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700475 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800476 }
477 return err;
478}
479
480status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
481 Mutex::Autolock autoLock(mLock);
482
483 if (mInitCheck != OK) {
484 return mInitCheck;
485 }
486
487 Status status = mPlugin->closeSession(toHidlVec(sessionId));
488 if (status == Status::OK) {
489 DrmSessionManager::Instance()->removeSession(sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700490 for (size_t i = 0; i < mOpenSessions.size(); i++) {
491 if (mOpenSessions[i] == sessionId) {
492 mOpenSessions.removeAt(i);
493 break;
494 }
495 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800496 }
497 return toStatusT(status);
498}
499
500status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
501 Vector<uint8_t> const &initData, String8 const &mimeType,
502 DrmPlugin::KeyType keyType, KeyedVector<String8,
503 String8> const &optionalParameters, Vector<uint8_t> &request,
504 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
505 Mutex::Autolock autoLock(mLock);
506
507 if (mInitCheck != OK) {
508 return mInitCheck;
509 }
510
511 DrmSessionManager::Instance()->useSession(sessionId);
512
513 KeyType hKeyType;
514 if (keyType == DrmPlugin::kKeyType_Streaming) {
515 hKeyType = KeyType::STREAMING;
516 } else if (keyType == DrmPlugin::kKeyType_Offline) {
517 hKeyType = KeyType::OFFLINE;
518 } else if (keyType == DrmPlugin::kKeyType_Release) {
519 hKeyType = KeyType::RELEASE;
520 } else {
521 return BAD_VALUE;
522 }
523
524 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
525
526 status_t err = UNKNOWN_ERROR;
527
528 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
529 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
530 [&](Status status, const hidl_vec<uint8_t>& hRequest,
531 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
532
533 if (status == Status::OK) {
534 request = toVector(hRequest);
535 defaultUrl = toString8(hDefaultUrl);
536
537 switch (hKeyRequestType) {
538 case KeyRequestType::INITIAL:
539 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
540 break;
541 case KeyRequestType::RENEWAL:
542 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
543 break;
544 case KeyRequestType::RELEASE:
545 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
546 break;
547 default:
548 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
549 break;
550 }
551 err = toStatusT(status);
552 }
553 });
554
555 return hResult.isOk() ? err : DEAD_OBJECT;
556}
557
558status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
559 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
560 Mutex::Autolock autoLock(mLock);
561
562 if (mInitCheck != OK) {
563 return mInitCheck;
564 }
565
566 DrmSessionManager::Instance()->useSession(sessionId);
567
568 status_t err = UNKNOWN_ERROR;
569
570 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
571 toHidlVec(response),
572 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
573 if (status == Status::OK) {
574 keySetId = toVector(hKeySetId);
575 }
576 err = toStatusT(status);
577 }
578 );
579
580 return hResult.isOk() ? err : DEAD_OBJECT;
581}
582
583status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
584 Mutex::Autolock autoLock(mLock);
585
586 if (mInitCheck != OK) {
587 return mInitCheck;
588 }
589
590 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
591}
592
593status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
594 Vector<uint8_t> const &keySetId) {
595 Mutex::Autolock autoLock(mLock);
596
597 if (mInitCheck != OK) {
598 return mInitCheck;
599 }
600
601 DrmSessionManager::Instance()->useSession(sessionId);
602
603 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
604 toHidlVec(keySetId)));
605}
606
607status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
608 KeyedVector<String8, String8> &infoMap) const {
609 Mutex::Autolock autoLock(mLock);
610
611 if (mInitCheck != OK) {
612 return mInitCheck;
613 }
614
615 DrmSessionManager::Instance()->useSession(sessionId);
616
617 ::KeyedVector hInfoMap;
618
619 status_t err = UNKNOWN_ERROR;
620
621 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
622 [&](Status status, const hidl_vec<KeyValue>& map) {
623 if (status == Status::OK) {
624 infoMap = toKeyedVector(map);
625 }
626 err = toStatusT(status);
627 }
628 );
629
630 return hResult.isOk() ? err : DEAD_OBJECT;
631}
632
633status_t DrmHal::getProvisionRequest(String8 const &certType,
634 String8 const &certAuthority, Vector<uint8_t> &request,
635 String8 &defaultUrl) {
636 Mutex::Autolock autoLock(mLock);
637
638 if (mInitCheck != OK) {
639 return mInitCheck;
640 }
641
642 status_t err = UNKNOWN_ERROR;
643
644 Return<void> hResult = mPlugin->getProvisionRequest(
645 toHidlString(certType), toHidlString(certAuthority),
646 [&](Status status, const hidl_vec<uint8_t>& hRequest,
647 const hidl_string& hDefaultUrl) {
648 if (status == Status::OK) {
649 request = toVector(hRequest);
650 defaultUrl = toString8(hDefaultUrl);
651 }
652 err = toStatusT(status);
653 }
654 );
655
656 return hResult.isOk() ? err : DEAD_OBJECT;
657}
658
659status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800660 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
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->provideProvisionResponse(toHidlVec(response),
670 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
671 const hidl_vec<uint8_t>& hWrappedKey) {
672 if (status == Status::OK) {
673 certificate = toVector(hCertificate);
674 wrappedKey = toVector(hWrappedKey);
675 }
676 err = toStatusT(status);
677 }
678 );
679
680 return hResult.isOk() ? err : DEAD_OBJECT;
681}
682
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800683status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800684 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->getSecureStops(
693 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
694 if (status == Status::OK) {
695 secureStops = toSecureStops(hSecureStops);
696 }
697 err = toStatusT(status);
698 }
699 );
700
701 return hResult.isOk() ? err : DEAD_OBJECT;
702}
703
704
705status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
706 Mutex::Autolock autoLock(mLock);
707
708 if (mInitCheck != OK) {
709 return mInitCheck;
710 }
711
712 status_t err = UNKNOWN_ERROR;
713
714 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
715 [&](Status status, const SecureStop& hSecureStop) {
716 if (status == Status::OK) {
717 secureStop = toVector(hSecureStop.opaqueData);
718 }
719 err = toStatusT(status);
720 }
721 );
722
723 return hResult.isOk() ? err : DEAD_OBJECT;
724}
725
726status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
727 Mutex::Autolock autoLock(mLock);
728
729 if (mInitCheck != OK) {
730 return mInitCheck;
731 }
732
733 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
734}
735
736status_t DrmHal::releaseAllSecureStops() {
737 Mutex::Autolock autoLock(mLock);
738
739 if (mInitCheck != OK) {
740 return mInitCheck;
741 }
742
743 return toStatusT(mPlugin->releaseAllSecureStops());
744}
745
746status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
747 Mutex::Autolock autoLock(mLock);
748
749 if (mInitCheck != OK) {
750 return mInitCheck;
751 }
752
753 status_t err = UNKNOWN_ERROR;
754
755 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
756 [&](Status status, const hidl_string& hValue) {
757 if (status == Status::OK) {
758 value = toString8(hValue);
759 }
760 err = toStatusT(status);
761 }
762 );
763
764 return hResult.isOk() ? err : DEAD_OBJECT;
765}
766
767status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
768 Mutex::Autolock autoLock(mLock);
769
770 if (mInitCheck != OK) {
771 return mInitCheck;
772 }
773
774 status_t err = UNKNOWN_ERROR;
775
776 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
777 [&](Status status, const hidl_vec<uint8_t>& hValue) {
778 if (status == Status::OK) {
779 value = toVector(hValue);
780 }
781 err = toStatusT(status);
782 }
783 );
784
785 return hResult.isOk() ? err : DEAD_OBJECT;
786}
787
788status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
789 Mutex::Autolock autoLock(mLock);
790
791 if (mInitCheck != OK) {
792 return mInitCheck;
793 }
794
795 Status status = mPlugin->setPropertyString(toHidlString(name),
796 toHidlString(value));
797 return toStatusT(status);
798}
799
800status_t DrmHal::setPropertyByteArray(String8 const &name,
801 Vector<uint8_t> const &value ) const {
802 Mutex::Autolock autoLock(mLock);
803
804 if (mInitCheck != OK) {
805 return mInitCheck;
806 }
807
808 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
809 toHidlVec(value));
810 return toStatusT(status);
811}
812
813
814status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
815 String8 const &algorithm) {
816 Mutex::Autolock autoLock(mLock);
817
818 if (mInitCheck != OK) {
819 return mInitCheck;
820 }
821
822 DrmSessionManager::Instance()->useSession(sessionId);
823
824 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
825 toHidlString(algorithm));
826 return toStatusT(status);
827}
828
829status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
830 String8 const &algorithm) {
831 Mutex::Autolock autoLock(mLock);
832
833 if (mInitCheck != OK) {
834 return mInitCheck;
835 }
836
837 DrmSessionManager::Instance()->useSession(sessionId);
838
839 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
840 toHidlString(algorithm));
841 return toStatusT(status);
842}
843
844status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800845 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
846 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800847 Mutex::Autolock autoLock(mLock);
848
849 if (mInitCheck != OK) {
850 return mInitCheck;
851 }
852
853 DrmSessionManager::Instance()->useSession(sessionId);
854
855 status_t err = UNKNOWN_ERROR;
856
857 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
858 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
859 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
860 if (status == Status::OK) {
861 output = toVector(hOutput);
862 }
863 err = toStatusT(status);
864 }
865 );
866
867 return hResult.isOk() ? err : DEAD_OBJECT;
868}
869
870status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800871 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
872 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800873 Mutex::Autolock autoLock(mLock);
874
875 if (mInitCheck != OK) {
876 return mInitCheck;
877 }
878
879 DrmSessionManager::Instance()->useSession(sessionId);
880
881 status_t err = UNKNOWN_ERROR;
882
883 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
884 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
885 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
886 if (status == Status::OK) {
887 output = toVector(hOutput);
888 }
889 err = toStatusT(status);
890 }
891 );
892
893 return hResult.isOk() ? err : DEAD_OBJECT;
894}
895
896status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800897 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
898 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899 Mutex::Autolock autoLock(mLock);
900
901 if (mInitCheck != OK) {
902 return mInitCheck;
903 }
904
905 DrmSessionManager::Instance()->useSession(sessionId);
906
907 status_t err = UNKNOWN_ERROR;
908
909 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
910 toHidlVec(keyId), toHidlVec(message),
911 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
912 if (status == Status::OK) {
913 signature = toVector(hSignature);
914 }
915 err = toStatusT(status);
916 }
917 );
918
919 return hResult.isOk() ? err : DEAD_OBJECT;
920}
921
922status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800923 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
924 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800925 Mutex::Autolock autoLock(mLock);
926
927 if (mInitCheck != OK) {
928 return mInitCheck;
929 }
930
931 DrmSessionManager::Instance()->useSession(sessionId);
932
933 status_t err = UNKNOWN_ERROR;
934
935 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
936 toHidlVec(message), toHidlVec(signature),
937 [&](Status status, bool hMatch) {
938 if (status == Status::OK) {
939 match = hMatch;
940 } else {
941 match = false;
942 }
943 err = toStatusT(status);
944 }
945 );
946
947 return hResult.isOk() ? err : DEAD_OBJECT;
948}
949
950status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800951 String8 const &algorithm, Vector<uint8_t> const &message,
952 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800953 Mutex::Autolock autoLock(mLock);
954
955 if (mInitCheck != OK) {
956 return mInitCheck;
957 }
958
959 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
960 return -EPERM;
961 }
962
963 DrmSessionManager::Instance()->useSession(sessionId);
964
965 status_t err = UNKNOWN_ERROR;
966
967 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
968 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
969 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
970 if (status == Status::OK) {
971 signature = toVector(hSignature);
972 }
973 err = toStatusT(status);
974 }
975 );
976
977 return hResult.isOk() ? err : DEAD_OBJECT;
978}
979
980void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
981{
Jeff Tinkera53d6552017-01-20 00:31:46 -0800982 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -0700983 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -0700984 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700985 if (mPlugin != NULL) {
986 mPlugin->setListener(NULL);
987 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800988 mPlugin.clear();
Jeff Tinker70367f52017-06-16 12:41:33 -0700989 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800990}
991
992void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
993{
994 if (vec.size()) {
995 obj.writeInt32(vec.size());
996 obj.write(vec.data(), vec.size());
997 } else {
998 obj.writeInt32(0);
999 }
1000}
1001
1002} // namespace android