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 <iomanip>
20
21 #include <utils/Log.h>
22
23 #include <binder/IPCThreadState.h>
24 #include <binder/IServiceManager.h>
25
26 #include <android/hardware/drm/1.2/types.h>
27 #include <android/hidl/manager/1.2/IServiceManager.h>
28 #include <hidl/ServiceManagement.h>
29
30 #include <media/EventMetric.h>
31 #include <media/PluginMetricsReporting.h>
32 #include <media/drm/DrmAPI.h>
33 #include <media/stagefright/foundation/ADebug.h>
34 #include <media/stagefright/foundation/AString.h>
35 #include <media/stagefright/foundation/base64.h>
36 #include <media/stagefright/foundation/hexdump.h>
37 #include <media/stagefright/MediaErrors.h>
38 #include <mediadrm/DrmHal.h>
39 #include <mediadrm/DrmSessionClientInterface.h>
40 #include <mediadrm/DrmSessionManager.h>
41
42 using drm::V1_0::KeyedVector;
43 using drm::V1_0::KeyRequestType;
44 using drm::V1_0::KeyType;
45 using drm::V1_0::KeyValue;
46 using drm::V1_0::SecureStop;
47 using drm::V1_0::SecureStopId;
48 using drm::V1_0::Status;
49 using drm::V1_1::HdcpLevel;
50 using drm::V1_1::SecureStopRelease;
51 using drm::V1_1::SecurityLevel;
52 using drm::V1_2::KeySetId;
53 using drm::V1_2::KeyStatusType;
54 using ::android::hardware::drm::V1_1::DrmMetricGroup;
55 using ::android::hardware::hidl_array;
56 using ::android::hardware::hidl_string;
57 using ::android::hardware::hidl_vec;
58 using ::android::hardware::Return;
59 using ::android::hardware::Void;
60 using ::android::hidl::manager::V1_0::IServiceManager;
61 using ::android::os::PersistableBundle;
62 using ::android::sp;
63
64 typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
65 typedef drm::V1_2::Status Status_V1_2;
66 typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
67
68 namespace {
69
70 // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
71 // in the MediaDrm API.
72 constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
73 constexpr char kEqualsSign[] = "=";
74
75 template<typename T>
toBase64StringNoPad(const T * data,size_t size)76 std::string toBase64StringNoPad(const T* data, size_t size) {
77 // Note that the base 64 conversion only works with arrays of single-byte
78 // values. If the source is empty or is not an array of single-byte values,
79 // return empty string.
80 if (size == 0 || sizeof(data[0]) != 1) {
81 return "";
82 }
83
84 android::AString outputString;
85 encodeBase64(data, size, &outputString);
86 // Remove trailing equals padding if it exists.
87 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
88 outputString.erase(outputString.size() - 1, 1);
89 }
90
91 return std::string(outputString.c_str(), outputString.size());
92 }
93
94 } // anonymous namespace
95
96 namespace android {
97
98 #define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
99
getCallingPid()100 static inline int getCallingPid() {
101 return IPCThreadState::self()->getCallingPid();
102 }
103
checkPermission(const char * permissionString)104 static bool checkPermission(const char* permissionString) {
105 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
106 bool ok = checkCallingPermission(String16(permissionString));
107 if (!ok) ALOGE("Request requires %s", permissionString);
108 return ok;
109 }
110
toVector(const hidl_vec<uint8_t> & vec)111 static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
112 Vector<uint8_t> vector;
113 vector.appendArray(vec.data(), vec.size());
114 return *const_cast<const Vector<uint8_t> *>(&vector);
115 }
116
toHidlVec(const Vector<uint8_t> & vector)117 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
118 hidl_vec<uint8_t> vec;
119 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
120 return vec;
121 }
122
toString8(const hidl_string & string)123 static String8 toString8(const hidl_string &string) {
124 return String8(string.c_str());
125 }
126
toHidlString(const String8 & string)127 static hidl_string toHidlString(const String8& string) {
128 return hidl_string(string.string());
129 }
130
toSecurityLevel(SecurityLevel level)131 static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
132 switch(level) {
133 case SecurityLevel::SW_SECURE_CRYPTO:
134 return DrmPlugin::kSecurityLevelSwSecureCrypto;
135 case SecurityLevel::SW_SECURE_DECODE:
136 return DrmPlugin::kSecurityLevelSwSecureDecode;
137 case SecurityLevel::HW_SECURE_CRYPTO:
138 return DrmPlugin::kSecurityLevelHwSecureCrypto;
139 case SecurityLevel::HW_SECURE_DECODE:
140 return DrmPlugin::kSecurityLevelHwSecureDecode;
141 case SecurityLevel::HW_SECURE_ALL:
142 return DrmPlugin::kSecurityLevelHwSecureAll;
143 default:
144 return DrmPlugin::kSecurityLevelUnknown;
145 }
146 }
147
toHidlSecurityLevel(DrmPlugin::SecurityLevel level)148 static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
149 switch(level) {
150 case DrmPlugin::kSecurityLevelSwSecureCrypto:
151 return SecurityLevel::SW_SECURE_CRYPTO;
152 case DrmPlugin::kSecurityLevelSwSecureDecode:
153 return SecurityLevel::SW_SECURE_DECODE;
154 case DrmPlugin::kSecurityLevelHwSecureCrypto:
155 return SecurityLevel::HW_SECURE_CRYPTO;
156 case DrmPlugin::kSecurityLevelHwSecureDecode:
157 return SecurityLevel::HW_SECURE_DECODE;
158 case DrmPlugin::kSecurityLevelHwSecureAll:
159 return SecurityLevel::HW_SECURE_ALL;
160 default:
161 return SecurityLevel::UNKNOWN;
162 }
163 }
164
toOfflineLicenseState(OfflineLicenseState licenseState)165 static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
166 OfflineLicenseState licenseState) {
167 switch(licenseState) {
168 case OfflineLicenseState::USABLE:
169 return DrmPlugin::kOfflineLicenseStateUsable;
170 case OfflineLicenseState::INACTIVE:
171 return DrmPlugin::kOfflineLicenseStateReleased;
172 default:
173 return DrmPlugin::kOfflineLicenseStateUnknown;
174 }
175 }
176
toHdcpLevel(HdcpLevel_V1_2 level)177 static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
178 switch(level) {
179 case HdcpLevel_V1_2::HDCP_NONE:
180 return DrmPlugin::kHdcpNone;
181 case HdcpLevel_V1_2::HDCP_V1:
182 return DrmPlugin::kHdcpV1;
183 case HdcpLevel_V1_2::HDCP_V2:
184 return DrmPlugin::kHdcpV2;
185 case HdcpLevel_V1_2::HDCP_V2_1:
186 return DrmPlugin::kHdcpV2_1;
187 case HdcpLevel_V1_2::HDCP_V2_2:
188 return DrmPlugin::kHdcpV2_2;
189 case HdcpLevel_V1_2::HDCP_V2_3:
190 return DrmPlugin::kHdcpV2_3;
191 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
192 return DrmPlugin::kHdcpNoOutput;
193 default:
194 return DrmPlugin::kHdcpLevelUnknown;
195 }
196 }
toHidlKeyedVector(const KeyedVector<String8,String8> & keyedVector)197 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
198 keyedVector) {
199 std::vector<KeyValue> stdKeyedVector;
200 for (size_t i = 0; i < keyedVector.size(); i++) {
201 KeyValue keyValue;
202 keyValue.key = toHidlString(keyedVector.keyAt(i));
203 keyValue.value = toHidlString(keyedVector.valueAt(i));
204 stdKeyedVector.push_back(keyValue);
205 }
206 return ::KeyedVector(stdKeyedVector);
207 }
208
toKeyedVector(const::KeyedVector & hKeyedVector)209 static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
210 hKeyedVector) {
211 KeyedVector<String8, String8> keyedVector;
212 for (size_t i = 0; i < hKeyedVector.size(); i++) {
213 keyedVector.add(toString8(hKeyedVector[i].key),
214 toString8(hKeyedVector[i].value));
215 }
216 return keyedVector;
217 }
218
toSecureStops(const hidl_vec<SecureStop> & hSecureStops)219 static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
220 hSecureStops) {
221 List<Vector<uint8_t>> secureStops;
222 for (size_t i = 0; i < hSecureStops.size(); i++) {
223 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
224 }
225 return secureStops;
226 }
227
toSecureStopIds(const hidl_vec<SecureStopId> & hSecureStopIds)228 static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
229 hSecureStopIds) {
230 List<Vector<uint8_t>> secureStopIds;
231 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
232 secureStopIds.push_back(toVector(hSecureStopIds[i]));
233 }
234 return secureStopIds;
235 }
236
toKeySetIds(const hidl_vec<KeySetId> & hKeySetIds)237 static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
238 hKeySetIds) {
239 List<Vector<uint8_t>> keySetIds;
240 for (size_t i = 0; i < hKeySetIds.size(); i++) {
241 keySetIds.push_back(toVector(hKeySetIds[i]));
242 }
243 return keySetIds;
244 }
245
toStatusT(Status status)246 static status_t toStatusT(Status status) {
247 switch (status) {
248 case Status::OK:
249 return OK;
250 break;
251 case Status::ERROR_DRM_NO_LICENSE:
252 return ERROR_DRM_NO_LICENSE;
253 break;
254 case Status::ERROR_DRM_LICENSE_EXPIRED:
255 return ERROR_DRM_LICENSE_EXPIRED;
256 break;
257 case Status::ERROR_DRM_SESSION_NOT_OPENED:
258 return ERROR_DRM_SESSION_NOT_OPENED;
259 break;
260 case Status::ERROR_DRM_CANNOT_HANDLE:
261 return ERROR_DRM_CANNOT_HANDLE;
262 break;
263 case Status::ERROR_DRM_INVALID_STATE:
264 return ERROR_DRM_INVALID_STATE;
265 break;
266 case Status::BAD_VALUE:
267 return BAD_VALUE;
268 break;
269 case Status::ERROR_DRM_NOT_PROVISIONED:
270 return ERROR_DRM_NOT_PROVISIONED;
271 break;
272 case Status::ERROR_DRM_RESOURCE_BUSY:
273 return ERROR_DRM_RESOURCE_BUSY;
274 break;
275 case Status::ERROR_DRM_DEVICE_REVOKED:
276 return ERROR_DRM_DEVICE_REVOKED;
277 break;
278 case Status::ERROR_DRM_UNKNOWN:
279 default:
280 return ERROR_DRM_UNKNOWN;
281 break;
282 }
283 }
284
toStatusT_1_2(Status_V1_2 status)285 static status_t toStatusT_1_2(Status_V1_2 status) {
286 switch (status) {
287 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
288 return ERROR_DRM_RESOURCE_CONTENTION;
289 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
290 return ERROR_DRM_FRAME_TOO_LARGE;
291 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
292 return ERROR_DRM_INSUFFICIENT_SECURITY;
293 default:
294 return toStatusT(static_cast<Status>(status));
295 }
296 }
297
298
299 Mutex DrmHal::mLock;
300
301 struct DrmSessionClient : public DrmSessionClientInterface {
DrmSessionClientandroid::DrmSessionClient302 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
303
reclaimSessionandroid::DrmSessionClient304 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
305 sp<DrmHal> drm = mDrm.promote();
306 if (drm == NULL) {
307 return true;
308 }
309 status_t err = drm->closeSession(sessionId);
310 if (err != OK) {
311 return false;
312 }
313 drm->sendEvent(EventType::SESSION_RECLAIMED,
314 toHidlVec(sessionId), hidl_vec<uint8_t>());
315 return true;
316 }
317
318 protected:
~DrmSessionClientandroid::DrmSessionClient319 virtual ~DrmSessionClient() {}
320
321 private:
322 wp<DrmHal> mDrm;
323
324 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
325 };
326
DrmHal()327 DrmHal::DrmHal()
328 : mDrmSessionClient(new DrmSessionClient(this)),
329 mFactories(makeDrmFactories()),
330 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
331 }
332
closeOpenSessions()333 void DrmHal::closeOpenSessions() {
334 Mutex::Autolock autoLock(mLock);
335 auto openSessions = mOpenSessions;
336 for (size_t i = 0; i < openSessions.size(); i++) {
337 mLock.unlock();
338 closeSession(openSessions[i]);
339 mLock.lock();
340 }
341 mOpenSessions.clear();
342 }
343
~DrmHal()344 DrmHal::~DrmHal() {
345 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
346 }
347
cleanup()348 void DrmHal::cleanup() {
349 closeOpenSessions();
350
351 Mutex::Autolock autoLock(mLock);
352 reportPluginMetrics();
353 reportFrameworkMetrics();
354
355 setListener(NULL);
356 mInitCheck = NO_INIT;
357 if (mPluginV1_2 != NULL) {
358 if (!mPluginV1_2->setListener(NULL).isOk()) {
359 mInitCheck = DEAD_OBJECT;
360 }
361 } else if (mPlugin != NULL) {
362 if (!mPlugin->setListener(NULL).isOk()) {
363 mInitCheck = DEAD_OBJECT;
364 }
365 }
366 mPlugin.clear();
367 mPluginV1_1.clear();
368 mPluginV1_2.clear();
369 }
370
makeDrmFactories()371 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
372 Vector<sp<IDrmFactory>> factories;
373
374 auto manager = hardware::defaultServiceManager1_2();
375
376 if (manager != NULL) {
377 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
378 [&factories](const hidl_vec<hidl_string> ®istered) {
379 for (const auto &instance : registered) {
380 auto factory = drm::V1_0::IDrmFactory::getService(instance);
381 if (factory != NULL) {
382 factories.push_back(factory);
383 }
384 }
385 }
386 );
387 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
388 [&factories](const hidl_vec<hidl_string> ®istered) {
389 for (const auto &instance : registered) {
390 auto factory = drm::V1_1::IDrmFactory::getService(instance);
391 if (factory != NULL) {
392 factories.push_back(factory);
393 }
394 }
395 }
396 );
397 manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
398 [&factories](const hidl_vec<hidl_string> ®istered) {
399 for (const auto &instance : registered) {
400 auto factory = drm::V1_2::IDrmFactory::getService(instance);
401 if (factory != NULL) {
402 factories.push_back(factory);
403 }
404 }
405 }
406 );
407 }
408
409 if (factories.size() == 0) {
410 // must be in passthrough mode, load the default passthrough service
411 auto passthrough = IDrmFactory::getService();
412 if (passthrough != NULL) {
413 ALOGI("makeDrmFactories: using default passthrough drm instance");
414 factories.push_back(passthrough);
415 } else {
416 ALOGE("Failed to find any drm factories");
417 }
418 }
419 return factories;
420 }
421
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)422 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
423 const uint8_t uuid[16], const String8& appPackageName) {
424 mAppPackageName = appPackageName;
425 mMetrics.SetAppPackageName(appPackageName);
426
427 sp<IDrmPlugin> plugin;
428 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
429 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
430 if (status != Status::OK) {
431 ALOGE("Failed to make drm plugin");
432 return;
433 }
434 plugin = hPlugin;
435 }
436 );
437
438 if (!hResult.isOk()) {
439 ALOGE("createPlugin remote call failed");
440 }
441
442 return plugin;
443 }
444
initCheck() const445 status_t DrmHal::initCheck() const {
446 return mInitCheck;
447 }
448
setListener(const sp<IDrmClient> & listener)449 status_t DrmHal::setListener(const sp<IDrmClient>& listener)
450 {
451 Mutex::Autolock lock(mEventLock);
452 if (mListener != NULL){
453 IInterface::asBinder(mListener)->unlinkToDeath(this);
454 }
455 if (listener != NULL) {
456 IInterface::asBinder(listener)->linkToDeath(this);
457 }
458 mListener = listener;
459 return NO_ERROR;
460 }
461
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)462 Return<void> DrmHal::sendEvent(EventType hEventType,
463 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
464 mMetrics.mEventCounter.Increment(hEventType);
465
466 mEventLock.lock();
467 sp<IDrmClient> listener = mListener;
468 mEventLock.unlock();
469
470 if (listener != NULL) {
471 Parcel obj;
472 writeByteArray(obj, sessionId);
473 writeByteArray(obj, data);
474
475 Mutex::Autolock lock(mNotifyLock);
476 DrmPlugin::EventType eventType;
477 switch(hEventType) {
478 case EventType::PROVISION_REQUIRED:
479 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
480 break;
481 case EventType::KEY_NEEDED:
482 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
483 break;
484 case EventType::KEY_EXPIRED:
485 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
486 break;
487 case EventType::VENDOR_DEFINED:
488 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
489 break;
490 case EventType::SESSION_RECLAIMED:
491 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
492 break;
493 default:
494 return Void();
495 }
496 listener->notify(eventType, 0, &obj);
497 }
498 return Void();
499 }
500
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)501 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
502 int64_t expiryTimeInMS) {
503
504 mEventLock.lock();
505 sp<IDrmClient> listener = mListener;
506 mEventLock.unlock();
507
508 if (listener != NULL) {
509 Parcel obj;
510 writeByteArray(obj, sessionId);
511 obj.writeInt64(expiryTimeInMS);
512
513 Mutex::Autolock lock(mNotifyLock);
514 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
515 }
516 return Void();
517 }
518
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus_V1_0> & keyStatusList_V1_0,bool hasNewUsableKey)519 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
520 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
521 std::vector<KeyStatus> keyStatusVec;
522 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
523 keyStatusVec.push_back({keyStatus_V1_0.keyId,
524 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
525 }
526 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
527 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
528 }
529
sendKeysChange_1_2(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)530 Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
531 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
532
533 mEventLock.lock();
534 sp<IDrmClient> listener = mListener;
535 mEventLock.unlock();
536
537 if (listener != NULL) {
538 Parcel obj;
539 writeByteArray(obj, sessionId);
540
541 size_t nKeys = keyStatusList.size();
542 obj.writeInt32(nKeys);
543 for (size_t i = 0; i < nKeys; ++i) {
544 const KeyStatus &keyStatus = keyStatusList[i];
545 writeByteArray(obj, keyStatus.keyId);
546 uint32_t type;
547 switch(keyStatus.type) {
548 case KeyStatusType::USABLE:
549 type = DrmPlugin::kKeyStatusType_Usable;
550 break;
551 case KeyStatusType::EXPIRED:
552 type = DrmPlugin::kKeyStatusType_Expired;
553 break;
554 case KeyStatusType::OUTPUTNOTALLOWED:
555 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
556 break;
557 case KeyStatusType::STATUSPENDING:
558 type = DrmPlugin::kKeyStatusType_StatusPending;
559 break;
560 case KeyStatusType::USABLEINFUTURE:
561 type = DrmPlugin::kKeyStatusType_UsableInFuture;
562 break;
563 case KeyStatusType::INTERNALERROR:
564 default:
565 type = DrmPlugin::kKeyStatusType_InternalError;
566 break;
567 }
568 obj.writeInt32(type);
569 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
570 }
571 obj.writeInt32(hasNewUsableKey);
572
573 Mutex::Autolock lock(mNotifyLock);
574 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
575 } else {
576 // There's no listener. But we still want to count the key change
577 // events.
578 size_t nKeys = keyStatusList.size();
579 for (size_t i = 0; i < nKeys; i++) {
580 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
581 }
582 }
583
584 return Void();
585 }
586
sendSessionLostState(const hidl_vec<uint8_t> & sessionId)587 Return<void> DrmHal::sendSessionLostState(
588 const hidl_vec<uint8_t>& sessionId) {
589
590 mEventLock.lock();
591 sp<IDrmClient> listener = mListener;
592 mEventLock.unlock();
593
594 if (listener != NULL) {
595 Parcel obj;
596 writeByteArray(obj, sessionId);
597 Mutex::Autolock lock(mNotifyLock);
598 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
599 }
600 return Void();
601 }
602
matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)603 status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
604 const uint8_t uuid[16],
605 const String8 &mimeType,
606 DrmPlugin::SecurityLevel level,
607 bool *isSupported) {
608 *isSupported = false;
609
610 // handle default value cases
611 if (level == DrmPlugin::kSecurityLevelUnknown) {
612 if (mimeType == "") {
613 // isCryptoSchemeSupported(uuid)
614 *isSupported = true;
615 } else {
616 // isCryptoSchemeSupported(uuid, mimeType)
617 *isSupported = factory->isContentTypeSupported(mimeType.string());
618 }
619 return OK;
620 } else if (mimeType == "") {
621 return BAD_VALUE;
622 }
623
624 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
625 if (factoryV1_2 == NULL) {
626 return ERROR_UNSUPPORTED;
627 } else {
628 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
629 mimeType.string(), toHidlSecurityLevel(level));
630 return OK;
631 }
632 }
633
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)634 status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
635 const String8 &mimeType,
636 DrmPlugin::SecurityLevel level,
637 bool *isSupported) {
638 Mutex::Autolock autoLock(mLock);
639 *isSupported = false;
640 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
641 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
642 return matchMimeTypeAndSecurityLevel(mFactories[i],
643 uuid, mimeType, level, isSupported);
644 }
645 }
646 return OK;
647 }
648
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)649 status_t DrmHal::createPlugin(const uint8_t uuid[16],
650 const String8& appPackageName) {
651 Mutex::Autolock autoLock(mLock);
652
653 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
654 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
655 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
656 if (plugin != NULL) {
657 mPlugin = plugin;
658 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
659 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
660 break;
661 }
662 }
663 }
664
665 if (mPlugin == NULL) {
666 mInitCheck = ERROR_UNSUPPORTED;
667 } else {
668 mInitCheck = OK;
669 if (mPluginV1_2 != NULL) {
670 if (!mPluginV1_2->setListener(this).isOk()) {
671 mInitCheck = DEAD_OBJECT;
672 }
673 } else if (!mPlugin->setListener(this).isOk()) {
674 mInitCheck = DEAD_OBJECT;
675 }
676 if (mInitCheck != OK) {
677 mPlugin.clear();
678 mPluginV1_1.clear();
679 mPluginV1_2.clear();
680 }
681 }
682
683
684 return mInitCheck;
685 }
686
destroyPlugin()687 status_t DrmHal::destroyPlugin() {
688 cleanup();
689 return OK;
690 }
691
openSession(DrmPlugin::SecurityLevel level,Vector<uint8_t> & sessionId)692 status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
693 Vector<uint8_t> &sessionId) {
694 Mutex::Autolock autoLock(mLock);
695 INIT_CHECK();
696
697 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
698 bool setSecurityLevel = true;
699
700 if (level == DrmPlugin::kSecurityLevelMax) {
701 setSecurityLevel = false;
702 } else {
703 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
704 return ERROR_DRM_CANNOT_HANDLE;
705 }
706 }
707
708 status_t err = UNKNOWN_ERROR;
709 bool retry = true;
710 do {
711 hidl_vec<uint8_t> hSessionId;
712
713 Return<void> hResult;
714 if (mPluginV1_1 == NULL || !setSecurityLevel) {
715 hResult = mPlugin->openSession(
716 [&](Status status,const hidl_vec<uint8_t>& id) {
717 if (status == Status::OK) {
718 sessionId = toVector(id);
719 }
720 err = toStatusT(status);
721 }
722 );
723 } else {
724 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
725 [&](Status status, const hidl_vec<uint8_t>& id) {
726 if (status == Status::OK) {
727 sessionId = toVector(id);
728 }
729 err = toStatusT(status);
730 }
731 );
732 }
733
734 if (!hResult.isOk()) {
735 err = DEAD_OBJECT;
736 }
737
738 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
739 mLock.unlock();
740 // reclaimSession may call back to closeSession, since mLock is
741 // shared between Drm instances, we should unlock here to avoid
742 // deadlock.
743 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
744 mLock.lock();
745 } else {
746 retry = false;
747 }
748 } while (retry);
749
750 if (err == OK) {
751 DrmSessionManager::Instance()->addSession(getCallingPid(),
752 mDrmSessionClient, sessionId);
753 mOpenSessions.push(sessionId);
754 mMetrics.SetSessionStart(sessionId);
755 }
756
757 mMetrics.mOpenSessionCounter.Increment(err);
758 return err;
759 }
760
closeSession(Vector<uint8_t> const & sessionId)761 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
762 Mutex::Autolock autoLock(mLock);
763 INIT_CHECK();
764
765 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
766 if (status.isOk()) {
767 if (status == Status::OK) {
768 DrmSessionManager::Instance()->removeSession(sessionId);
769 for (size_t i = 0; i < mOpenSessions.size(); i++) {
770 if (mOpenSessions[i] == sessionId) {
771 mOpenSessions.removeAt(i);
772 break;
773 }
774 }
775 }
776 status_t response = toStatusT(status);
777 mMetrics.SetSessionEnd(sessionId);
778 mMetrics.mCloseSessionCounter.Increment(response);
779 return response;
780 }
781 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
782 return DEAD_OBJECT;
783 }
784
toKeyRequestType(KeyRequestType keyRequestType)785 static DrmPlugin::KeyRequestType toKeyRequestType(
786 KeyRequestType keyRequestType) {
787 switch (keyRequestType) {
788 case KeyRequestType::INITIAL:
789 return DrmPlugin::kKeyRequestType_Initial;
790 break;
791 case KeyRequestType::RENEWAL:
792 return DrmPlugin::kKeyRequestType_Renewal;
793 break;
794 case KeyRequestType::RELEASE:
795 return DrmPlugin::kKeyRequestType_Release;
796 break;
797 default:
798 return DrmPlugin::kKeyRequestType_Unknown;
799 break;
800 }
801 }
802
toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType)803 static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
804 KeyRequestType_V1_1 keyRequestType) {
805 switch (keyRequestType) {
806 case KeyRequestType_V1_1::NONE:
807 return DrmPlugin::kKeyRequestType_None;
808 break;
809 case KeyRequestType_V1_1::UPDATE:
810 return DrmPlugin::kKeyRequestType_Update;
811 break;
812 default:
813 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
814 break;
815 }
816 }
817
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)818 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
819 Vector<uint8_t> const &initData, String8 const &mimeType,
820 DrmPlugin::KeyType keyType, KeyedVector<String8,
821 String8> const &optionalParameters, Vector<uint8_t> &request,
822 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
823 Mutex::Autolock autoLock(mLock);
824 INIT_CHECK();
825 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
826
827 DrmSessionManager::Instance()->useSession(sessionId);
828
829 KeyType hKeyType;
830 if (keyType == DrmPlugin::kKeyType_Streaming) {
831 hKeyType = KeyType::STREAMING;
832 } else if (keyType == DrmPlugin::kKeyType_Offline) {
833 hKeyType = KeyType::OFFLINE;
834 } else if (keyType == DrmPlugin::kKeyType_Release) {
835 hKeyType = KeyType::RELEASE;
836 } else {
837 keyRequestTimer.SetAttribute(BAD_VALUE);
838 return BAD_VALUE;
839 }
840
841 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
842
843 status_t err = UNKNOWN_ERROR;
844 Return<void> hResult;
845
846 if (mPluginV1_2 != NULL) {
847 hResult = mPluginV1_2->getKeyRequest_1_2(
848 toHidlVec(sessionId), toHidlVec(initData),
849 toHidlString(mimeType), hKeyType, hOptionalParameters,
850 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
851 KeyRequestType_V1_1 hKeyRequestType,
852 const hidl_string& hDefaultUrl) {
853 if (status == Status_V1_2::OK) {
854 request = toVector(hRequest);
855 defaultUrl = toString8(hDefaultUrl);
856 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
857 }
858 err = toStatusT_1_2(status);
859 });
860 } else if (mPluginV1_1 != NULL) {
861 hResult = mPluginV1_1->getKeyRequest_1_1(
862 toHidlVec(sessionId), toHidlVec(initData),
863 toHidlString(mimeType), hKeyType, hOptionalParameters,
864 [&](Status status, const hidl_vec<uint8_t>& hRequest,
865 KeyRequestType_V1_1 hKeyRequestType,
866 const hidl_string& hDefaultUrl) {
867 if (status == Status::OK) {
868 request = toVector(hRequest);
869 defaultUrl = toString8(hDefaultUrl);
870 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
871 }
872 err = toStatusT(status);
873 });
874 } else {
875 hResult = mPlugin->getKeyRequest(
876 toHidlVec(sessionId), toHidlVec(initData),
877 toHidlString(mimeType), hKeyType, hOptionalParameters,
878 [&](Status status, const hidl_vec<uint8_t>& hRequest,
879 KeyRequestType hKeyRequestType,
880 const hidl_string& hDefaultUrl) {
881 if (status == Status::OK) {
882 request = toVector(hRequest);
883 defaultUrl = toString8(hDefaultUrl);
884 *keyRequestType = toKeyRequestType(hKeyRequestType);
885 }
886 err = toStatusT(status);
887 });
888 }
889
890 err = hResult.isOk() ? err : DEAD_OBJECT;
891 keyRequestTimer.SetAttribute(err);
892 return err;
893 }
894
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)895 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
896 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
897 Mutex::Autolock autoLock(mLock);
898 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
899
900 INIT_CHECK();
901
902 DrmSessionManager::Instance()->useSession(sessionId);
903
904 status_t err = UNKNOWN_ERROR;
905
906 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
907 toHidlVec(response),
908 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
909 if (status == Status::OK) {
910 keySetId = toVector(hKeySetId);
911 }
912 err = toStatusT(status);
913 }
914 );
915 err = hResult.isOk() ? err : DEAD_OBJECT;
916 keyResponseTimer.SetAttribute(err);
917 return err;
918 }
919
removeKeys(Vector<uint8_t> const & keySetId)920 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
921 Mutex::Autolock autoLock(mLock);
922 INIT_CHECK();
923
924 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
925 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
926 }
927
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)928 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
929 Vector<uint8_t> const &keySetId) {
930 Mutex::Autolock autoLock(mLock);
931 INIT_CHECK();
932
933 DrmSessionManager::Instance()->useSession(sessionId);
934
935 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
936 toHidlVec(keySetId));
937 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
938 }
939
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const940 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
941 KeyedVector<String8, String8> &infoMap) const {
942 Mutex::Autolock autoLock(mLock);
943 INIT_CHECK();
944
945 DrmSessionManager::Instance()->useSession(sessionId);
946
947 ::KeyedVector hInfoMap;
948
949 status_t err = UNKNOWN_ERROR;
950
951 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
952 [&](Status status, const hidl_vec<KeyValue>& map) {
953 if (status == Status::OK) {
954 infoMap = toKeyedVector(map);
955 }
956 err = toStatusT(status);
957 }
958 );
959
960 return hResult.isOk() ? err : DEAD_OBJECT;
961 }
962
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)963 status_t DrmHal::getProvisionRequest(String8 const &certType,
964 String8 const &certAuthority, Vector<uint8_t> &request,
965 String8 &defaultUrl) {
966 Mutex::Autolock autoLock(mLock);
967 INIT_CHECK();
968
969 status_t err = UNKNOWN_ERROR;
970 Return<void> hResult;
971
972 if (mPluginV1_2 != NULL) {
973 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
974 toHidlString(certType), toHidlString(certAuthority),
975 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
976 const hidl_string& hDefaultUrl) {
977 if (status == Status_V1_2::OK) {
978 request = toVector(hRequest);
979 defaultUrl = toString8(hDefaultUrl);
980 }
981 err = toStatusT_1_2(status);
982 }
983 );
984 } else {
985 Return<void> hResult = mPlugin->getProvisionRequest(
986 toHidlString(certType), toHidlString(certAuthority),
987 [&](Status status, const hidl_vec<uint8_t>& hRequest,
988 const hidl_string& hDefaultUrl) {
989 if (status == Status::OK) {
990 request = toVector(hRequest);
991 defaultUrl = toString8(hDefaultUrl);
992 }
993 err = toStatusT(status);
994 }
995 );
996 }
997
998 err = hResult.isOk() ? err : DEAD_OBJECT;
999 mMetrics.mGetProvisionRequestCounter.Increment(err);
1000 return err;
1001 }
1002
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)1003 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
1004 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
1005 Mutex::Autolock autoLock(mLock);
1006 INIT_CHECK();
1007
1008 status_t err = UNKNOWN_ERROR;
1009
1010 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1011 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1012 const hidl_vec<uint8_t>& hWrappedKey) {
1013 if (status == Status::OK) {
1014 certificate = toVector(hCertificate);
1015 wrappedKey = toVector(hWrappedKey);
1016 }
1017 err = toStatusT(status);
1018 }
1019 );
1020
1021 err = hResult.isOk() ? err : DEAD_OBJECT;
1022 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1023 return err;
1024 }
1025
getSecureStops(List<Vector<uint8_t>> & secureStops)1026 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
1027 Mutex::Autolock autoLock(mLock);
1028 INIT_CHECK();
1029
1030 status_t err = UNKNOWN_ERROR;
1031
1032 Return<void> hResult = mPlugin->getSecureStops(
1033 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1034 if (status == Status::OK) {
1035 secureStops = toSecureStops(hSecureStops);
1036 }
1037 err = toStatusT(status);
1038 }
1039 );
1040
1041 return hResult.isOk() ? err : DEAD_OBJECT;
1042 }
1043
1044
getSecureStopIds(List<Vector<uint8_t>> & secureStopIds)1045 status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1046 Mutex::Autolock autoLock(mLock);
1047
1048 if (mInitCheck != OK) {
1049 return mInitCheck;
1050 }
1051
1052 if (mPluginV1_1 == NULL) {
1053 return ERROR_DRM_CANNOT_HANDLE;
1054 }
1055
1056 status_t err = UNKNOWN_ERROR;
1057
1058 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1059 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1060 if (status == Status::OK) {
1061 secureStopIds = toSecureStopIds(hSecureStopIds);
1062 }
1063 err = toStatusT(status);
1064 }
1065 );
1066
1067 return hResult.isOk() ? err : DEAD_OBJECT;
1068 }
1069
1070
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)1071 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1072 Mutex::Autolock autoLock(mLock);
1073 INIT_CHECK();
1074
1075 status_t err = UNKNOWN_ERROR;
1076
1077 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1078 [&](Status status, const SecureStop& hSecureStop) {
1079 if (status == Status::OK) {
1080 secureStop = toVector(hSecureStop.opaqueData);
1081 }
1082 err = toStatusT(status);
1083 }
1084 );
1085
1086 return hResult.isOk() ? err : DEAD_OBJECT;
1087 }
1088
releaseSecureStops(Vector<uint8_t> const & ssRelease)1089 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1090 Mutex::Autolock autoLock(mLock);
1091 INIT_CHECK();
1092
1093 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1094 if (mPluginV1_1 != NULL) {
1095 SecureStopRelease secureStopRelease;
1096 secureStopRelease.opaqueData = toHidlVec(ssRelease);
1097 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1098 } else {
1099 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
1100 }
1101 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1102 }
1103
removeSecureStop(Vector<uint8_t> const & ssid)1104 status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1105 Mutex::Autolock autoLock(mLock);
1106
1107 if (mInitCheck != OK) {
1108 return mInitCheck;
1109 }
1110
1111 if (mPluginV1_1 == NULL) {
1112 return ERROR_DRM_CANNOT_HANDLE;
1113 }
1114
1115 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1116 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1117 }
1118
removeAllSecureStops()1119 status_t DrmHal::removeAllSecureStops() {
1120 Mutex::Autolock autoLock(mLock);
1121 INIT_CHECK();
1122
1123 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1124 if (mPluginV1_1 != NULL) {
1125 status = mPluginV1_1->removeAllSecureStops();
1126 } else {
1127 status = mPlugin->releaseAllSecureStops();
1128 }
1129 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1130 }
1131
getHdcpLevels(DrmPlugin::HdcpLevel * connected,DrmPlugin::HdcpLevel * max) const1132 status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1133 DrmPlugin::HdcpLevel *max) const {
1134 Mutex::Autolock autoLock(mLock);
1135 INIT_CHECK();
1136
1137 if (connected == NULL || max == NULL) {
1138 return BAD_VALUE;
1139 }
1140 status_t err = UNKNOWN_ERROR;
1141
1142 *connected = DrmPlugin::kHdcpLevelUnknown;
1143 *max = DrmPlugin::kHdcpLevelUnknown;
1144
1145 Return<void> hResult;
1146 if (mPluginV1_2 != NULL) {
1147 hResult = mPluginV1_2->getHdcpLevels_1_2(
1148 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1149 if (status == Status_V1_2::OK) {
1150 *connected = toHdcpLevel(hConnected);
1151 *max = toHdcpLevel(hMax);
1152 }
1153 err = toStatusT_1_2(status);
1154 });
1155 } else if (mPluginV1_1 != NULL) {
1156 hResult = mPluginV1_1->getHdcpLevels(
1157 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1158 if (status == Status::OK) {
1159 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1160 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1161 }
1162 err = toStatusT(status);
1163 });
1164 } else {
1165 return ERROR_DRM_CANNOT_HANDLE;
1166 }
1167
1168 return hResult.isOk() ? err : DEAD_OBJECT;
1169 }
1170
getNumberOfSessions(uint32_t * open,uint32_t * max) const1171 status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1172 Mutex::Autolock autoLock(mLock);
1173 INIT_CHECK();
1174
1175 if (open == NULL || max == NULL) {
1176 return BAD_VALUE;
1177 }
1178 status_t err = UNKNOWN_ERROR;
1179
1180 *open = 0;
1181 *max = 0;
1182
1183 if (mPluginV1_1 == NULL) {
1184 return ERROR_DRM_CANNOT_HANDLE;
1185 }
1186
1187 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1188 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1189 if (status == Status::OK) {
1190 *open = hOpen;
1191 *max = hMax;
1192 }
1193 err = toStatusT(status);
1194 }
1195 );
1196
1197 return hResult.isOk() ? err : DEAD_OBJECT;
1198 }
1199
getSecurityLevel(Vector<uint8_t> const & sessionId,DrmPlugin::SecurityLevel * level) const1200 status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1201 DrmPlugin::SecurityLevel *level) const {
1202 Mutex::Autolock autoLock(mLock);
1203 INIT_CHECK();
1204
1205 if (level == NULL) {
1206 return BAD_VALUE;
1207 }
1208 status_t err = UNKNOWN_ERROR;
1209
1210 if (mPluginV1_1 == NULL) {
1211 return ERROR_DRM_CANNOT_HANDLE;
1212 }
1213
1214 *level = DrmPlugin::kSecurityLevelUnknown;
1215
1216 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1217 [&](Status status, SecurityLevel hLevel) {
1218 if (status == Status::OK) {
1219 *level = toSecurityLevel(hLevel);
1220 }
1221 err = toStatusT(status);
1222 }
1223 );
1224
1225 return hResult.isOk() ? err : DEAD_OBJECT;
1226 }
1227
getOfflineLicenseKeySetIds(List<Vector<uint8_t>> & keySetIds) const1228 status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1229 Mutex::Autolock autoLock(mLock);
1230
1231 if (mInitCheck != OK) {
1232 return mInitCheck;
1233 }
1234
1235 if (mPluginV1_2 == NULL) {
1236 return ERROR_UNSUPPORTED;
1237 }
1238
1239 status_t err = UNKNOWN_ERROR;
1240
1241 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1242 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1243 if (status == Status::OK) {
1244 keySetIds = toKeySetIds(hKeySetIds);
1245 }
1246 err = toStatusT(status);
1247 }
1248 );
1249
1250 return hResult.isOk() ? err : DEAD_OBJECT;
1251 }
1252
removeOfflineLicense(Vector<uint8_t> const & keySetId)1253 status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1254 Mutex::Autolock autoLock(mLock);
1255
1256 if (mInitCheck != OK) {
1257 return mInitCheck;
1258 }
1259
1260 if (mPluginV1_2 == NULL) {
1261 return ERROR_UNSUPPORTED;
1262 }
1263
1264 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1265 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1266 }
1267
getOfflineLicenseState(Vector<uint8_t> const & keySetId,DrmPlugin::OfflineLicenseState * licenseState) const1268 status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1269 DrmPlugin::OfflineLicenseState *licenseState) const {
1270 Mutex::Autolock autoLock(mLock);
1271
1272 if (mInitCheck != OK) {
1273 return mInitCheck;
1274 }
1275
1276 if (mPluginV1_2 == NULL) {
1277 return ERROR_UNSUPPORTED;
1278 }
1279 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1280
1281 status_t err = UNKNOWN_ERROR;
1282
1283 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1284 [&](Status status, OfflineLicenseState hLicenseState) {
1285 if (status == Status::OK) {
1286 *licenseState = toOfflineLicenseState(hLicenseState);
1287 }
1288 err = toStatusT(status);
1289 }
1290 );
1291
1292 return hResult.isOk() ? err : DEAD_OBJECT;
1293 }
1294
getPropertyString(String8 const & name,String8 & value) const1295 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1296 Mutex::Autolock autoLock(mLock);
1297 return getPropertyStringInternal(name, value);
1298 }
1299
getPropertyStringInternal(String8 const & name,String8 & value) const1300 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1301 // This function is internal to the class and should only be called while
1302 // mLock is already held.
1303 INIT_CHECK();
1304
1305 status_t err = UNKNOWN_ERROR;
1306
1307 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1308 [&](Status status, const hidl_string& hValue) {
1309 if (status == Status::OK) {
1310 value = toString8(hValue);
1311 }
1312 err = toStatusT(status);
1313 }
1314 );
1315
1316 return hResult.isOk() ? err : DEAD_OBJECT;
1317 }
1318
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const1319 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1320 Mutex::Autolock autoLock(mLock);
1321 return getPropertyByteArrayInternal(name, value);
1322 }
1323
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const1324 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1325 // This function is internal to the class and should only be called while
1326 // mLock is already held.
1327 INIT_CHECK();
1328
1329 status_t err = UNKNOWN_ERROR;
1330
1331 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1332 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1333 if (status == Status::OK) {
1334 value = toVector(hValue);
1335 }
1336 err = toStatusT(status);
1337 }
1338 );
1339
1340 err = hResult.isOk() ? err : DEAD_OBJECT;
1341 if (name == kPropertyDeviceUniqueId) {
1342 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1343 }
1344 return err;
1345 }
1346
setPropertyString(String8 const & name,String8 const & value) const1347 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1348 Mutex::Autolock autoLock(mLock);
1349 INIT_CHECK();
1350
1351 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
1352 toHidlString(value));
1353 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1354 }
1355
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const1356 status_t DrmHal::setPropertyByteArray(String8 const &name,
1357 Vector<uint8_t> const &value ) const {
1358 Mutex::Autolock autoLock(mLock);
1359 INIT_CHECK();
1360
1361 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
1362 toHidlVec(value));
1363 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1364 }
1365
getMetrics(PersistableBundle * metrics)1366 status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1367 if (metrics == nullptr) {
1368 return UNEXPECTED_NULL;
1369 }
1370 mMetrics.Export(metrics);
1371
1372 // Append vendor metrics if they are supported.
1373 if (mPluginV1_1 != NULL) {
1374 String8 vendor;
1375 String8 description;
1376 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1377 || vendor.isEmpty()) {
1378 ALOGE("Get vendor failed or is empty");
1379 vendor = "NONE";
1380 }
1381 if (getPropertyStringInternal(String8("description"), description) != OK
1382 || description.isEmpty()) {
1383 ALOGE("Get description failed or is empty.");
1384 description = "NONE";
1385 }
1386 vendor += ".";
1387 vendor += description;
1388
1389 hidl_vec<DrmMetricGroup> pluginMetrics;
1390 status_t err = UNKNOWN_ERROR;
1391
1392 Return<void> status = mPluginV1_1->getMetrics(
1393 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1394 if (status != Status::OK) {
1395 ALOGV("Error getting plugin metrics: %d", status);
1396 } else {
1397 PersistableBundle pluginBundle;
1398 if (MediaDrmMetrics::HidlMetricsToBundle(
1399 pluginMetrics, &pluginBundle) == OK) {
1400 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1401 }
1402 }
1403 err = toStatusT(status);
1404 });
1405 return status.isOk() ? err : DEAD_OBJECT;
1406 }
1407
1408 return OK;
1409 }
1410
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1411 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1412 String8 const &algorithm) {
1413 Mutex::Autolock autoLock(mLock);
1414 INIT_CHECK();
1415
1416 DrmSessionManager::Instance()->useSession(sessionId);
1417
1418 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1419 toHidlString(algorithm));
1420 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1421 }
1422
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1423 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1424 String8 const &algorithm) {
1425 Mutex::Autolock autoLock(mLock);
1426 INIT_CHECK();
1427
1428 DrmSessionManager::Instance()->useSession(sessionId);
1429
1430 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1431 toHidlString(algorithm));
1432 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1433 }
1434
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)1435 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
1436 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1437 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1438 Mutex::Autolock autoLock(mLock);
1439 INIT_CHECK();
1440
1441 DrmSessionManager::Instance()->useSession(sessionId);
1442
1443 status_t err = UNKNOWN_ERROR;
1444
1445 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1446 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1447 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1448 if (status == Status::OK) {
1449 output = toVector(hOutput);
1450 }
1451 err = toStatusT(status);
1452 }
1453 );
1454
1455 return hResult.isOk() ? err : DEAD_OBJECT;
1456 }
1457
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)1458 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
1459 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1460 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1461 Mutex::Autolock autoLock(mLock);
1462 INIT_CHECK();
1463
1464 DrmSessionManager::Instance()->useSession(sessionId);
1465
1466 status_t err = UNKNOWN_ERROR;
1467
1468 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1469 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1470 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1471 if (status == Status::OK) {
1472 output = toVector(hOutput);
1473 }
1474 err = toStatusT(status);
1475 }
1476 );
1477
1478 return hResult.isOk() ? err : DEAD_OBJECT;
1479 }
1480
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)1481 status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
1482 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1483 Vector<uint8_t> &signature) {
1484 Mutex::Autolock autoLock(mLock);
1485 INIT_CHECK();
1486
1487 DrmSessionManager::Instance()->useSession(sessionId);
1488
1489 status_t err = UNKNOWN_ERROR;
1490
1491 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1492 toHidlVec(keyId), toHidlVec(message),
1493 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1494 if (status == Status::OK) {
1495 signature = toVector(hSignature);
1496 }
1497 err = toStatusT(status);
1498 }
1499 );
1500
1501 return hResult.isOk() ? err : DEAD_OBJECT;
1502 }
1503
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)1504 status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
1505 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1506 Vector<uint8_t> const &signature, bool &match) {
1507 Mutex::Autolock autoLock(mLock);
1508 INIT_CHECK();
1509
1510 DrmSessionManager::Instance()->useSession(sessionId);
1511
1512 status_t err = UNKNOWN_ERROR;
1513
1514 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1515 toHidlVec(message), toHidlVec(signature),
1516 [&](Status status, bool hMatch) {
1517 if (status == Status::OK) {
1518 match = hMatch;
1519 } else {
1520 match = false;
1521 }
1522 err = toStatusT(status);
1523 }
1524 );
1525
1526 return hResult.isOk() ? err : DEAD_OBJECT;
1527 }
1528
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)1529 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
1530 String8 const &algorithm, Vector<uint8_t> const &message,
1531 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
1532 Mutex::Autolock autoLock(mLock);
1533 INIT_CHECK();
1534
1535 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1536 return -EPERM;
1537 }
1538
1539 DrmSessionManager::Instance()->useSession(sessionId);
1540
1541 status_t err = UNKNOWN_ERROR;
1542
1543 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1544 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1545 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1546 if (status == Status::OK) {
1547 signature = toVector(hSignature);
1548 }
1549 err = toStatusT(status);
1550 }
1551 );
1552
1553 return hResult.isOk() ? err : DEAD_OBJECT;
1554 }
1555
binderDied(const wp<IBinder> & the_late_who __unused)1556 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1557 {
1558 cleanup();
1559 }
1560
writeByteArray(Parcel & obj,hidl_vec<uint8_t> const & vec)1561 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1562 {
1563 if (vec.size()) {
1564 obj.writeInt32(vec.size());
1565 obj.write(vec.data(), vec.size());
1566 } else {
1567 obj.writeInt32(0);
1568 }
1569 }
1570
reportFrameworkMetrics() const1571 void DrmHal::reportFrameworkMetrics() const
1572 {
1573 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1574 item->generateSessionID();
1575 item->setPkgName(mMetrics.GetAppPackageName().c_str());
1576 String8 vendor;
1577 String8 description;
1578 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1579 if (result != OK) {
1580 ALOGE("Failed to get vendor from drm plugin: %d", result);
1581 } else {
1582 item->setCString("vendor", vendor.c_str());
1583 }
1584 result = getPropertyStringInternal(String8("description"), description);
1585 if (result != OK) {
1586 ALOGE("Failed to get description from drm plugin: %d", result);
1587 } else {
1588 item->setCString("description", description.c_str());
1589 }
1590
1591 std::string serializedMetrics;
1592 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1593 if (result != OK) {
1594 ALOGE("Failed to serialize framework metrics: %d", result);
1595 }
1596 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1597 serializedMetrics.size());
1598 if (!b64EncodedMetrics.empty()) {
1599 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
1600 }
1601 if (!item->selfrecord()) {
1602 ALOGE("Failed to self record framework metrics");
1603 }
1604 }
1605
reportPluginMetrics() const1606 void DrmHal::reportPluginMetrics() const
1607 {
1608 Vector<uint8_t> metricsVector;
1609 String8 vendor;
1610 String8 description;
1611 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1612 getPropertyStringInternal(String8("description"), description) == OK &&
1613 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1614 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1615 metricsVector.size());
1616 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1617 description, mAppPackageName);
1618 if (res != OK) {
1619 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1620 }
1621 }
1622 }
1623
1624 } // namespace android
1625