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 Mutex DrmHal::mLock;
299
reclaimResource()300 bool DrmHal::DrmSessionClient::reclaimResource() {
301 sp<DrmHal> drm = mDrm.promote();
302 if (drm == NULL) {
303 return true;
304 }
305 status_t err = drm->closeSession(mSessionId);
306 if (err != OK) {
307 return false;
308 }
309 drm->sendEvent(EventType::SESSION_RECLAIMED,
310 toHidlVec(mSessionId), hidl_vec<uint8_t>());
311 return true;
312 }
313
getName()314 String8 DrmHal::DrmSessionClient::getName() {
315 String8 name;
316 sp<DrmHal> drm = mDrm.promote();
317 if (drm == NULL) {
318 name.append("<deleted>");
319 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
320 || name.isEmpty()) {
321 name.append("<Get vendor failed or is empty>");
322 }
323 name.append("[");
324 for (size_t i = 0; i < mSessionId.size(); ++i) {
325 name.appendFormat("%02x", mSessionId[i]);
326 }
327 name.append("]");
328 return name;
329 }
330
~DrmSessionClient()331 DrmHal::DrmSessionClient::~DrmSessionClient() {
332 DrmSessionManager::Instance()->removeSession(mSessionId);
333 }
334
DrmHal()335 DrmHal::DrmHal()
336 : mFactories(makeDrmFactories()),
337 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
338 }
339
closeOpenSessions()340 void DrmHal::closeOpenSessions() {
341 Mutex::Autolock autoLock(mLock);
342 auto openSessions = mOpenSessions;
343 for (size_t i = 0; i < openSessions.size(); i++) {
344 mLock.unlock();
345 closeSession(openSessions[i]->mSessionId);
346 mLock.lock();
347 }
348 mOpenSessions.clear();
349 }
350
~DrmHal()351 DrmHal::~DrmHal() {
352 }
353
cleanup()354 void DrmHal::cleanup() {
355 closeOpenSessions();
356
357 Mutex::Autolock autoLock(mLock);
358 reportPluginMetrics();
359 reportFrameworkMetrics();
360
361 setListener(NULL);
362 mInitCheck = NO_INIT;
363 if (mPluginV1_2 != NULL) {
364 if (!mPluginV1_2->setListener(NULL).isOk()) {
365 mInitCheck = DEAD_OBJECT;
366 }
367 } else if (mPlugin != NULL) {
368 if (!mPlugin->setListener(NULL).isOk()) {
369 mInitCheck = DEAD_OBJECT;
370 }
371 }
372 mPlugin.clear();
373 mPluginV1_1.clear();
374 mPluginV1_2.clear();
375 }
376
makeDrmFactories()377 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
378 Vector<sp<IDrmFactory>> factories;
379
380 auto manager = hardware::defaultServiceManager1_2();
381
382 if (manager != NULL) {
383 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
384 [&factories](const hidl_vec<hidl_string> ®istered) {
385 for (const auto &instance : registered) {
386 auto factory = drm::V1_0::IDrmFactory::getService(instance);
387 if (factory != NULL) {
388 factories.push_back(factory);
389 }
390 }
391 }
392 );
393 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
394 [&factories](const hidl_vec<hidl_string> ®istered) {
395 for (const auto &instance : registered) {
396 auto factory = drm::V1_1::IDrmFactory::getService(instance);
397 if (factory != NULL) {
398 factories.push_back(factory);
399 }
400 }
401 }
402 );
403 manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
404 [&factories](const hidl_vec<hidl_string> ®istered) {
405 for (const auto &instance : registered) {
406 auto factory = drm::V1_2::IDrmFactory::getService(instance);
407 if (factory != NULL) {
408 factories.push_back(factory);
409 }
410 }
411 }
412 );
413 }
414
415 if (factories.size() == 0) {
416 // must be in passthrough mode, load the default passthrough service
417 auto passthrough = IDrmFactory::getService();
418 if (passthrough != NULL) {
419 ALOGI("makeDrmFactories: using default passthrough drm instance");
420 factories.push_back(passthrough);
421 } else {
422 ALOGE("Failed to find any drm factories");
423 }
424 }
425 return factories;
426 }
427
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)428 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
429 const uint8_t uuid[16], const String8& appPackageName) {
430 mAppPackageName = appPackageName;
431 mMetrics.SetAppPackageName(appPackageName);
432
433 sp<IDrmPlugin> plugin;
434 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
435 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
436 if (status != Status::OK) {
437 ALOGE("Failed to make drm plugin");
438 return;
439 }
440 plugin = hPlugin;
441 }
442 );
443
444 if (!hResult.isOk()) {
445 ALOGE("createPlugin remote call failed");
446 }
447
448 return plugin;
449 }
450
initCheck() const451 status_t DrmHal::initCheck() const {
452 return mInitCheck;
453 }
454
setListener(const sp<IDrmClient> & listener)455 status_t DrmHal::setListener(const sp<IDrmClient>& listener)
456 {
457 Mutex::Autolock lock(mEventLock);
458 if (mListener != NULL){
459 IInterface::asBinder(mListener)->unlinkToDeath(this);
460 }
461 if (listener != NULL) {
462 IInterface::asBinder(listener)->linkToDeath(this);
463 }
464 mListener = listener;
465 return NO_ERROR;
466 }
467
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)468 Return<void> DrmHal::sendEvent(EventType hEventType,
469 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
470 mMetrics.mEventCounter.Increment(hEventType);
471
472 mEventLock.lock();
473 sp<IDrmClient> listener = mListener;
474 mEventLock.unlock();
475
476 if (listener != NULL) {
477 Parcel obj;
478 writeByteArray(obj, sessionId);
479 writeByteArray(obj, data);
480
481 Mutex::Autolock lock(mNotifyLock);
482 DrmPlugin::EventType eventType;
483 switch(hEventType) {
484 case EventType::PROVISION_REQUIRED:
485 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
486 break;
487 case EventType::KEY_NEEDED:
488 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
489 break;
490 case EventType::KEY_EXPIRED:
491 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
492 break;
493 case EventType::VENDOR_DEFINED:
494 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
495 break;
496 case EventType::SESSION_RECLAIMED:
497 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
498 break;
499 default:
500 return Void();
501 }
502 listener->notify(eventType, 0, &obj);
503 }
504 return Void();
505 }
506
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)507 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
508 int64_t expiryTimeInMS) {
509
510 mEventLock.lock();
511 sp<IDrmClient> listener = mListener;
512 mEventLock.unlock();
513
514 if (listener != NULL) {
515 Parcel obj;
516 writeByteArray(obj, sessionId);
517 obj.writeInt64(expiryTimeInMS);
518
519 Mutex::Autolock lock(mNotifyLock);
520 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
521 }
522 return Void();
523 }
524
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus_V1_0> & keyStatusList_V1_0,bool hasNewUsableKey)525 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
526 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
527 std::vector<KeyStatus> keyStatusVec;
528 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
529 keyStatusVec.push_back({keyStatus_V1_0.keyId,
530 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
531 }
532 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
533 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
534 }
535
sendKeysChange_1_2(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)536 Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
537 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
538
539 mEventLock.lock();
540 sp<IDrmClient> listener = mListener;
541 mEventLock.unlock();
542
543 if (listener != NULL) {
544 Parcel obj;
545 writeByteArray(obj, sessionId);
546
547 size_t nKeys = keyStatusList.size();
548 obj.writeInt32(nKeys);
549 for (size_t i = 0; i < nKeys; ++i) {
550 const KeyStatus &keyStatus = keyStatusList[i];
551 writeByteArray(obj, keyStatus.keyId);
552 uint32_t type;
553 switch(keyStatus.type) {
554 case KeyStatusType::USABLE:
555 type = DrmPlugin::kKeyStatusType_Usable;
556 break;
557 case KeyStatusType::EXPIRED:
558 type = DrmPlugin::kKeyStatusType_Expired;
559 break;
560 case KeyStatusType::OUTPUTNOTALLOWED:
561 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
562 break;
563 case KeyStatusType::STATUSPENDING:
564 type = DrmPlugin::kKeyStatusType_StatusPending;
565 break;
566 case KeyStatusType::USABLEINFUTURE:
567 type = DrmPlugin::kKeyStatusType_UsableInFuture;
568 break;
569 case KeyStatusType::INTERNALERROR:
570 default:
571 type = DrmPlugin::kKeyStatusType_InternalError;
572 break;
573 }
574 obj.writeInt32(type);
575 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
576 }
577 obj.writeInt32(hasNewUsableKey);
578
579 Mutex::Autolock lock(mNotifyLock);
580 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
581 } else {
582 // There's no listener. But we still want to count the key change
583 // events.
584 size_t nKeys = keyStatusList.size();
585 for (size_t i = 0; i < nKeys; i++) {
586 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
587 }
588 }
589
590 return Void();
591 }
592
sendSessionLostState(const hidl_vec<uint8_t> & sessionId)593 Return<void> DrmHal::sendSessionLostState(
594 const hidl_vec<uint8_t>& sessionId) {
595
596 mEventLock.lock();
597 sp<IDrmClient> listener = mListener;
598 mEventLock.unlock();
599
600 if (listener != NULL) {
601 Parcel obj;
602 writeByteArray(obj, sessionId);
603 Mutex::Autolock lock(mNotifyLock);
604 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
605 }
606 return Void();
607 }
608
matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)609 status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
610 const uint8_t uuid[16],
611 const String8 &mimeType,
612 DrmPlugin::SecurityLevel level,
613 bool *isSupported) {
614 *isSupported = false;
615
616 // handle default value cases
617 if (level == DrmPlugin::kSecurityLevelUnknown) {
618 if (mimeType == "") {
619 // isCryptoSchemeSupported(uuid)
620 *isSupported = true;
621 } else {
622 // isCryptoSchemeSupported(uuid, mimeType)
623 *isSupported = factory->isContentTypeSupported(mimeType.string());
624 }
625 return OK;
626 } else if (mimeType == "") {
627 return BAD_VALUE;
628 }
629
630 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
631 if (factoryV1_2 == NULL) {
632 return ERROR_UNSUPPORTED;
633 } else {
634 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
635 mimeType.string(), toHidlSecurityLevel(level));
636 return OK;
637 }
638 }
639
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType,DrmPlugin::SecurityLevel level,bool * isSupported)640 status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
641 const String8 &mimeType,
642 DrmPlugin::SecurityLevel level,
643 bool *isSupported) {
644 Mutex::Autolock autoLock(mLock);
645 *isSupported = false;
646 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
647 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
648 return matchMimeTypeAndSecurityLevel(mFactories[i],
649 uuid, mimeType, level, isSupported);
650 }
651 }
652 return OK;
653 }
654
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)655 status_t DrmHal::createPlugin(const uint8_t uuid[16],
656 const String8& appPackageName) {
657 Mutex::Autolock autoLock(mLock);
658
659 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
660 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
661 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
662 if (plugin != NULL) {
663 mPlugin = plugin;
664 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
665 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
666 break;
667 }
668 }
669 }
670
671 if (mPlugin == NULL) {
672 mInitCheck = ERROR_UNSUPPORTED;
673 } else {
674 mInitCheck = OK;
675 if (mPluginV1_2 != NULL) {
676 if (!mPluginV1_2->setListener(this).isOk()) {
677 mInitCheck = DEAD_OBJECT;
678 }
679 } else if (!mPlugin->setListener(this).isOk()) {
680 mInitCheck = DEAD_OBJECT;
681 }
682 if (mInitCheck != OK) {
683 mPlugin.clear();
684 mPluginV1_1.clear();
685 mPluginV1_2.clear();
686 }
687 }
688
689
690 return mInitCheck;
691 }
692
destroyPlugin()693 status_t DrmHal::destroyPlugin() {
694 cleanup();
695 return OK;
696 }
697
openSession(DrmPlugin::SecurityLevel level,Vector<uint8_t> & sessionId)698 status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
699 Vector<uint8_t> &sessionId) {
700 Mutex::Autolock autoLock(mLock);
701 INIT_CHECK();
702
703 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
704 bool setSecurityLevel = true;
705
706 if (level == DrmPlugin::kSecurityLevelMax) {
707 setSecurityLevel = false;
708 } else {
709 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
710 return ERROR_DRM_CANNOT_HANDLE;
711 }
712 }
713
714 status_t err = UNKNOWN_ERROR;
715 bool retry = true;
716 do {
717 hidl_vec<uint8_t> hSessionId;
718
719 Return<void> hResult;
720 if (mPluginV1_1 == NULL || !setSecurityLevel) {
721 hResult = mPlugin->openSession(
722 [&](Status status,const hidl_vec<uint8_t>& id) {
723 if (status == Status::OK) {
724 sessionId = toVector(id);
725 }
726 err = toStatusT(status);
727 }
728 );
729 } else {
730 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
731 [&](Status status, const hidl_vec<uint8_t>& id) {
732 if (status == Status::OK) {
733 sessionId = toVector(id);
734 }
735 err = toStatusT(status);
736 }
737 );
738 }
739
740 if (!hResult.isOk()) {
741 err = DEAD_OBJECT;
742 }
743
744 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
745 mLock.unlock();
746 // reclaimSession may call back to closeSession, since mLock is
747 // shared between Drm instances, we should unlock here to avoid
748 // deadlock.
749 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
750 mLock.lock();
751 } else {
752 retry = false;
753 }
754 } while (retry);
755
756 if (err == OK) {
757 sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
758 DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
759 mOpenSessions.push(client);
760 mMetrics.SetSessionStart(sessionId);
761 }
762
763 mMetrics.mOpenSessionCounter.Increment(err);
764 return err;
765 }
766
closeSession(Vector<uint8_t> const & sessionId)767 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
768 Mutex::Autolock autoLock(mLock);
769 INIT_CHECK();
770
771 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
772 if (status.isOk()) {
773 if (status == Status::OK) {
774 DrmSessionManager::Instance()->removeSession(sessionId);
775 for (size_t i = 0; i < mOpenSessions.size(); i++) {
776 if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
777 mOpenSessions.removeAt(i);
778 break;
779 }
780 }
781 }
782 status_t response = toStatusT(status);
783 mMetrics.SetSessionEnd(sessionId);
784 mMetrics.mCloseSessionCounter.Increment(response);
785 return response;
786 }
787 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
788 return DEAD_OBJECT;
789 }
790
toKeyRequestType(KeyRequestType keyRequestType)791 static DrmPlugin::KeyRequestType toKeyRequestType(
792 KeyRequestType keyRequestType) {
793 switch (keyRequestType) {
794 case KeyRequestType::INITIAL:
795 return DrmPlugin::kKeyRequestType_Initial;
796 break;
797 case KeyRequestType::RENEWAL:
798 return DrmPlugin::kKeyRequestType_Renewal;
799 break;
800 case KeyRequestType::RELEASE:
801 return DrmPlugin::kKeyRequestType_Release;
802 break;
803 default:
804 return DrmPlugin::kKeyRequestType_Unknown;
805 break;
806 }
807 }
808
toKeyRequestType_1_1(KeyRequestType_V1_1 keyRequestType)809 static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
810 KeyRequestType_V1_1 keyRequestType) {
811 switch (keyRequestType) {
812 case KeyRequestType_V1_1::NONE:
813 return DrmPlugin::kKeyRequestType_None;
814 break;
815 case KeyRequestType_V1_1::UPDATE:
816 return DrmPlugin::kKeyRequestType_Update;
817 break;
818 default:
819 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
820 break;
821 }
822 }
823
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)824 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
825 Vector<uint8_t> const &initData, String8 const &mimeType,
826 DrmPlugin::KeyType keyType, KeyedVector<String8,
827 String8> const &optionalParameters, Vector<uint8_t> &request,
828 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
829 Mutex::Autolock autoLock(mLock);
830 INIT_CHECK();
831 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
832
833 DrmSessionManager::Instance()->useSession(sessionId);
834
835 KeyType hKeyType;
836 if (keyType == DrmPlugin::kKeyType_Streaming) {
837 hKeyType = KeyType::STREAMING;
838 } else if (keyType == DrmPlugin::kKeyType_Offline) {
839 hKeyType = KeyType::OFFLINE;
840 } else if (keyType == DrmPlugin::kKeyType_Release) {
841 hKeyType = KeyType::RELEASE;
842 } else {
843 keyRequestTimer.SetAttribute(BAD_VALUE);
844 return BAD_VALUE;
845 }
846
847 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
848
849 status_t err = UNKNOWN_ERROR;
850 Return<void> hResult;
851
852 if (mPluginV1_2 != NULL) {
853 hResult = mPluginV1_2->getKeyRequest_1_2(
854 toHidlVec(sessionId), toHidlVec(initData),
855 toHidlString(mimeType), hKeyType, hOptionalParameters,
856 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
857 KeyRequestType_V1_1 hKeyRequestType,
858 const hidl_string& hDefaultUrl) {
859 if (status == Status_V1_2::OK) {
860 request = toVector(hRequest);
861 defaultUrl = toString8(hDefaultUrl);
862 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
863 }
864 err = toStatusT_1_2(status);
865 });
866 } else if (mPluginV1_1 != NULL) {
867 hResult = mPluginV1_1->getKeyRequest_1_1(
868 toHidlVec(sessionId), toHidlVec(initData),
869 toHidlString(mimeType), hKeyType, hOptionalParameters,
870 [&](Status status, const hidl_vec<uint8_t>& hRequest,
871 KeyRequestType_V1_1 hKeyRequestType,
872 const hidl_string& hDefaultUrl) {
873 if (status == Status::OK) {
874 request = toVector(hRequest);
875 defaultUrl = toString8(hDefaultUrl);
876 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
877 }
878 err = toStatusT(status);
879 });
880 } else {
881 hResult = mPlugin->getKeyRequest(
882 toHidlVec(sessionId), toHidlVec(initData),
883 toHidlString(mimeType), hKeyType, hOptionalParameters,
884 [&](Status status, const hidl_vec<uint8_t>& hRequest,
885 KeyRequestType hKeyRequestType,
886 const hidl_string& hDefaultUrl) {
887 if (status == Status::OK) {
888 request = toVector(hRequest);
889 defaultUrl = toString8(hDefaultUrl);
890 *keyRequestType = toKeyRequestType(hKeyRequestType);
891 }
892 err = toStatusT(status);
893 });
894 }
895
896 err = hResult.isOk() ? err : DEAD_OBJECT;
897 keyRequestTimer.SetAttribute(err);
898 return err;
899 }
900
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)901 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
902 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
903 Mutex::Autolock autoLock(mLock);
904 INIT_CHECK();
905 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
906
907 DrmSessionManager::Instance()->useSession(sessionId);
908
909 status_t err = UNKNOWN_ERROR;
910
911 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
912 toHidlVec(response),
913 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
914 if (status == Status::OK) {
915 keySetId = toVector(hKeySetId);
916 }
917 err = toStatusT(status);
918 }
919 );
920 err = hResult.isOk() ? err : DEAD_OBJECT;
921 keyResponseTimer.SetAttribute(err);
922 return err;
923 }
924
removeKeys(Vector<uint8_t> const & keySetId)925 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
926 Mutex::Autolock autoLock(mLock);
927 INIT_CHECK();
928
929 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
930 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
931 }
932
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)933 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
934 Vector<uint8_t> const &keySetId) {
935 Mutex::Autolock autoLock(mLock);
936 INIT_CHECK();
937
938 DrmSessionManager::Instance()->useSession(sessionId);
939
940 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
941 toHidlVec(keySetId));
942 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
943 }
944
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const945 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
946 KeyedVector<String8, String8> &infoMap) const {
947 Mutex::Autolock autoLock(mLock);
948 INIT_CHECK();
949
950 DrmSessionManager::Instance()->useSession(sessionId);
951
952 ::KeyedVector hInfoMap;
953
954 status_t err = UNKNOWN_ERROR;
955
956 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
957 [&](Status status, const hidl_vec<KeyValue>& map) {
958 if (status == Status::OK) {
959 infoMap = toKeyedVector(map);
960 }
961 err = toStatusT(status);
962 }
963 );
964
965 return hResult.isOk() ? err : DEAD_OBJECT;
966 }
967
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)968 status_t DrmHal::getProvisionRequest(String8 const &certType,
969 String8 const &certAuthority, Vector<uint8_t> &request,
970 String8 &defaultUrl) {
971 Mutex::Autolock autoLock(mLock);
972 INIT_CHECK();
973
974 status_t err = UNKNOWN_ERROR;
975 Return<void> hResult;
976
977 if (mPluginV1_2 != NULL) {
978 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
979 toHidlString(certType), toHidlString(certAuthority),
980 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
981 const hidl_string& hDefaultUrl) {
982 if (status == Status_V1_2::OK) {
983 request = toVector(hRequest);
984 defaultUrl = toString8(hDefaultUrl);
985 }
986 err = toStatusT_1_2(status);
987 }
988 );
989 } else {
990 Return<void> hResult = mPlugin->getProvisionRequest(
991 toHidlString(certType), toHidlString(certAuthority),
992 [&](Status status, const hidl_vec<uint8_t>& hRequest,
993 const hidl_string& hDefaultUrl) {
994 if (status == Status::OK) {
995 request = toVector(hRequest);
996 defaultUrl = toString8(hDefaultUrl);
997 }
998 err = toStatusT(status);
999 }
1000 );
1001 }
1002
1003 err = hResult.isOk() ? err : DEAD_OBJECT;
1004 mMetrics.mGetProvisionRequestCounter.Increment(err);
1005 return err;
1006 }
1007
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)1008 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
1009 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
1010 Mutex::Autolock autoLock(mLock);
1011 INIT_CHECK();
1012
1013 status_t err = UNKNOWN_ERROR;
1014
1015 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1016 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1017 const hidl_vec<uint8_t>& hWrappedKey) {
1018 if (status == Status::OK) {
1019 certificate = toVector(hCertificate);
1020 wrappedKey = toVector(hWrappedKey);
1021 }
1022 err = toStatusT(status);
1023 }
1024 );
1025
1026 err = hResult.isOk() ? err : DEAD_OBJECT;
1027 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1028 return err;
1029 }
1030
getSecureStops(List<Vector<uint8_t>> & secureStops)1031 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
1032 Mutex::Autolock autoLock(mLock);
1033 INIT_CHECK();
1034
1035 status_t err = UNKNOWN_ERROR;
1036
1037 Return<void> hResult = mPlugin->getSecureStops(
1038 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1039 if (status == Status::OK) {
1040 secureStops = toSecureStops(hSecureStops);
1041 }
1042 err = toStatusT(status);
1043 }
1044 );
1045
1046 return hResult.isOk() ? err : DEAD_OBJECT;
1047 }
1048
1049
getSecureStopIds(List<Vector<uint8_t>> & secureStopIds)1050 status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1051 Mutex::Autolock autoLock(mLock);
1052
1053 if (mInitCheck != OK) {
1054 return mInitCheck;
1055 }
1056
1057 if (mPluginV1_1 == NULL) {
1058 return ERROR_DRM_CANNOT_HANDLE;
1059 }
1060
1061 status_t err = UNKNOWN_ERROR;
1062
1063 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1064 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1065 if (status == Status::OK) {
1066 secureStopIds = toSecureStopIds(hSecureStopIds);
1067 }
1068 err = toStatusT(status);
1069 }
1070 );
1071
1072 return hResult.isOk() ? err : DEAD_OBJECT;
1073 }
1074
1075
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)1076 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1077 Mutex::Autolock autoLock(mLock);
1078 INIT_CHECK();
1079
1080 status_t err = UNKNOWN_ERROR;
1081
1082 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1083 [&](Status status, const SecureStop& hSecureStop) {
1084 if (status == Status::OK) {
1085 secureStop = toVector(hSecureStop.opaqueData);
1086 }
1087 err = toStatusT(status);
1088 }
1089 );
1090
1091 return hResult.isOk() ? err : DEAD_OBJECT;
1092 }
1093
releaseSecureStops(Vector<uint8_t> const & ssRelease)1094 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1095 Mutex::Autolock autoLock(mLock);
1096 INIT_CHECK();
1097
1098 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1099 if (mPluginV1_1 != NULL) {
1100 SecureStopRelease secureStopRelease;
1101 secureStopRelease.opaqueData = toHidlVec(ssRelease);
1102 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1103 } else {
1104 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
1105 }
1106 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1107 }
1108
removeSecureStop(Vector<uint8_t> const & ssid)1109 status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1110 Mutex::Autolock autoLock(mLock);
1111
1112 if (mInitCheck != OK) {
1113 return mInitCheck;
1114 }
1115
1116 if (mPluginV1_1 == NULL) {
1117 return ERROR_DRM_CANNOT_HANDLE;
1118 }
1119
1120 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1121 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1122 }
1123
removeAllSecureStops()1124 status_t DrmHal::removeAllSecureStops() {
1125 Mutex::Autolock autoLock(mLock);
1126 INIT_CHECK();
1127
1128 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
1129 if (mPluginV1_1 != NULL) {
1130 status = mPluginV1_1->removeAllSecureStops();
1131 } else {
1132 status = mPlugin->releaseAllSecureStops();
1133 }
1134 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1135 }
1136
getHdcpLevels(DrmPlugin::HdcpLevel * connected,DrmPlugin::HdcpLevel * max) const1137 status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1138 DrmPlugin::HdcpLevel *max) const {
1139 Mutex::Autolock autoLock(mLock);
1140 INIT_CHECK();
1141
1142 if (connected == NULL || max == NULL) {
1143 return BAD_VALUE;
1144 }
1145 status_t err = UNKNOWN_ERROR;
1146
1147 *connected = DrmPlugin::kHdcpLevelUnknown;
1148 *max = DrmPlugin::kHdcpLevelUnknown;
1149
1150 Return<void> hResult;
1151 if (mPluginV1_2 != NULL) {
1152 hResult = mPluginV1_2->getHdcpLevels_1_2(
1153 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1154 if (status == Status_V1_2::OK) {
1155 *connected = toHdcpLevel(hConnected);
1156 *max = toHdcpLevel(hMax);
1157 }
1158 err = toStatusT_1_2(status);
1159 });
1160 } else if (mPluginV1_1 != NULL) {
1161 hResult = mPluginV1_1->getHdcpLevels(
1162 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1163 if (status == Status::OK) {
1164 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1165 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1166 }
1167 err = toStatusT(status);
1168 });
1169 } else {
1170 return ERROR_DRM_CANNOT_HANDLE;
1171 }
1172
1173 return hResult.isOk() ? err : DEAD_OBJECT;
1174 }
1175
getNumberOfSessions(uint32_t * open,uint32_t * max) const1176 status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1177 Mutex::Autolock autoLock(mLock);
1178 INIT_CHECK();
1179
1180 if (open == NULL || max == NULL) {
1181 return BAD_VALUE;
1182 }
1183 status_t err = UNKNOWN_ERROR;
1184
1185 *open = 0;
1186 *max = 0;
1187
1188 if (mPluginV1_1 == NULL) {
1189 return ERROR_DRM_CANNOT_HANDLE;
1190 }
1191
1192 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1193 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1194 if (status == Status::OK) {
1195 *open = hOpen;
1196 *max = hMax;
1197 }
1198 err = toStatusT(status);
1199 }
1200 );
1201
1202 return hResult.isOk() ? err : DEAD_OBJECT;
1203 }
1204
getSecurityLevel(Vector<uint8_t> const & sessionId,DrmPlugin::SecurityLevel * level) const1205 status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1206 DrmPlugin::SecurityLevel *level) const {
1207 Mutex::Autolock autoLock(mLock);
1208 INIT_CHECK();
1209
1210 if (level == NULL) {
1211 return BAD_VALUE;
1212 }
1213 status_t err = UNKNOWN_ERROR;
1214
1215 if (mPluginV1_1 == NULL) {
1216 return ERROR_DRM_CANNOT_HANDLE;
1217 }
1218
1219 *level = DrmPlugin::kSecurityLevelUnknown;
1220
1221 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1222 [&](Status status, SecurityLevel hLevel) {
1223 if (status == Status::OK) {
1224 *level = toSecurityLevel(hLevel);
1225 }
1226 err = toStatusT(status);
1227 }
1228 );
1229
1230 return hResult.isOk() ? err : DEAD_OBJECT;
1231 }
1232
getOfflineLicenseKeySetIds(List<Vector<uint8_t>> & keySetIds) const1233 status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1234 Mutex::Autolock autoLock(mLock);
1235
1236 if (mInitCheck != OK) {
1237 return mInitCheck;
1238 }
1239
1240 if (mPluginV1_2 == NULL) {
1241 return ERROR_UNSUPPORTED;
1242 }
1243
1244 status_t err = UNKNOWN_ERROR;
1245
1246 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1247 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1248 if (status == Status::OK) {
1249 keySetIds = toKeySetIds(hKeySetIds);
1250 }
1251 err = toStatusT(status);
1252 }
1253 );
1254
1255 return hResult.isOk() ? err : DEAD_OBJECT;
1256 }
1257
removeOfflineLicense(Vector<uint8_t> const & keySetId)1258 status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1259 Mutex::Autolock autoLock(mLock);
1260
1261 if (mInitCheck != OK) {
1262 return mInitCheck;
1263 }
1264
1265 if (mPluginV1_2 == NULL) {
1266 return ERROR_UNSUPPORTED;
1267 }
1268
1269 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1270 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1271 }
1272
getOfflineLicenseState(Vector<uint8_t> const & keySetId,DrmPlugin::OfflineLicenseState * licenseState) const1273 status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1274 DrmPlugin::OfflineLicenseState *licenseState) const {
1275 Mutex::Autolock autoLock(mLock);
1276
1277 if (mInitCheck != OK) {
1278 return mInitCheck;
1279 }
1280
1281 if (mPluginV1_2 == NULL) {
1282 return ERROR_UNSUPPORTED;
1283 }
1284 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1285
1286 status_t err = UNKNOWN_ERROR;
1287
1288 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1289 [&](Status status, OfflineLicenseState hLicenseState) {
1290 if (status == Status::OK) {
1291 *licenseState = toOfflineLicenseState(hLicenseState);
1292 }
1293 err = toStatusT(status);
1294 }
1295 );
1296
1297 return hResult.isOk() ? err : DEAD_OBJECT;
1298 }
1299
getPropertyString(String8 const & name,String8 & value) const1300 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1301 Mutex::Autolock autoLock(mLock);
1302 return getPropertyStringInternal(name, value);
1303 }
1304
getPropertyStringInternal(String8 const & name,String8 & value) const1305 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1306 // This function is internal to the class and should only be called while
1307 // mLock is already held.
1308 INIT_CHECK();
1309
1310 status_t err = UNKNOWN_ERROR;
1311
1312 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1313 [&](Status status, const hidl_string& hValue) {
1314 if (status == Status::OK) {
1315 value = toString8(hValue);
1316 }
1317 err = toStatusT(status);
1318 }
1319 );
1320
1321 return hResult.isOk() ? err : DEAD_OBJECT;
1322 }
1323
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const1324 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1325 Mutex::Autolock autoLock(mLock);
1326 return getPropertyByteArrayInternal(name, value);
1327 }
1328
getPropertyByteArrayInternal(String8 const & name,Vector<uint8_t> & value) const1329 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1330 // This function is internal to the class and should only be called while
1331 // mLock is already held.
1332 INIT_CHECK();
1333
1334 status_t err = UNKNOWN_ERROR;
1335
1336 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1337 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1338 if (status == Status::OK) {
1339 value = toVector(hValue);
1340 }
1341 err = toStatusT(status);
1342 }
1343 );
1344
1345 err = hResult.isOk() ? err : DEAD_OBJECT;
1346 if (name == kPropertyDeviceUniqueId) {
1347 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1348 }
1349 return err;
1350 }
1351
setPropertyString(String8 const & name,String8 const & value) const1352 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1353 Mutex::Autolock autoLock(mLock);
1354 INIT_CHECK();
1355
1356 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
1357 toHidlString(value));
1358 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1359 }
1360
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const1361 status_t DrmHal::setPropertyByteArray(String8 const &name,
1362 Vector<uint8_t> const &value ) const {
1363 Mutex::Autolock autoLock(mLock);
1364 INIT_CHECK();
1365
1366 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
1367 toHidlVec(value));
1368 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1369 }
1370
getMetrics(PersistableBundle * metrics)1371 status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1372 if (metrics == nullptr) {
1373 return UNEXPECTED_NULL;
1374 }
1375 mMetrics.Export(metrics);
1376
1377 // Append vendor metrics if they are supported.
1378 if (mPluginV1_1 != NULL) {
1379 String8 vendor;
1380 String8 description;
1381 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1382 || vendor.isEmpty()) {
1383 ALOGE("Get vendor failed or is empty");
1384 vendor = "NONE";
1385 }
1386 if (getPropertyStringInternal(String8("description"), description) != OK
1387 || description.isEmpty()) {
1388 ALOGE("Get description failed or is empty.");
1389 description = "NONE";
1390 }
1391 vendor += ".";
1392 vendor += description;
1393
1394 hidl_vec<DrmMetricGroup> pluginMetrics;
1395 status_t err = UNKNOWN_ERROR;
1396
1397 Return<void> status = mPluginV1_1->getMetrics(
1398 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1399 if (status != Status::OK) {
1400 ALOGV("Error getting plugin metrics: %d", status);
1401 } else {
1402 PersistableBundle pluginBundle;
1403 if (MediaDrmMetrics::HidlMetricsToBundle(
1404 pluginMetrics, &pluginBundle) == OK) {
1405 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1406 }
1407 }
1408 err = toStatusT(status);
1409 });
1410 return status.isOk() ? err : DEAD_OBJECT;
1411 }
1412
1413 return OK;
1414 }
1415
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1416 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1417 String8 const &algorithm) {
1418 Mutex::Autolock autoLock(mLock);
1419 INIT_CHECK();
1420
1421 DrmSessionManager::Instance()->useSession(sessionId);
1422
1423 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1424 toHidlString(algorithm));
1425 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1426 }
1427
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)1428 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1429 String8 const &algorithm) {
1430 Mutex::Autolock autoLock(mLock);
1431 INIT_CHECK();
1432
1433 DrmSessionManager::Instance()->useSession(sessionId);
1434
1435 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1436 toHidlString(algorithm));
1437 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1438 }
1439
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)1440 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
1441 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1442 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1443 Mutex::Autolock autoLock(mLock);
1444 INIT_CHECK();
1445
1446 DrmSessionManager::Instance()->useSession(sessionId);
1447
1448 status_t err = UNKNOWN_ERROR;
1449
1450 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1451 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1452 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1453 if (status == Status::OK) {
1454 output = toVector(hOutput);
1455 }
1456 err = toStatusT(status);
1457 }
1458 );
1459
1460 return hResult.isOk() ? err : DEAD_OBJECT;
1461 }
1462
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)1463 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
1464 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1465 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
1466 Mutex::Autolock autoLock(mLock);
1467 INIT_CHECK();
1468
1469 DrmSessionManager::Instance()->useSession(sessionId);
1470
1471 status_t err = UNKNOWN_ERROR;
1472
1473 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1474 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1475 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1476 if (status == Status::OK) {
1477 output = toVector(hOutput);
1478 }
1479 err = toStatusT(status);
1480 }
1481 );
1482
1483 return hResult.isOk() ? err : DEAD_OBJECT;
1484 }
1485
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)1486 status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
1487 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1488 Vector<uint8_t> &signature) {
1489 Mutex::Autolock autoLock(mLock);
1490 INIT_CHECK();
1491
1492 DrmSessionManager::Instance()->useSession(sessionId);
1493
1494 status_t err = UNKNOWN_ERROR;
1495
1496 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1497 toHidlVec(keyId), toHidlVec(message),
1498 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1499 if (status == Status::OK) {
1500 signature = toVector(hSignature);
1501 }
1502 err = toStatusT(status);
1503 }
1504 );
1505
1506 return hResult.isOk() ? err : DEAD_OBJECT;
1507 }
1508
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)1509 status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
1510 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1511 Vector<uint8_t> const &signature, bool &match) {
1512 Mutex::Autolock autoLock(mLock);
1513 INIT_CHECK();
1514
1515 DrmSessionManager::Instance()->useSession(sessionId);
1516
1517 status_t err = UNKNOWN_ERROR;
1518
1519 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1520 toHidlVec(message), toHidlVec(signature),
1521 [&](Status status, bool hMatch) {
1522 if (status == Status::OK) {
1523 match = hMatch;
1524 } else {
1525 match = false;
1526 }
1527 err = toStatusT(status);
1528 }
1529 );
1530
1531 return hResult.isOk() ? err : DEAD_OBJECT;
1532 }
1533
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)1534 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
1535 String8 const &algorithm, Vector<uint8_t> const &message,
1536 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
1537 Mutex::Autolock autoLock(mLock);
1538 INIT_CHECK();
1539
1540 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1541 return -EPERM;
1542 }
1543
1544 DrmSessionManager::Instance()->useSession(sessionId);
1545
1546 status_t err = UNKNOWN_ERROR;
1547
1548 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1549 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1550 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1551 if (status == Status::OK) {
1552 signature = toVector(hSignature);
1553 }
1554 err = toStatusT(status);
1555 }
1556 );
1557
1558 return hResult.isOk() ? err : DEAD_OBJECT;
1559 }
1560
binderDied(const wp<IBinder> & the_late_who __unused)1561 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1562 {
1563 cleanup();
1564 }
1565
writeByteArray(Parcel & obj,hidl_vec<uint8_t> const & vec)1566 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1567 {
1568 if (vec.size()) {
1569 obj.writeInt32(vec.size());
1570 obj.write(vec.data(), vec.size());
1571 } else {
1572 obj.writeInt32(0);
1573 }
1574 }
1575
reportFrameworkMetrics() const1576 void DrmHal::reportFrameworkMetrics() const
1577 {
1578 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1579 item->generateSessionID();
1580 item->setPkgName(mMetrics.GetAppPackageName().c_str());
1581 String8 vendor;
1582 String8 description;
1583 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1584 if (result != OK) {
1585 ALOGE("Failed to get vendor from drm plugin: %d", result);
1586 } else {
1587 item->setCString("vendor", vendor.c_str());
1588 }
1589 result = getPropertyStringInternal(String8("description"), description);
1590 if (result != OK) {
1591 ALOGE("Failed to get description from drm plugin: %d", result);
1592 } else {
1593 item->setCString("description", description.c_str());
1594 }
1595
1596 std::string serializedMetrics;
1597 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1598 if (result != OK) {
1599 ALOGE("Failed to serialize framework metrics: %d", result);
1600 }
1601 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1602 serializedMetrics.size());
1603 if (!b64EncodedMetrics.empty()) {
1604 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
1605 }
1606 if (!item->selfrecord()) {
1607 ALOGE("Failed to self record framework metrics");
1608 }
1609 }
1610
reportPluginMetrics() const1611 void DrmHal::reportPluginMetrics() const
1612 {
1613 Vector<uint8_t> metricsVector;
1614 String8 vendor;
1615 String8 description;
1616 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1617 getPropertyStringInternal(String8("description"), description) == OK &&
1618 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1619 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1620 metricsVector.size());
1621 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1622 description, mAppPackageName);
1623 if (res != OK) {
1624 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1625 }
1626 }
1627 }
1628
1629 } // namespace android
1630