1 /*
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>
23
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>
27 #include <android/hidl/manager/1.0/IServiceManager.h>
28 #include <hidl/ServiceManagement.h>
29
30 #include <media/DrmHal.h>
31 #include <media/DrmSessionClientInterface.h>
32 #include <media/DrmSessionManager.h>
33 #include <media/PluginMetricsReporting.h>
34 #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
40 using ::android::hardware::drm::V1_0::EventType;
41 using ::android::hardware::drm::V1_0::IDrmFactory;
42 using ::android::hardware::drm::V1_0::IDrmPlugin;
43 using ::android::hardware::drm::V1_0::KeyedVector;
44 using ::android::hardware::drm::V1_0::KeyRequestType;
45 using ::android::hardware::drm::V1_0::KeyStatus;
46 using ::android::hardware::drm::V1_0::KeyStatusType;
47 using ::android::hardware::drm::V1_0::KeyType;
48 using ::android::hardware::drm::V1_0::KeyValue;
49 using ::android::hardware::drm::V1_0::SecureStop;
50 using ::android::hardware::drm::V1_0::Status;
51 using ::android::hardware::hidl_array;
52 using ::android::hardware::hidl_string;
53 using ::android::hardware::hidl_vec;
54 using ::android::hardware::Return;
55 using ::android::hardware::Void;
56 using ::android::hidl::manager::V1_0::IServiceManager;
57 using ::android::sp;
58
59 namespace android {
60
getCallingPid()61 static inline int getCallingPid() {
62 return IPCThreadState::self()->getCallingPid();
63 }
64
checkPermission(const char * permissionString)65 static 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
toVector(const hidl_vec<uint8_t> & vec)72 static 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
toHidlVec(const Vector<uint8_t> & vector)78 static 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
toString8(const hidl_string & string)84 static String8 toString8(const hidl_string &string) {
85 return String8(string.c_str());
86 }
87
toHidlString(const String8 & string)88 static hidl_string toHidlString(const String8& string) {
89 return hidl_string(string.string());
90 }
91
92
toHidlKeyedVector(const KeyedVector<String8,String8> & keyedVector)93 static ::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
toKeyedVector(const::KeyedVector & hKeyedVector)105 static 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
toSecureStops(const hidl_vec<SecureStop> & hSecureStops)115 static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
116 hSecureStops) {
117 List<Vector<uint8_t>> secureStops;
118 for (size_t i = 0; i < hSecureStops.size(); i++) {
119 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
120 }
121 return secureStops;
122 }
123
toStatusT(Status status)124 static 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
164 Mutex DrmHal::mLock;
165
166 struct DrmSessionClient : public DrmSessionClientInterface {
DrmSessionClientandroid::DrmSessionClient167 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
168
reclaimSessionandroid::DrmSessionClient169 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
183 protected:
~DrmSessionClientandroid::DrmSessionClient184 virtual ~DrmSessionClient() {}
185
186 private:
187 wp<DrmHal> mDrm;
188
189 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
190 };
191
DrmHal()192 DrmHal::DrmHal()
193 : mDrmSessionClient(new DrmSessionClient(this)),
194 mFactories(makeDrmFactories()),
195 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
196 }
197
closeOpenSessions()198 void 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
~DrmHal()208 DrmHal::~DrmHal() {
209 closeOpenSessions();
210 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
211 }
212
makeDrmFactories()213 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
214 Vector<sp<IDrmFactory>> factories;
215
216 auto manager = hardware::defaultServiceManager();
217
218 if (manager != NULL) {
219 manager->listByInterface(IDrmFactory::descriptor,
220 [&factories](const hidl_vec<hidl_string> ®istered) {
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 );
232 }
233
234 if (factories.size() == 0) {
235 // must be in passthrough mode, load the default passthrough service
236 auto passthrough = IDrmFactory::getService();
237 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;
245 }
246
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)247 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
248 const uint8_t uuid[16], const String8& appPackageName) {
249
250 sp<IDrmPlugin> plugin;
251 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
252 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
253 if (status != Status::OK) {
254 ALOGE("Failed to make drm plugin");
255 return;
256 }
257 plugin = hPlugin;
258 }
259 );
260
261 if (!hResult.isOk()) {
262 ALOGE("createPlugin remote call failed");
263 }
264
265 return plugin;
266 }
267
initCheck() const268 status_t DrmHal::initCheck() const {
269 return mInitCheck;
270 }
271
setListener(const sp<IDrmClient> & listener)272 status_t DrmHal::setListener(const sp<IDrmClient>& listener)
273 {
274 Mutex::Autolock lock(mEventLock);
275 if (mListener != NULL){
276 IInterface::asBinder(mListener)->unlinkToDeath(this);
277 }
278 if (listener != NULL) {
279 IInterface::asBinder(listener)->linkToDeath(this);
280 }
281 mListener = listener;
282 return NO_ERROR;
283 }
284
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)285 Return<void> DrmHal::sendEvent(EventType hEventType,
286 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
287
288 mEventLock.lock();
289 sp<IDrmClient> listener = mListener;
290 mEventLock.unlock();
291
292 if (listener != NULL) {
293 Parcel obj;
294 writeByteArray(obj, sessionId);
295 writeByteArray(obj, data);
296
297 Mutex::Autolock lock(mNotifyLock);
298 DrmPlugin::EventType eventType;
299 switch(hEventType) {
300 case EventType::PROVISION_REQUIRED:
301 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
302 break;
303 case EventType::KEY_NEEDED:
304 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
305 break;
306 case EventType::KEY_EXPIRED:
307 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
308 break;
309 case EventType::VENDOR_DEFINED:
310 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
311 break;
312 case EventType::SESSION_RECLAIMED:
313 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
314 break;
315 default:
316 return Void();
317 }
318 listener->notify(eventType, 0, &obj);
319 }
320 return Void();
321 }
322
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)323 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
324 int64_t expiryTimeInMS) {
325
326 mEventLock.lock();
327 sp<IDrmClient> listener = mListener;
328 mEventLock.unlock();
329
330 if (listener != NULL) {
331 Parcel obj;
332 writeByteArray(obj, sessionId);
333 obj.writeInt64(expiryTimeInMS);
334
335 Mutex::Autolock lock(mNotifyLock);
336 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
337 }
338 return Void();
339 }
340
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)341 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
342 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
343
344 mEventLock.lock();
345 sp<IDrmClient> listener = mListener;
346 mEventLock.unlock();
347
348 if (listener != NULL) {
349 Parcel obj;
350 writeByteArray(obj, sessionId);
351
352 size_t nKeys = keyStatusList.size();
353 obj.writeInt32(nKeys);
354 for (size_t i = 0; i < nKeys; ++i) {
355 const KeyStatus &keyStatus = keyStatusList[i];
356 writeByteArray(obj, keyStatus.keyId);
357 uint32_t type;
358 switch(keyStatus.type) {
359 case KeyStatusType::USABLE:
360 type = DrmPlugin::kKeyStatusType_Usable;
361 break;
362 case KeyStatusType::EXPIRED:
363 type = DrmPlugin::kKeyStatusType_Expired;
364 break;
365 case KeyStatusType::OUTPUTNOTALLOWED:
366 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
367 break;
368 case KeyStatusType::STATUSPENDING:
369 type = DrmPlugin::kKeyStatusType_StatusPending;
370 break;
371 case KeyStatusType::INTERNALERROR:
372 default:
373 type = DrmPlugin::kKeyStatusType_InternalError;
374 break;
375 }
376 obj.writeInt32(type);
377 }
378 obj.writeInt32(hasNewUsableKey);
379
380 Mutex::Autolock lock(mNotifyLock);
381 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
382 }
383 return Void();
384 }
385
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType)386 bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
387 Mutex::Autolock autoLock(mLock);
388
389 for (size_t i = 0; i < mFactories.size(); i++) {
390 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
391 if (mimeType != "") {
392 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
393 return true;
394 }
395 } else {
396 return true;
397 }
398 }
399 }
400 return false;
401 }
402
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)403 status_t DrmHal::createPlugin(const uint8_t uuid[16],
404 const String8& appPackageName) {
405 Mutex::Autolock autoLock(mLock);
406
407 for (size_t i = 0; i < mFactories.size(); i++) {
408 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
409 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
410 }
411 }
412
413 if (mPlugin == NULL) {
414 mInitCheck = ERROR_UNSUPPORTED;
415 } else {
416 if (!mPlugin->setListener(this).isOk()) {
417 mInitCheck = DEAD_OBJECT;
418 } else {
419 mInitCheck = OK;
420 }
421 }
422
423 return mInitCheck;
424 }
425
destroyPlugin()426 status_t DrmHal::destroyPlugin() {
427 Mutex::Autolock autoLock(mLock);
428 if (mInitCheck != OK) {
429 return mInitCheck;
430 }
431
432 closeOpenSessions();
433 reportMetrics();
434 setListener(NULL);
435 mInitCheck = NO_INIT;
436
437 if (mPlugin != NULL) {
438 if (!mPlugin->setListener(NULL).isOk()) {
439 mInitCheck = DEAD_OBJECT;
440 }
441 }
442 mPlugin.clear();
443 return OK;
444 }
445
openSession(Vector<uint8_t> & sessionId)446 status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
447 Mutex::Autolock autoLock(mLock);
448
449 if (mInitCheck != OK) {
450 return mInitCheck;
451 }
452
453 status_t err = UNKNOWN_ERROR;
454
455 bool retry = true;
456 do {
457 hidl_vec<uint8_t> hSessionId;
458
459 Return<void> hResult = mPlugin->openSession(
460 [&](Status status, const hidl_vec<uint8_t>& id) {
461 if (status == Status::OK) {
462 sessionId = toVector(id);
463 }
464 err = toStatusT(status);
465 }
466 );
467
468 if (!hResult.isOk()) {
469 err = DEAD_OBJECT;
470 }
471
472 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
473 mLock.unlock();
474 // reclaimSession may call back to closeSession, since mLock is
475 // shared between Drm instances, we should unlock here to avoid
476 // deadlock.
477 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
478 mLock.lock();
479 } else {
480 retry = false;
481 }
482 } while (retry);
483
484 if (err == OK) {
485 DrmSessionManager::Instance()->addSession(getCallingPid(),
486 mDrmSessionClient, sessionId);
487 mOpenSessions.push(sessionId);
488 }
489 return err;
490 }
491
closeSession(Vector<uint8_t> const & sessionId)492 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
493 Mutex::Autolock autoLock(mLock);
494
495 if (mInitCheck != OK) {
496 return mInitCheck;
497 }
498
499 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
500 if (status.isOk()) {
501 if (status == Status::OK) {
502 DrmSessionManager::Instance()->removeSession(sessionId);
503 for (size_t i = 0; i < mOpenSessions.size(); i++) {
504 if (mOpenSessions[i] == sessionId) {
505 mOpenSessions.removeAt(i);
506 break;
507 }
508 }
509 }
510 reportMetrics();
511 return toStatusT(status);
512 }
513 return DEAD_OBJECT;
514 }
515
getKeyRequest(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & initData,String8 const & mimeType,DrmPlugin::KeyType keyType,KeyedVector<String8,String8> const & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl,DrmPlugin::KeyRequestType * keyRequestType)516 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
517 Vector<uint8_t> const &initData, String8 const &mimeType,
518 DrmPlugin::KeyType keyType, KeyedVector<String8,
519 String8> const &optionalParameters, Vector<uint8_t> &request,
520 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
521 Mutex::Autolock autoLock(mLock);
522
523 if (mInitCheck != OK) {
524 return mInitCheck;
525 }
526
527 DrmSessionManager::Instance()->useSession(sessionId);
528
529 KeyType hKeyType;
530 if (keyType == DrmPlugin::kKeyType_Streaming) {
531 hKeyType = KeyType::STREAMING;
532 } else if (keyType == DrmPlugin::kKeyType_Offline) {
533 hKeyType = KeyType::OFFLINE;
534 } else if (keyType == DrmPlugin::kKeyType_Release) {
535 hKeyType = KeyType::RELEASE;
536 } else {
537 return BAD_VALUE;
538 }
539
540 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
541
542 status_t err = UNKNOWN_ERROR;
543
544 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
545 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
546 [&](Status status, const hidl_vec<uint8_t>& hRequest,
547 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
548
549 if (status == Status::OK) {
550 request = toVector(hRequest);
551 defaultUrl = toString8(hDefaultUrl);
552
553 switch (hKeyRequestType) {
554 case KeyRequestType::INITIAL:
555 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
556 break;
557 case KeyRequestType::RENEWAL:
558 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
559 break;
560 case KeyRequestType::RELEASE:
561 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
562 break;
563 default:
564 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
565 break;
566 }
567 err = toStatusT(status);
568 }
569 });
570
571 return hResult.isOk() ? err : DEAD_OBJECT;
572 }
573
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)574 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
575 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
576 Mutex::Autolock autoLock(mLock);
577
578 if (mInitCheck != OK) {
579 return mInitCheck;
580 }
581
582 DrmSessionManager::Instance()->useSession(sessionId);
583
584 status_t err = UNKNOWN_ERROR;
585
586 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
587 toHidlVec(response),
588 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
589 if (status == Status::OK) {
590 keySetId = toVector(hKeySetId);
591 }
592 err = toStatusT(status);
593 }
594 );
595
596 return hResult.isOk() ? err : DEAD_OBJECT;
597 }
598
removeKeys(Vector<uint8_t> const & keySetId)599 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
600 Mutex::Autolock autoLock(mLock);
601
602 if (mInitCheck != OK) {
603 return mInitCheck;
604 }
605
606 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
607 }
608
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)609 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
610 Vector<uint8_t> const &keySetId) {
611 Mutex::Autolock autoLock(mLock);
612
613 if (mInitCheck != OK) {
614 return mInitCheck;
615 }
616
617 DrmSessionManager::Instance()->useSession(sessionId);
618
619 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
620 toHidlVec(keySetId)));
621 }
622
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const623 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
624 KeyedVector<String8, String8> &infoMap) const {
625 Mutex::Autolock autoLock(mLock);
626
627 if (mInitCheck != OK) {
628 return mInitCheck;
629 }
630
631 DrmSessionManager::Instance()->useSession(sessionId);
632
633 ::KeyedVector hInfoMap;
634
635 status_t err = UNKNOWN_ERROR;
636
637 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
638 [&](Status status, const hidl_vec<KeyValue>& map) {
639 if (status == Status::OK) {
640 infoMap = toKeyedVector(map);
641 }
642 err = toStatusT(status);
643 }
644 );
645
646 return hResult.isOk() ? err : DEAD_OBJECT;
647 }
648
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)649 status_t DrmHal::getProvisionRequest(String8 const &certType,
650 String8 const &certAuthority, Vector<uint8_t> &request,
651 String8 &defaultUrl) {
652 Mutex::Autolock autoLock(mLock);
653
654 if (mInitCheck != OK) {
655 return mInitCheck;
656 }
657
658 status_t err = UNKNOWN_ERROR;
659
660 Return<void> hResult = mPlugin->getProvisionRequest(
661 toHidlString(certType), toHidlString(certAuthority),
662 [&](Status status, const hidl_vec<uint8_t>& hRequest,
663 const hidl_string& hDefaultUrl) {
664 if (status == Status::OK) {
665 request = toVector(hRequest);
666 defaultUrl = toString8(hDefaultUrl);
667 }
668 err = toStatusT(status);
669 }
670 );
671
672 return hResult.isOk() ? err : DEAD_OBJECT;
673 }
674
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)675 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
676 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
677 Mutex::Autolock autoLock(mLock);
678
679 if (mInitCheck != OK) {
680 return mInitCheck;
681 }
682
683 status_t err = UNKNOWN_ERROR;
684
685 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
686 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
687 const hidl_vec<uint8_t>& hWrappedKey) {
688 if (status == Status::OK) {
689 certificate = toVector(hCertificate);
690 wrappedKey = toVector(hWrappedKey);
691 }
692 err = toStatusT(status);
693 }
694 );
695
696 return hResult.isOk() ? err : DEAD_OBJECT;
697 }
698
getSecureStops(List<Vector<uint8_t>> & secureStops)699 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
700 Mutex::Autolock autoLock(mLock);
701
702 if (mInitCheck != OK) {
703 return mInitCheck;
704 }
705
706 status_t err = UNKNOWN_ERROR;
707
708 Return<void> hResult = mPlugin->getSecureStops(
709 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
710 if (status == Status::OK) {
711 secureStops = toSecureStops(hSecureStops);
712 }
713 err = toStatusT(status);
714 }
715 );
716
717 return hResult.isOk() ? err : DEAD_OBJECT;
718 }
719
720
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)721 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
722 Mutex::Autolock autoLock(mLock);
723
724 if (mInitCheck != OK) {
725 return mInitCheck;
726 }
727
728 status_t err = UNKNOWN_ERROR;
729
730 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
731 [&](Status status, const SecureStop& hSecureStop) {
732 if (status == Status::OK) {
733 secureStop = toVector(hSecureStop.opaqueData);
734 }
735 err = toStatusT(status);
736 }
737 );
738
739 return hResult.isOk() ? err : DEAD_OBJECT;
740 }
741
releaseSecureStops(Vector<uint8_t> const & ssRelease)742 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
743 Mutex::Autolock autoLock(mLock);
744
745 if (mInitCheck != OK) {
746 return mInitCheck;
747 }
748
749 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
750 }
751
releaseAllSecureStops()752 status_t DrmHal::releaseAllSecureStops() {
753 Mutex::Autolock autoLock(mLock);
754
755 if (mInitCheck != OK) {
756 return mInitCheck;
757 }
758
759 return toStatusT(mPlugin->releaseAllSecureStops());
760 }
761
getPropertyString(String8 const & name,String8 & value) const762 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
763 Mutex::Autolock autoLock(mLock);
764 return getPropertyStringInternal(name, value);
765 }
766
getPropertyStringInternal(String8 const & name,String8 & value) const767 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
768 // This function is internal to the class and should only be called while
769 // mLock is already held.
770
771 if (mInitCheck != OK) {
772 return mInitCheck;
773 }
774
775 status_t err = UNKNOWN_ERROR;
776
777 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
778 [&](Status status, const hidl_string& hValue) {
779 if (status == Status::OK) {
780 value = toString8(hValue);
781 }
782 err = toStatusT(status);
783 }
784 );
785
786 return hResult.isOk() ? err : DEAD_OBJECT;
787 }
788
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const789 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
790 Mutex::Autolock autoLock(mLock);
791 return getPropertyByteArrayInternal(name, value);
792 }
793
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const794 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
795 // This function is internal to the class and should only be called while
796 // mLock is already held.
797
798 if (mInitCheck != OK) {
799 return mInitCheck;
800 }
801
802 status_t err = UNKNOWN_ERROR;
803
804 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
805 [&](Status status, const hidl_vec<uint8_t>& hValue) {
806 if (status == Status::OK) {
807 value = toVector(hValue);
808 }
809 err = toStatusT(status);
810 }
811 );
812
813 return hResult.isOk() ? err : DEAD_OBJECT;
814 }
815
setPropertyString(String8 const & name,String8 const & value) const816 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
817 Mutex::Autolock autoLock(mLock);
818
819 if (mInitCheck != OK) {
820 return mInitCheck;
821 }
822
823 Status status = mPlugin->setPropertyString(toHidlString(name),
824 toHidlString(value));
825 return toStatusT(status);
826 }
827
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const828 status_t DrmHal::setPropertyByteArray(String8 const &name,
829 Vector<uint8_t> const &value ) const {
830 Mutex::Autolock autoLock(mLock);
831
832 if (mInitCheck != OK) {
833 return mInitCheck;
834 }
835
836 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
837 toHidlVec(value));
838 return toStatusT(status);
839 }
840
841
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)842 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
843 String8 const &algorithm) {
844 Mutex::Autolock autoLock(mLock);
845
846 if (mInitCheck != OK) {
847 return mInitCheck;
848 }
849
850 DrmSessionManager::Instance()->useSession(sessionId);
851
852 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
853 toHidlString(algorithm));
854 return toStatusT(status);
855 }
856
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)857 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
858 String8 const &algorithm) {
859 Mutex::Autolock autoLock(mLock);
860
861 if (mInitCheck != OK) {
862 return mInitCheck;
863 }
864
865 DrmSessionManager::Instance()->useSession(sessionId);
866
867 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
868 toHidlString(algorithm));
869 return toStatusT(status);
870 }
871
encrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)872 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
873 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
874 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
875 Mutex::Autolock autoLock(mLock);
876
877 if (mInitCheck != OK) {
878 return mInitCheck;
879 }
880
881 DrmSessionManager::Instance()->useSession(sessionId);
882
883 status_t err = UNKNOWN_ERROR;
884
885 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
886 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
887 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
888 if (status == Status::OK) {
889 output = toVector(hOutput);
890 }
891 err = toStatusT(status);
892 }
893 );
894
895 return hResult.isOk() ? err : DEAD_OBJECT;
896 }
897
decrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)898 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
899 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
900 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
901 Mutex::Autolock autoLock(mLock);
902
903 if (mInitCheck != OK) {
904 return mInitCheck;
905 }
906
907 DrmSessionManager::Instance()->useSession(sessionId);
908
909 status_t err = UNKNOWN_ERROR;
910
911 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
912 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
913 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
914 if (status == Status::OK) {
915 output = toVector(hOutput);
916 }
917 err = toStatusT(status);
918 }
919 );
920
921 return hResult.isOk() ? err : DEAD_OBJECT;
922 }
923
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)924 status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
925 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
926 Vector<uint8_t> &signature) {
927 Mutex::Autolock autoLock(mLock);
928
929 if (mInitCheck != OK) {
930 return mInitCheck;
931 }
932
933 DrmSessionManager::Instance()->useSession(sessionId);
934
935 status_t err = UNKNOWN_ERROR;
936
937 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
938 toHidlVec(keyId), toHidlVec(message),
939 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
940 if (status == Status::OK) {
941 signature = toVector(hSignature);
942 }
943 err = toStatusT(status);
944 }
945 );
946
947 return hResult.isOk() ? err : DEAD_OBJECT;
948 }
949
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)950 status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
951 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
952 Vector<uint8_t> const &signature, bool &match) {
953 Mutex::Autolock autoLock(mLock);
954
955 if (mInitCheck != OK) {
956 return mInitCheck;
957 }
958
959 DrmSessionManager::Instance()->useSession(sessionId);
960
961 status_t err = UNKNOWN_ERROR;
962
963 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
964 toHidlVec(message), toHidlVec(signature),
965 [&](Status status, bool hMatch) {
966 if (status == Status::OK) {
967 match = hMatch;
968 } else {
969 match = false;
970 }
971 err = toStatusT(status);
972 }
973 );
974
975 return hResult.isOk() ? err : DEAD_OBJECT;
976 }
977
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)978 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
979 String8 const &algorithm, Vector<uint8_t> const &message,
980 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
981 Mutex::Autolock autoLock(mLock);
982
983 if (mInitCheck != OK) {
984 return mInitCheck;
985 }
986
987 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
988 return -EPERM;
989 }
990
991 DrmSessionManager::Instance()->useSession(sessionId);
992
993 status_t err = UNKNOWN_ERROR;
994
995 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
996 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
997 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
998 if (status == Status::OK) {
999 signature = toVector(hSignature);
1000 }
1001 err = toStatusT(status);
1002 }
1003 );
1004
1005 return hResult.isOk() ? err : DEAD_OBJECT;
1006 }
1007
binderDied(const wp<IBinder> & the_late_who __unused)1008 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1009 {
1010 Mutex::Autolock autoLock(mLock);
1011 closeOpenSessions();
1012 setListener(NULL);
1013 mInitCheck = NO_INIT;
1014
1015 if (mPlugin != NULL) {
1016 if (!mPlugin->setListener(NULL).isOk()) {
1017 mInitCheck = DEAD_OBJECT;
1018 }
1019 }
1020 mPlugin.clear();
1021 }
1022
writeByteArray(Parcel & obj,hidl_vec<uint8_t> const & vec)1023 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1024 {
1025 if (vec.size()) {
1026 obj.writeInt32(vec.size());
1027 obj.write(vec.data(), vec.size());
1028 } else {
1029 obj.writeInt32(0);
1030 }
1031 }
1032
reportMetrics() const1033 void DrmHal::reportMetrics() const
1034 {
1035 Vector<uint8_t> metrics;
1036 String8 vendor;
1037 String8 description;
1038 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1039 getPropertyStringInternal(String8("description"), description) == OK &&
1040 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1041 status_t res = android::reportDrmPluginMetrics(
1042 metrics, vendor, description);
1043 if (res != OK) {
1044 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1045 }
1046 }
1047 }
1048
1049 } // namespace android
1050