blob: 3150e3c92ef06578847c7bfd97d40a4649384759 [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>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070033#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080034#include <media/drm/DrmAPI.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AString.h>
37#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/MediaErrors.h>
39
40using ::android::hardware::drm::V1_0::EventType;
41using ::android::hardware::drm::V1_0::IDrmFactory;
42using ::android::hardware::drm::V1_0::IDrmPlugin;
43using ::android::hardware::drm::V1_0::KeyedVector;
44using ::android::hardware::drm::V1_0::KeyRequestType;
45using ::android::hardware::drm::V1_0::KeyStatus;
46using ::android::hardware::drm::V1_0::KeyStatusType;
47using ::android::hardware::drm::V1_0::KeyType;
48using ::android::hardware::drm::V1_0::KeyValue;
49using ::android::hardware::drm::V1_0::SecureStop;
50using ::android::hardware::drm::V1_0::Status;
51using ::android::hardware::hidl_array;
52using ::android::hardware::hidl_string;
53using ::android::hardware::hidl_vec;
54using ::android::hardware::Return;
55using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080056using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080057using ::android::sp;
58
59namespace android {
60
61static inline int getCallingPid() {
62 return IPCThreadState::self()->getCallingPid();
63}
64
65static bool checkPermission(const char* permissionString) {
66 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
67 bool ok = checkCallingPermission(String16(permissionString));
68 if (!ok) ALOGE("Request requires %s", permissionString);
69 return ok;
70}
71
72static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
73 Vector<uint8_t> vector;
74 vector.appendArray(vec.data(), vec.size());
75 return *const_cast<const Vector<uint8_t> *>(&vector);
76}
77
78static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
79 hidl_vec<uint8_t> vec;
80 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
81 return vec;
82}
83
84static String8 toString8(const hidl_string &string) {
85 return String8(string.c_str());
86}
87
88static hidl_string toHidlString(const String8& string) {
89 return hidl_string(string.string());
90}
91
92
93static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
94 keyedVector) {
95 std::vector<KeyValue> stdKeyedVector;
96 for (size_t i = 0; i < keyedVector.size(); i++) {
97 KeyValue keyValue;
98 keyValue.key = toHidlString(keyedVector.keyAt(i));
99 keyValue.value = toHidlString(keyedVector.valueAt(i));
100 stdKeyedVector.push_back(keyValue);
101 }
102 return ::KeyedVector(stdKeyedVector);
103}
104
105static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
106 hKeyedVector) {
107 KeyedVector<String8, String8> keyedVector;
108 for (size_t i = 0; i < hKeyedVector.size(); i++) {
109 keyedVector.add(toString8(hKeyedVector[i].key),
110 toString8(hKeyedVector[i].value));
111 }
112 return keyedVector;
113}
114
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800115static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800116 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800117 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800118 for (size_t i = 0; i < hSecureStops.size(); i++) {
119 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
120 }
121 return secureStops;
122}
123
124static status_t toStatusT(Status status) {
125 switch (status) {
126 case Status::OK:
127 return OK;
128 break;
129 case Status::ERROR_DRM_NO_LICENSE:
130 return ERROR_DRM_NO_LICENSE;
131 break;
132 case Status::ERROR_DRM_LICENSE_EXPIRED:
133 return ERROR_DRM_LICENSE_EXPIRED;
134 break;
135 case Status::ERROR_DRM_SESSION_NOT_OPENED:
136 return ERROR_DRM_SESSION_NOT_OPENED;
137 break;
138 case Status::ERROR_DRM_CANNOT_HANDLE:
139 return ERROR_DRM_CANNOT_HANDLE;
140 break;
141 case Status::ERROR_DRM_INVALID_STATE:
142 return ERROR_DRM_TAMPER_DETECTED;
143 break;
144 case Status::BAD_VALUE:
145 return BAD_VALUE;
146 break;
147 case Status::ERROR_DRM_NOT_PROVISIONED:
148 return ERROR_DRM_NOT_PROVISIONED;
149 break;
150 case Status::ERROR_DRM_RESOURCE_BUSY:
151 return ERROR_DRM_RESOURCE_BUSY;
152 break;
153 case Status::ERROR_DRM_DEVICE_REVOKED:
154 return ERROR_DRM_DEVICE_REVOKED;
155 break;
156 case Status::ERROR_DRM_UNKNOWN:
157 default:
158 return ERROR_DRM_UNKNOWN;
159 break;
160 }
161}
162
163
164Mutex DrmHal::mLock;
165
166struct DrmSessionClient : public DrmSessionClientInterface {
167 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
168
169 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
170 sp<DrmHal> drm = mDrm.promote();
171 if (drm == NULL) {
172 return true;
173 }
174 status_t err = drm->closeSession(sessionId);
175 if (err != OK) {
176 return false;
177 }
178 drm->sendEvent(EventType::SESSION_RECLAIMED,
179 toHidlVec(sessionId), hidl_vec<uint8_t>());
180 return true;
181 }
182
183protected:
184 virtual ~DrmSessionClient() {}
185
186private:
187 wp<DrmHal> mDrm;
188
189 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
190};
191
192DrmHal::DrmHal()
193 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800194 mFactories(makeDrmFactories()),
195 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800196}
197
Jeff Tinker61332812017-05-15 16:53:10 -0700198void DrmHal::closeOpenSessions() {
199 if (mPlugin != NULL) {
200 for (size_t i = 0; i < mOpenSessions.size(); i++) {
201 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
202 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
203 }
204 }
205 mOpenSessions.clear();
206}
207
Jeff Tinkera53d6552017-01-20 00:31:46 -0800208DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700209 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800210 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
211}
212
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800213Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
214 Vector<sp<IDrmFactory>> factories;
215
Jeff Tinker593111f2017-05-25 16:00:21 -0700216 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800217
218 if (manager != NULL) {
219 manager->listByInterface(IDrmFactory::descriptor,
220 [&factories](const hidl_vec<hidl_string> &registered) {
221 for (const auto &instance : registered) {
222 auto factory = IDrmFactory::getService(instance);
223 if (factory != NULL) {
224 factories.push_back(factory);
225 ALOGI("makeDrmFactories: factory instance %s is %s",
226 instance.c_str(),
227 factory->isRemote() ? "Remote" : "Not Remote");
228 }
229 }
230 }
231 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800232 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800233
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800234 if (factories.size() == 0) {
235 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700236 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800237 if (passthrough != NULL) {
238 ALOGI("makeDrmFactories: using default drm instance");
239 factories.push_back(passthrough);
240 } else {
241 ALOGE("Failed to find any drm factories");
242 }
243 }
244 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800245}
246
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800247sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
248 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800249
250 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800251 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800252 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800253 if (status != Status::OK) {
254 ALOGE("Failed to make drm plugin");
255 return;
256 }
257 plugin = hPlugin;
258 }
259 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800260 return plugin;
261}
262
263status_t DrmHal::initCheck() const {
264 return mInitCheck;
265}
266
267status_t DrmHal::setListener(const sp<IDrmClient>& listener)
268{
269 Mutex::Autolock lock(mEventLock);
270 if (mListener != NULL){
271 IInterface::asBinder(mListener)->unlinkToDeath(this);
272 }
273 if (listener != NULL) {
274 IInterface::asBinder(listener)->linkToDeath(this);
275 }
276 mListener = listener;
277 return NO_ERROR;
278}
279
280Return<void> DrmHal::sendEvent(EventType hEventType,
281 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
282
283 mEventLock.lock();
284 sp<IDrmClient> listener = mListener;
285 mEventLock.unlock();
286
287 if (listener != NULL) {
288 Parcel obj;
289 writeByteArray(obj, sessionId);
290 writeByteArray(obj, data);
291
292 Mutex::Autolock lock(mNotifyLock);
293 DrmPlugin::EventType eventType;
294 switch(hEventType) {
295 case EventType::PROVISION_REQUIRED:
296 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
297 break;
298 case EventType::KEY_NEEDED:
299 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
300 break;
301 case EventType::KEY_EXPIRED:
302 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
303 break;
304 case EventType::VENDOR_DEFINED:
305 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
306 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700307 case EventType::SESSION_RECLAIMED:
308 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
309 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800310 default:
311 return Void();
312 }
313 listener->notify(eventType, 0, &obj);
314 }
315 return Void();
316}
317
318Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
319 int64_t expiryTimeInMS) {
320
321 mEventLock.lock();
322 sp<IDrmClient> listener = mListener;
323 mEventLock.unlock();
324
325 if (listener != NULL) {
326 Parcel obj;
327 writeByteArray(obj, sessionId);
328 obj.writeInt64(expiryTimeInMS);
329
330 Mutex::Autolock lock(mNotifyLock);
331 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
332 }
333 return Void();
334}
335
336Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
337 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
338
339 mEventLock.lock();
340 sp<IDrmClient> listener = mListener;
341 mEventLock.unlock();
342
343 if (listener != NULL) {
344 Parcel obj;
345 writeByteArray(obj, sessionId);
346
347 size_t nKeys = keyStatusList.size();
348 obj.writeInt32(nKeys);
349 for (size_t i = 0; i < nKeys; ++i) {
350 const KeyStatus &keyStatus = keyStatusList[i];
351 writeByteArray(obj, keyStatus.keyId);
352 uint32_t type;
353 switch(keyStatus.type) {
354 case KeyStatusType::USABLE:
355 type = DrmPlugin::kKeyStatusType_Usable;
356 break;
357 case KeyStatusType::EXPIRED:
358 type = DrmPlugin::kKeyStatusType_Expired;
359 break;
360 case KeyStatusType::OUTPUTNOTALLOWED:
361 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
362 break;
363 case KeyStatusType::STATUSPENDING:
364 type = DrmPlugin::kKeyStatusType_StatusPending;
365 break;
366 case KeyStatusType::INTERNALERROR:
367 default:
368 type = DrmPlugin::kKeyStatusType_InternalError;
369 break;
370 }
371 obj.writeInt32(type);
372 }
373 obj.writeInt32(hasNewUsableKey);
374
375 Mutex::Autolock lock(mNotifyLock);
376 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
377 }
378 return Void();
379}
380
381bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
382 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800383
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800384 for (size_t i = 0; i < mFactories.size(); i++) {
385 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
386 if (mimeType != "") {
387 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
388 return true;
389 }
390 } else {
391 return true;
392 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800393 }
394 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800395 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800396}
397
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800398status_t DrmHal::createPlugin(const uint8_t uuid[16],
399 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800400 Mutex::Autolock autoLock(mLock);
401
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800402 for (size_t i = 0; i < mFactories.size(); i++) {
403 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
404 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
405 }
406 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800407
408 if (mPlugin == NULL) {
409 mInitCheck = ERROR_UNSUPPORTED;
410 } else {
411 mInitCheck = OK;
412 mPlugin->setListener(this);
413 }
414
415 return mInitCheck;
416}
417
418status_t DrmHal::destroyPlugin() {
419 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800420 if (mInitCheck != OK) {
421 return mInitCheck;
422 }
423
Jeff Tinker61332812017-05-15 16:53:10 -0700424 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700425 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800426 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700427 if (mPlugin != NULL) {
428 mPlugin->setListener(NULL);
429 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800430 mPlugin.clear();
Jeff Tinker70367f52017-06-16 12:41:33 -0700431 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800432
433 return OK;
434}
435
436status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
437 Mutex::Autolock autoLock(mLock);
438
439 if (mInitCheck != OK) {
440 return mInitCheck;
441 }
442
443 status_t err = UNKNOWN_ERROR;
444
445 bool retry = true;
446 do {
447 hidl_vec<uint8_t> hSessionId;
448
449 Return<void> hResult = mPlugin->openSession(
450 [&](Status status, const hidl_vec<uint8_t>& id) {
451 if (status == Status::OK) {
452 sessionId = toVector(id);
453 }
454 err = toStatusT(status);
455 }
456 );
457
458 if (!hResult.isOk()) {
459 err = DEAD_OBJECT;
460 }
461
462 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
463 mLock.unlock();
464 // reclaimSession may call back to closeSession, since mLock is
465 // shared between Drm instances, we should unlock here to avoid
466 // deadlock.
467 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
468 mLock.lock();
469 } else {
470 retry = false;
471 }
472 } while (retry);
473
474 if (err == OK) {
475 DrmSessionManager::Instance()->addSession(getCallingPid(),
476 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700477 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800478 }
479 return err;
480}
481
482status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
483 Mutex::Autolock autoLock(mLock);
484
485 if (mInitCheck != OK) {
486 return mInitCheck;
487 }
488
489 Status status = mPlugin->closeSession(toHidlVec(sessionId));
490 if (status == Status::OK) {
491 DrmSessionManager::Instance()->removeSession(sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700492 for (size_t i = 0; i < mOpenSessions.size(); i++) {
493 if (mOpenSessions[i] == sessionId) {
494 mOpenSessions.removeAt(i);
495 break;
496 }
497 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800498 }
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700499 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800500 return toStatusT(status);
501}
502
503status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
504 Vector<uint8_t> const &initData, String8 const &mimeType,
505 DrmPlugin::KeyType keyType, KeyedVector<String8,
506 String8> const &optionalParameters, Vector<uint8_t> &request,
507 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
508 Mutex::Autolock autoLock(mLock);
509
510 if (mInitCheck != OK) {
511 return mInitCheck;
512 }
513
514 DrmSessionManager::Instance()->useSession(sessionId);
515
516 KeyType hKeyType;
517 if (keyType == DrmPlugin::kKeyType_Streaming) {
518 hKeyType = KeyType::STREAMING;
519 } else if (keyType == DrmPlugin::kKeyType_Offline) {
520 hKeyType = KeyType::OFFLINE;
521 } else if (keyType == DrmPlugin::kKeyType_Release) {
522 hKeyType = KeyType::RELEASE;
523 } else {
524 return BAD_VALUE;
525 }
526
527 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
528
529 status_t err = UNKNOWN_ERROR;
530
531 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
532 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
533 [&](Status status, const hidl_vec<uint8_t>& hRequest,
534 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
535
536 if (status == Status::OK) {
537 request = toVector(hRequest);
538 defaultUrl = toString8(hDefaultUrl);
539
540 switch (hKeyRequestType) {
541 case KeyRequestType::INITIAL:
542 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
543 break;
544 case KeyRequestType::RENEWAL:
545 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
546 break;
547 case KeyRequestType::RELEASE:
548 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
549 break;
550 default:
551 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
552 break;
553 }
554 err = toStatusT(status);
555 }
556 });
557
558 return hResult.isOk() ? err : DEAD_OBJECT;
559}
560
561status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
562 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
563 Mutex::Autolock autoLock(mLock);
564
565 if (mInitCheck != OK) {
566 return mInitCheck;
567 }
568
569 DrmSessionManager::Instance()->useSession(sessionId);
570
571 status_t err = UNKNOWN_ERROR;
572
573 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
574 toHidlVec(response),
575 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
576 if (status == Status::OK) {
577 keySetId = toVector(hKeySetId);
578 }
579 err = toStatusT(status);
580 }
581 );
582
583 return hResult.isOk() ? err : DEAD_OBJECT;
584}
585
586status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
587 Mutex::Autolock autoLock(mLock);
588
589 if (mInitCheck != OK) {
590 return mInitCheck;
591 }
592
593 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
594}
595
596status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
597 Vector<uint8_t> const &keySetId) {
598 Mutex::Autolock autoLock(mLock);
599
600 if (mInitCheck != OK) {
601 return mInitCheck;
602 }
603
604 DrmSessionManager::Instance()->useSession(sessionId);
605
606 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
607 toHidlVec(keySetId)));
608}
609
610status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
611 KeyedVector<String8, String8> &infoMap) const {
612 Mutex::Autolock autoLock(mLock);
613
614 if (mInitCheck != OK) {
615 return mInitCheck;
616 }
617
618 DrmSessionManager::Instance()->useSession(sessionId);
619
620 ::KeyedVector hInfoMap;
621
622 status_t err = UNKNOWN_ERROR;
623
624 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
625 [&](Status status, const hidl_vec<KeyValue>& map) {
626 if (status == Status::OK) {
627 infoMap = toKeyedVector(map);
628 }
629 err = toStatusT(status);
630 }
631 );
632
633 return hResult.isOk() ? err : DEAD_OBJECT;
634}
635
636status_t DrmHal::getProvisionRequest(String8 const &certType,
637 String8 const &certAuthority, Vector<uint8_t> &request,
638 String8 &defaultUrl) {
639 Mutex::Autolock autoLock(mLock);
640
641 if (mInitCheck != OK) {
642 return mInitCheck;
643 }
644
645 status_t err = UNKNOWN_ERROR;
646
647 Return<void> hResult = mPlugin->getProvisionRequest(
648 toHidlString(certType), toHidlString(certAuthority),
649 [&](Status status, const hidl_vec<uint8_t>& hRequest,
650 const hidl_string& hDefaultUrl) {
651 if (status == Status::OK) {
652 request = toVector(hRequest);
653 defaultUrl = toString8(hDefaultUrl);
654 }
655 err = toStatusT(status);
656 }
657 );
658
659 return hResult.isOk() ? err : DEAD_OBJECT;
660}
661
662status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800663 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664 Mutex::Autolock autoLock(mLock);
665
666 if (mInitCheck != OK) {
667 return mInitCheck;
668 }
669
670 status_t err = UNKNOWN_ERROR;
671
672 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
673 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
674 const hidl_vec<uint8_t>& hWrappedKey) {
675 if (status == Status::OK) {
676 certificate = toVector(hCertificate);
677 wrappedKey = toVector(hWrappedKey);
678 }
679 err = toStatusT(status);
680 }
681 );
682
683 return hResult.isOk() ? err : DEAD_OBJECT;
684}
685
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800686status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800687 Mutex::Autolock autoLock(mLock);
688
689 if (mInitCheck != OK) {
690 return mInitCheck;
691 }
692
693 status_t err = UNKNOWN_ERROR;
694
695 Return<void> hResult = mPlugin->getSecureStops(
696 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
697 if (status == Status::OK) {
698 secureStops = toSecureStops(hSecureStops);
699 }
700 err = toStatusT(status);
701 }
702 );
703
704 return hResult.isOk() ? err : DEAD_OBJECT;
705}
706
707
708status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
709 Mutex::Autolock autoLock(mLock);
710
711 if (mInitCheck != OK) {
712 return mInitCheck;
713 }
714
715 status_t err = UNKNOWN_ERROR;
716
717 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
718 [&](Status status, const SecureStop& hSecureStop) {
719 if (status == Status::OK) {
720 secureStop = toVector(hSecureStop.opaqueData);
721 }
722 err = toStatusT(status);
723 }
724 );
725
726 return hResult.isOk() ? err : DEAD_OBJECT;
727}
728
729status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
730 Mutex::Autolock autoLock(mLock);
731
732 if (mInitCheck != OK) {
733 return mInitCheck;
734 }
735
736 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
737}
738
739status_t DrmHal::releaseAllSecureStops() {
740 Mutex::Autolock autoLock(mLock);
741
742 if (mInitCheck != OK) {
743 return mInitCheck;
744 }
745
746 return toStatusT(mPlugin->releaseAllSecureStops());
747}
748
749status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
750 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700751 return getPropertyStringInternal(name, value);
752}
753
754status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
755 // This function is internal to the class and should only be called while
756 // mLock is already held.
Jeff Tinkera53d6552017-01-20 00:31:46 -0800757
758 if (mInitCheck != OK) {
759 return mInitCheck;
760 }
761
762 status_t err = UNKNOWN_ERROR;
763
764 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
765 [&](Status status, const hidl_string& hValue) {
766 if (status == Status::OK) {
767 value = toString8(hValue);
768 }
769 err = toStatusT(status);
770 }
771 );
772
773 return hResult.isOk() ? err : DEAD_OBJECT;
774}
775
776status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
777 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700778 return getPropertyByteArrayInternal(name, value);
779}
780
781status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
782 // This function is internal to the class and should only be called while
783 // mLock is already held.
Jeff Tinkera53d6552017-01-20 00:31:46 -0800784
785 if (mInitCheck != OK) {
786 return mInitCheck;
787 }
788
789 status_t err = UNKNOWN_ERROR;
790
791 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
792 [&](Status status, const hidl_vec<uint8_t>& hValue) {
793 if (status == Status::OK) {
794 value = toVector(hValue);
795 }
796 err = toStatusT(status);
797 }
798 );
799
800 return hResult.isOk() ? err : DEAD_OBJECT;
801}
802
803status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
804 Mutex::Autolock autoLock(mLock);
805
806 if (mInitCheck != OK) {
807 return mInitCheck;
808 }
809
810 Status status = mPlugin->setPropertyString(toHidlString(name),
811 toHidlString(value));
812 return toStatusT(status);
813}
814
815status_t DrmHal::setPropertyByteArray(String8 const &name,
816 Vector<uint8_t> const &value ) const {
817 Mutex::Autolock autoLock(mLock);
818
819 if (mInitCheck != OK) {
820 return mInitCheck;
821 }
822
823 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
824 toHidlVec(value));
825 return toStatusT(status);
826}
827
828
829status_t DrmHal::setCipherAlgorithm(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->setCipherAlgorithm(toHidlVec(sessionId),
840 toHidlString(algorithm));
841 return toStatusT(status);
842}
843
844status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
845 String8 const &algorithm) {
846 Mutex::Autolock autoLock(mLock);
847
848 if (mInitCheck != OK) {
849 return mInitCheck;
850 }
851
852 DrmSessionManager::Instance()->useSession(sessionId);
853
854 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
855 toHidlString(algorithm));
856 return toStatusT(status);
857}
858
859status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800860 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
861 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800862 Mutex::Autolock autoLock(mLock);
863
864 if (mInitCheck != OK) {
865 return mInitCheck;
866 }
867
868 DrmSessionManager::Instance()->useSession(sessionId);
869
870 status_t err = UNKNOWN_ERROR;
871
872 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
873 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
874 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
875 if (status == Status::OK) {
876 output = toVector(hOutput);
877 }
878 err = toStatusT(status);
879 }
880 );
881
882 return hResult.isOk() ? err : DEAD_OBJECT;
883}
884
885status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800886 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
887 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800888 Mutex::Autolock autoLock(mLock);
889
890 if (mInitCheck != OK) {
891 return mInitCheck;
892 }
893
894 DrmSessionManager::Instance()->useSession(sessionId);
895
896 status_t err = UNKNOWN_ERROR;
897
898 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
899 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
900 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
901 if (status == Status::OK) {
902 output = toVector(hOutput);
903 }
904 err = toStatusT(status);
905 }
906 );
907
908 return hResult.isOk() ? err : DEAD_OBJECT;
909}
910
911status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800912 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
913 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800914 Mutex::Autolock autoLock(mLock);
915
916 if (mInitCheck != OK) {
917 return mInitCheck;
918 }
919
920 DrmSessionManager::Instance()->useSession(sessionId);
921
922 status_t err = UNKNOWN_ERROR;
923
924 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
925 toHidlVec(keyId), toHidlVec(message),
926 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
927 if (status == Status::OK) {
928 signature = toVector(hSignature);
929 }
930 err = toStatusT(status);
931 }
932 );
933
934 return hResult.isOk() ? err : DEAD_OBJECT;
935}
936
937status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800938 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
939 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800940 Mutex::Autolock autoLock(mLock);
941
942 if (mInitCheck != OK) {
943 return mInitCheck;
944 }
945
946 DrmSessionManager::Instance()->useSession(sessionId);
947
948 status_t err = UNKNOWN_ERROR;
949
950 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
951 toHidlVec(message), toHidlVec(signature),
952 [&](Status status, bool hMatch) {
953 if (status == Status::OK) {
954 match = hMatch;
955 } else {
956 match = false;
957 }
958 err = toStatusT(status);
959 }
960 );
961
962 return hResult.isOk() ? err : DEAD_OBJECT;
963}
964
965status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800966 String8 const &algorithm, Vector<uint8_t> const &message,
967 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800968 Mutex::Autolock autoLock(mLock);
969
970 if (mInitCheck != OK) {
971 return mInitCheck;
972 }
973
974 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
975 return -EPERM;
976 }
977
978 DrmSessionManager::Instance()->useSession(sessionId);
979
980 status_t err = UNKNOWN_ERROR;
981
982 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
983 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
984 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
985 if (status == Status::OK) {
986 signature = toVector(hSignature);
987 }
988 err = toStatusT(status);
989 }
990 );
991
992 return hResult.isOk() ? err : DEAD_OBJECT;
993}
994
995void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
996{
Jeff Tinkera53d6552017-01-20 00:31:46 -0800997 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -0700998 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -0700999 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -07001000 if (mPlugin != NULL) {
1001 mPlugin->setListener(NULL);
1002 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001003 mPlugin.clear();
Jeff Tinker70367f52017-06-16 12:41:33 -07001004 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001005}
1006
1007void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1008{
1009 if (vec.size()) {
1010 obj.writeInt32(vec.size());
1011 obj.write(vec.data(), vec.size());
1012 } else {
1013 obj.writeInt32(0);
1014 }
1015}
1016
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001017void DrmHal::reportMetrics() const
1018{
1019 Vector<uint8_t> metrics;
1020 String8 vendor;
1021 String8 description;
1022 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1023 getPropertyStringInternal(String8("description"), description) == OK &&
1024 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1025 status_t res = android::reportDrmPluginMetrics(
1026 metrics, vendor, description);
1027 if (res != OK) {
1028 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1029 }
1030 }
1031}
1032
Jeff Tinkera53d6552017-01-20 00:31:46 -08001033} // namespace android