blob: 7df57a35e538453f8a7cdf9f9873db21ff39f400 [file] [log] [blame]
Kyle Zhang6605add2022-01-13 17:51:23 +00001/*
2 * Copyright (C) 2021 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 "DrmHalAidl"
19
20#include <android/binder_auto_utils.h>
21#include <android/binder_manager.h>
22#include <media/PluginMetricsReporting.h>
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/foundation/AString.h>
25#include <media/stagefright/foundation/base64.h>
26#include <media/stagefright/foundation/hexdump.h>
27#include <mediadrm/DrmHalAidl.h>
28#include <mediadrm/DrmSessionManager.h>
29#include <mediadrm/DrmUtils.h>
30
31using ::android::DrmUtils::toStatusTAidl;
32
33using ::aidl::android::hardware::drm::DrmMetricNamedValue;
34using ::aidl::android::hardware::drm::DrmMetricValue;
35using ::aidl::android::hardware::drm::HdcpLevel;
36using ::aidl::android::hardware::drm::HdcpLevels;
37using ::aidl::android::hardware::drm::KeyRequest;
38using ::aidl::android::hardware::drm::KeyRequestType;
39using ::aidl::android::hardware::drm::KeySetId;
40using ::aidl::android::hardware::drm::KeyStatus;
41using ::aidl::android::hardware::drm::KeyStatusType;
42using ::aidl::android::hardware::drm::KeyType;
43using ::aidl::android::hardware::drm::KeyValue;
44using ::aidl::android::hardware::drm::NumberOfSessions;
45using ::aidl::android::hardware::drm::OfflineLicenseState;
46using ::aidl::android::hardware::drm::OpaqueData;
47using ::aidl::android::hardware::drm::ProvideProvisionResponseResult;
48using ::aidl::android::hardware::drm::ProvisionRequest;
49using ::aidl::android::hardware::drm::SecureStop;
50using ::aidl::android::hardware::drm::SecureStopId;
51using ::aidl::android::hardware::drm::SecurityLevel;
52using ::aidl::android::hardware::drm::Status;
53using ::aidl::android::hardware::drm::Uuid;
54using DrmMetricGroupAidl = ::aidl::android::hardware::drm::DrmMetricGroup;
55using DrmMetricGroupHidl = ::android::hardware::drm::V1_1::DrmMetricGroup;
56using DrmMetricAidl = ::aidl::android::hardware::drm::DrmMetric;
57using DrmMetricHidl = ::android::hardware::drm::V1_1::DrmMetricGroup::Metric;
58using ValueHidl = ::android::hardware::drm::V1_1::DrmMetricGroup::Value;
59using AttributeHidl = ::android::hardware::drm::V1_1::DrmMetricGroup::Attribute;
60using IDrmPluginAidl = ::aidl::android::hardware::drm::IDrmPlugin;
61using EventTypeAidl = ::aidl::android::hardware::drm::EventType;
62using KeyStatusAidl = ::aidl::android::hardware::drm::KeyStatus;
63using ::android::hardware::hidl_vec;
64
65namespace {
66
67constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
68constexpr char kEqualsSign[] = "=";
69
70template <typename T>
71std::string toBase64StringNoPad(const T* data, size_t size) {
72 // Note that the base 64 conversion only works with arrays of single-byte
73 // values. If the source is empty or is not an array of single-byte values,
74 // return empty string.
75 if (size == 0 || sizeof(data[0]) != 1) {
76 return "";
77 }
78
79 android::AString outputString;
80 encodeBase64(data, size, &outputString);
81 // Remove trailing equals padding if it exists.
82 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
83 outputString.erase(outputString.size() - 1, 1);
84 }
85
86 return std::string(outputString.c_str(), outputString.size());
87}
88
89} // anonymous namespace
90
91namespace android {
92
93#define INIT_CHECK() \
94 { \
95 if (mInitCheck != OK) return mInitCheck; \
96 }
97
98static Uuid toAidlUuid(const uint8_t* uuid) {
99 Uuid uuidAidl;
100 uuidAidl.uuid = std::vector<uint8_t>(uuid, uuid + 16);
101 return uuidAidl;
102}
103
104template <typename Byte = uint8_t>
105static std::vector<Byte> toStdVec(const Vector<uint8_t>& vector) {
106 auto v = reinterpret_cast<const Byte*>(vector.array());
107 std::vector<Byte> vec(v, v + vector.size());
108 return vec;
109}
110
111static const Vector<uint8_t> toVector(const std::vector<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
117static String8 toString8(const std::string& string) {
118 return String8(string.c_str());
119}
120
121static std::string toStdString(const String8& string8) {
122 return std::string(string8.string());
123}
124
125static std::vector<KeyValue> toKeyValueVector(const KeyedVector<String8, String8>& keyedVector) {
126 std::vector<KeyValue> stdKeyedVector;
127 for (size_t i = 0; i < keyedVector.size(); i++) {
128 KeyValue keyValue;
129 keyValue.key = toStdString(keyedVector.keyAt(i));
130 keyValue.value = toStdString(keyedVector.valueAt(i));
131 stdKeyedVector.push_back(keyValue);
132 }
133 return stdKeyedVector;
134}
135
136static KeyedVector<String8, String8> toKeyedVector(const std::vector<KeyValue>& keyValueVec) {
137 KeyedVector<String8, String8> keyedVector;
138 for (size_t i = 0; i < keyValueVec.size(); i++) {
139 keyedVector.add(toString8(keyValueVec[i].key), toString8(keyValueVec[i].value));
140 }
141 return keyedVector;
142}
143
144static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
145 switch (keyRequestType) {
146 case KeyRequestType::INITIAL:
147 return DrmPlugin::kKeyRequestType_Initial;
148 break;
149 case KeyRequestType::RENEWAL:
150 return DrmPlugin::kKeyRequestType_Renewal;
151 break;
152 case KeyRequestType::RELEASE:
153 return DrmPlugin::kKeyRequestType_Release;
154 break;
155 case KeyRequestType::NONE:
156 return DrmPlugin::kKeyRequestType_None;
157 break;
158 case KeyRequestType::UPDATE:
159 return DrmPlugin::kKeyRequestType_Update;
160 break;
161 default:
162 return DrmPlugin::kKeyRequestType_Unknown;
163 break;
164 }
165}
166
167static List<Vector<uint8_t>> toSecureStops(const std::vector<SecureStop>& aSecureStops) {
168 List<Vector<uint8_t>> secureStops;
169 for (size_t i = 0; i < aSecureStops.size(); i++) {
170 secureStops.push_back(toVector(aSecureStops[i].opaqueData));
171 }
172 return secureStops;
173}
174
175static List<Vector<uint8_t>> toSecureStopIds(const std::vector<SecureStopId>& aSecureStopIds) {
176 List<Vector<uint8_t>> secureStopIds;
177 for (size_t i = 0; i < aSecureStopIds.size(); i++) {
178 secureStopIds.push_back(toVector(aSecureStopIds[i].secureStopId));
179 }
180 return secureStopIds;
181}
182
183static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
184 switch (level) {
185 case HdcpLevel::HDCP_NONE:
186 return DrmPlugin::kHdcpNone;
187 case HdcpLevel::HDCP_V1:
188 return DrmPlugin::kHdcpV1;
189 case HdcpLevel::HDCP_V2:
190 return DrmPlugin::kHdcpV2;
191 case HdcpLevel::HDCP_V2_1:
192 return DrmPlugin::kHdcpV2_1;
193 case HdcpLevel::HDCP_V2_2:
194 return DrmPlugin::kHdcpV2_2;
195 case HdcpLevel::HDCP_V2_3:
196 return DrmPlugin::kHdcpV2_3;
197 case HdcpLevel::HDCP_NO_OUTPUT:
198 return DrmPlugin::kHdcpNoOutput;
199 default:
200 return DrmPlugin::kHdcpLevelUnknown;
201 }
202}
203
204static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
205 switch (level) {
206 case SecurityLevel::SW_SECURE_CRYPTO:
207 return DrmPlugin::kSecurityLevelSwSecureCrypto;
208 case SecurityLevel::SW_SECURE_DECODE:
209 return DrmPlugin::kSecurityLevelSwSecureDecode;
210 case SecurityLevel::HW_SECURE_CRYPTO:
211 return DrmPlugin::kSecurityLevelHwSecureCrypto;
212 case SecurityLevel::HW_SECURE_DECODE:
213 return DrmPlugin::kSecurityLevelHwSecureDecode;
214 case SecurityLevel::HW_SECURE_ALL:
215 return DrmPlugin::kSecurityLevelHwSecureAll;
216 case SecurityLevel::DEFAULT:
217 return DrmPlugin::kSecurityLevelMax;
218 default:
219 return DrmPlugin::kSecurityLevelUnknown;
220 }
221}
222
223static SecurityLevel toAidlSecurityLevel(DrmPlugin::SecurityLevel level) {
224 switch (level) {
225 case DrmPlugin::kSecurityLevelSwSecureCrypto:
226 return SecurityLevel::SW_SECURE_CRYPTO;
227 case DrmPlugin::kSecurityLevelSwSecureDecode:
228 return SecurityLevel::SW_SECURE_DECODE;
229 case DrmPlugin::kSecurityLevelHwSecureCrypto:
230 return SecurityLevel::HW_SECURE_CRYPTO;
231 case DrmPlugin::kSecurityLevelHwSecureDecode:
232 return SecurityLevel::HW_SECURE_DECODE;
233 case DrmPlugin::kSecurityLevelHwSecureAll:
234 return SecurityLevel::HW_SECURE_ALL;
235 case DrmPlugin::kSecurityLevelMax:
236 return SecurityLevel::DEFAULT;
237 default:
238 return SecurityLevel::UNKNOWN;
239 }
240}
241
242static List<Vector<uint8_t>> toKeySetIds(const std::vector<KeySetId>& hKeySetIds) {
243 List<Vector<uint8_t>> keySetIds;
244 for (size_t i = 0; i < hKeySetIds.size(); i++) {
245 keySetIds.push_back(toVector(hKeySetIds[i].keySetId));
246 }
247 return keySetIds;
248}
249
250static DrmPlugin::OfflineLicenseState toOfflineLicenseState(OfflineLicenseState licenseState) {
251 switch (licenseState) {
252 case OfflineLicenseState::USABLE:
253 return DrmPlugin::kOfflineLicenseStateUsable;
254 case OfflineLicenseState::INACTIVE:
255 return DrmPlugin::kOfflineLicenseStateReleased;
256 default:
257 return DrmPlugin::kOfflineLicenseStateUnknown;
258 }
259}
260
261template <typename T = uint8_t>
262static hidl_vec<T> toHidlVec(const Vector<T>& vector) {
263 hidl_vec<T> vec;
264 vec.setToExternal(const_cast<T*>(vector.array()), vector.size());
265 return vec;
266}
267
268Mutex DrmHalAidl::mLock;
269
270static hidl_vec<DrmMetricGroupHidl> toDrmMetricGroupHidl(std::vector<DrmMetricGroupAidl> result) {
271 Vector<DrmMetricGroupHidl> resultHidl;
272 for (auto r : result) {
273 DrmMetricGroupHidl re;
274 Vector<DrmMetricHidl> tmpMetric;
275 for (auto m : r.metrics) {
276 DrmMetricHidl me;
277 me.name = m.name;
278 Vector<AttributeHidl> aTmp;
279 for (auto attr : m.attributes) {
280 AttributeHidl attrHidl;
281 attrHidl.name = attr.name;
282
283 switch (attr.value.getTag()) {
284 case DrmMetricValue::Tag::int64Value:
285 attrHidl.type = DrmMetricGroupHidl::ValueType::INT64_TYPE;
286 attrHidl.int64Value = attr.value.get<DrmMetricValue::Tag::int64Value>();
287 break;
288 case DrmMetricValue::Tag::doubleValue:
289 attrHidl.type = DrmMetricGroupHidl::ValueType::DOUBLE_TYPE;
290 attrHidl.doubleValue = attr.value.get<DrmMetricValue::Tag::doubleValue>();
291 break;
292 case DrmMetricValue::Tag::stringValue:
293 attrHidl.type = DrmMetricGroupHidl::ValueType::STRING_TYPE;
294 attrHidl.stringValue = attr.value.get<DrmMetricValue::Tag::stringValue>();
295 break;
296 default:
297 break;
298 }
299
300 aTmp.push_back(attrHidl);
301 }
302
303 me.attributes = toHidlVec<AttributeHidl>(aTmp);
304
305 Vector<ValueHidl> vTmp;
306 for (auto value : m.values) {
307 ValueHidl valueHidl;
308 valueHidl.componentName = value.name;
309 switch (value.value.getTag()) {
310 case DrmMetricValue::Tag::int64Value:
311 valueHidl.type = DrmMetricGroupHidl::ValueType::INT64_TYPE;
312 valueHidl.int64Value = value.value.get<DrmMetricValue::Tag::int64Value>();
313 break;
314 case DrmMetricValue::Tag::doubleValue:
315 valueHidl.type = DrmMetricGroupHidl::ValueType::DOUBLE_TYPE;
316 valueHidl.doubleValue = value.value.get<DrmMetricValue::Tag::doubleValue>();
317 break;
318 case DrmMetricValue::Tag::stringValue:
319 valueHidl.type = DrmMetricGroupHidl::ValueType::STRING_TYPE;
320 valueHidl.stringValue = value.value.get<DrmMetricValue::Tag::stringValue>();
321 break;
322 default:
323 break;
324 }
325
326 vTmp.push_back(valueHidl);
327 }
328
329 me.values = toHidlVec<ValueHidl>(vTmp);
330 tmpMetric.push_back(me);
331 }
332
333 re.metrics = toHidlVec<DrmMetricHidl>(tmpMetric);
334 resultHidl.push_back(re);
335 }
336
337 return toHidlVec<DrmMetricGroupHidl>(resultHidl);
338}
339
340// DrmSessionClient Definition
341
342struct DrmHalAidl::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
343 explicit DrmSessionClient(DrmHalAidl* drm, const Vector<uint8_t>& sessionId)
344 : mSessionId(sessionId), mDrm(drm) {}
345
346 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
347 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
348
349 const Vector<uint8_t> mSessionId;
350
351 virtual ~DrmSessionClient();
352
353 private:
354 wp<DrmHalAidl> mDrm;
355
356 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
357};
358
359::ndk::ScopedAStatus DrmHalAidl::DrmSessionClient::reclaimResource(bool* _aidl_return) {
360 auto sessionId = mSessionId;
361 sp<DrmHalAidl> drm = mDrm.promote();
362 if (drm == NULL) {
363 *_aidl_return = true;
364 return ::ndk::ScopedAStatus::ok();
365 }
366 status_t err = drm->closeSession(sessionId);
367 if (err != OK) {
368 *_aidl_return = false;
369 return ::ndk::ScopedAStatus::ok();
370 }
371 drm->onEvent(EventTypeAidl::SESSION_RECLAIMED, toHidlVec(sessionId), hidl_vec<uint8_t>());
372 *_aidl_return = true;
373 return ::ndk::ScopedAStatus::ok();
374}
375
376::ndk::ScopedAStatus DrmHalAidl::DrmSessionClient::getName(::std::string* _aidl_return) {
377 String8 name;
378 sp<DrmHalAidl> drm = mDrm.promote();
379 if (drm == NULL) {
380 name.append("<deleted>");
381 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK || name.isEmpty()) {
382 name.append("<Get vendor failed or is empty>");
383 }
384 name.append("[");
385 for (size_t i = 0; i < mSessionId.size(); ++i) {
386 name.appendFormat("%02x", mSessionId[i]);
387 }
388 name.append("]");
389 *_aidl_return = name;
390 return ::ndk::ScopedAStatus::ok();
391}
392
393DrmHalAidl::DrmSessionClient::~DrmSessionClient() {
394 DrmSessionManager::Instance()->removeSession(mSessionId);
395}
396
397// DrmHalAidl methods
398DrmHalAidl::DrmHalAidl()
399 : mFactories(makeDrmFactories()),
400 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}
401
402status_t DrmHalAidl::initCheck() const {
403 return mInitCheck;
404}
405
406DrmHalAidl::~DrmHalAidl() {}
407
408std::vector<std::shared_ptr<IDrmFactoryAidl>> DrmHalAidl::makeDrmFactories() {
409 std::vector<std::shared_ptr<IDrmFactoryAidl>> factories;
410 AServiceManager_forEachDeclaredInstance(
411 IDrmFactoryAidl::descriptor, static_cast<void*>(&factories),
412 [](const char* instance, void* context) {
413 auto fullName = std::string(IDrmFactoryAidl::descriptor) + "/" + std::string(instance);
414 auto factory = IDrmFactoryAidl::fromBinder(
415 ::ndk::SpAIBinder(AServiceManager_getService(fullName.c_str())));
416 if (factory == nullptr) {
417 ALOGE("not found IDrmFactory. Instance name:[%s]", fullName.c_str());
418 return;
419 }
420
421 ALOGI("found IDrmFactory. Instance name:[%s]", fullName.c_str());
422 static_cast<std::vector<std::shared_ptr<IDrmFactoryAidl>>*>(context)->emplace_back(
423 factory);
424 });
425
426 return factories;
427}
428
429status_t DrmHalAidl::setListener(const sp<IDrmClient>& listener) {
430 Mutex::Autolock lock(mEventLock);
431 mListener = listener;
432 return NO_ERROR;
433}
434
435status_t DrmHalAidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
436 DrmPlugin::SecurityLevel level, bool* isSupported) {
437 Mutex::Autolock autoLock(mLock);
438 *isSupported = false;
439 Uuid uuidAidl = toAidlUuid(uuid);
440 SecurityLevel levelAidl = static_cast<SecurityLevel>((int32_t)level);
441 std::string mimeTypeStr = mimeType.string();
442 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
443 if (mFactories[i]
444 ->isCryptoSchemeSupported(uuidAidl, mimeTypeStr, levelAidl, isSupported)
445 .isOk()) {
446 if (*isSupported) break;
447 }
448 }
449
450 return OK;
451}
452
453status_t DrmHalAidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
454 Mutex::Autolock autoLock(mLock);
455
456 Uuid uuidAidl = toAidlUuid(uuid);
457 std::string appPackageNameAidl = toStdString(appPackageName);
458 std::shared_ptr<IDrmPluginAidl> pluginAidl;
459 mMetrics.SetAppPackageName(appPackageName);
460 mMetrics.SetAppUid(AIBinder_getCallingUid());
461 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
462 ::ndk::ScopedAStatus status =
463 mFactories[i]->createPlugin(uuidAidl, appPackageNameAidl, &pluginAidl);
464 if (status.isOk()) {
465 if (pluginAidl != NULL) {
466 mPlugin = pluginAidl;
467 break;
468 }
469 } else {
470 DrmUtils::LOG2BE(uuid, "Failed to make drm plugin: %d",
471 status.getServiceSpecificError());
472 }
473 }
474
475 if (mPlugin == NULL) {
476 DrmUtils::LOG2BE(uuid, "No supported hal instance found");
477 mInitCheck = ERROR_UNSUPPORTED;
478 } else {
479 mInitCheck = OK;
480
481 if (!mPlugin->setListener(shared_from_this()).isOk()) {
482 mInitCheck = DEAD_OBJECT;
483 }
484
485 if (mInitCheck != OK) {
486 mPlugin.reset();
487 }
488 }
489
490 return mInitCheck;
491}
492
493status_t DrmHalAidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
494 Mutex::Autolock autoLock(mLock);
495 INIT_CHECK();
496
497 SecurityLevel aSecurityLevel = toAidlSecurityLevel(level);
498
499 if (aSecurityLevel == SecurityLevel::UNKNOWN) {
500 return ERROR_DRM_CANNOT_HANDLE;
501 }
502
503 status_t err = UNKNOWN_ERROR;
504 bool retry = true;
505 do {
506 std::vector<uint8_t> aSessionId;
507
508 ::ndk::ScopedAStatus status = mPlugin->openSession(aSecurityLevel, &aSessionId);
509 if (status.isOk()) sessionId = toVector(aSessionId);
510 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
511
512 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
513 mLock.unlock();
514 // reclaimSession may call back to closeSession, since mLock is
515 // shared between Drm instances, we should unlock here to avoid
516 // deadlock.
517 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
518 mLock.lock();
519 } else {
520 retry = false;
521 }
522 } while (retry);
523
524 if (err == OK) {
525 std::shared_ptr<DrmSessionClient> client =
526 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
527 DrmSessionManager::Instance()->addSession(
528 AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
529 sessionId);
530 mOpenSessions.push_back(client);
531 mMetrics.SetSessionStart(sessionId);
532 }
533
534 mMetrics.mOpenSessionCounter.Increment(err);
535 return err;
536}
537
538status_t DrmHalAidl::closeSession(Vector<uint8_t> const& sessionId) {
539 Mutex::Autolock autoLock(mLock);
540 INIT_CHECK();
541
542 std::vector<uint8_t> sessionIdAidl = toStdVec(sessionId);
543 ::ndk::ScopedAStatus status = mPlugin->closeSession(sessionIdAidl);
544 if (status.isOk()) {
545 DrmSessionManager::Instance()->removeSession(sessionId);
546 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
547 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
548 mOpenSessions.erase(i);
549 break;
550 }
551 }
552
553 status_t response = toStatusTAidl(status.getServiceSpecificError());
554 mMetrics.SetSessionEnd(sessionId);
555 mMetrics.mCloseSessionCounter.Increment(response);
556 return response;
557 }
558 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
559 return DEAD_OBJECT;
560}
561
562status_t DrmHalAidl::getKeyRequest(Vector<uint8_t> const& sessionId,
563 Vector<uint8_t> const& initData, String8 const& mimeType,
564 DrmPlugin::KeyType keyType,
565 KeyedVector<String8, String8> const& optionalParameters,
566 Vector<uint8_t>& request, String8& defaultUrl,
567 DrmPlugin::KeyRequestType* keyRequestType) {
568 Mutex::Autolock autoLock(mLock);
569 INIT_CHECK();
570 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
571
572 DrmSessionManager::Instance()->useSession(sessionId);
573
574 KeyType aKeyType;
575 if (keyType == DrmPlugin::kKeyType_Streaming) {
576 aKeyType = KeyType::STREAMING;
577 } else if (keyType == DrmPlugin::kKeyType_Offline) {
578 aKeyType = KeyType::OFFLINE;
579 } else if (keyType == DrmPlugin::kKeyType_Release) {
580 aKeyType = KeyType::RELEASE;
581 } else {
582 keyRequestTimer.SetAttribute(BAD_VALUE);
583 return BAD_VALUE;
584 }
585
586 status_t err = UNKNOWN_ERROR;
587
588 std::vector<uint8_t> sessionIdAidl = toStdVec(sessionId);
589 std::vector<uint8_t> initDataAidl = toStdVec(initData);
590 KeyRequest keyRequest;
591
592 ::ndk::ScopedAStatus status =
593 mPlugin->getKeyRequest(sessionIdAidl, initDataAidl, toStdString(mimeType), aKeyType,
594 toKeyValueVector(optionalParameters), &keyRequest);
595 if (status.isOk()) {
596 request = toVector(keyRequest.request);
597 defaultUrl = toString8(keyRequest.defaultUrl);
598 *keyRequestType = toKeyRequestType(keyRequest.requestType);
599 }
600
601 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
602 keyRequestTimer.SetAttribute(err);
603 return err;
604}
605
606status_t DrmHalAidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
607 Vector<uint8_t> const& response,
608 Vector<uint8_t>& keySetId) {
609 Mutex::Autolock autoLock(mLock);
610 INIT_CHECK();
611 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
612
613 DrmSessionManager::Instance()->useSession(sessionId);
614
615 status_t err = UNKNOWN_ERROR;
616
617 std::vector<uint8_t> sessionIdAidl = toStdVec(sessionId);
618 std::vector<uint8_t> responseAidl = toStdVec(response);
619 KeySetId keySetIdsAidl;
620 ::ndk::ScopedAStatus status =
621 mPlugin->provideKeyResponse(sessionIdAidl, responseAidl, &keySetIdsAidl);
622
623 if (status.isOk()) keySetId = toVector(keySetIdsAidl.keySetId);
624 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
625 keyResponseTimer.SetAttribute(err);
626 return err;
627}
628
629status_t DrmHalAidl::removeKeys(Vector<uint8_t> const& keySetId) {
630 Mutex::Autolock autoLock(mLock);
631 INIT_CHECK();
632
633 ::ndk::ScopedAStatus status = mPlugin->removeKeys(toStdVec(keySetId));
634 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
635}
636
637status_t DrmHalAidl::restoreKeys(Vector<uint8_t> const& sessionId,
638 Vector<uint8_t> const& keySetId) {
639 Mutex::Autolock autoLock(mLock);
640 INIT_CHECK();
641
642 DrmSessionManager::Instance()->useSession(sessionId);
643
644 KeySetId keySetIdsAidl;
645 keySetIdsAidl.keySetId = toStdVec(keySetId);
646 ::ndk::ScopedAStatus status = mPlugin->restoreKeys(toStdVec(sessionId), keySetIdsAidl);
647 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
648}
649
650status_t DrmHalAidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
651 KeyedVector<String8, String8>& infoMap) const {
652 Mutex::Autolock autoLock(mLock);
653 INIT_CHECK();
654
655 DrmSessionManager::Instance()->useSession(sessionId);
656
657 std::vector<KeyValue> infoMapAidl;
658 ::ndk::ScopedAStatus status = mPlugin->queryKeyStatus(toStdVec(sessionId), &infoMapAidl);
659
660 infoMap = toKeyedVector(infoMapAidl);
661
662 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
663}
664
665status_t DrmHalAidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
666 Vector<uint8_t>& request, String8& defaultUrl) {
667 Mutex::Autolock autoLock(mLock);
668 INIT_CHECK();
669
670 status_t err = UNKNOWN_ERROR;
671
672 ProvisionRequest requestAidl;
673 ::ndk::ScopedAStatus status = mPlugin->getProvisionRequest(
674 toStdString(certType), toStdString(certAuthority), &requestAidl);
675
676 request = toVector(requestAidl.request);
677 defaultUrl = toString8(requestAidl.defaultUrl);
678
679 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
680 mMetrics.mGetProvisionRequestCounter.Increment(err);
681 return err;
682}
683
684status_t DrmHalAidl::provideProvisionResponse(Vector<uint8_t> const& response,
685 Vector<uint8_t>& certificate,
686 Vector<uint8_t>& wrappedKey) {
687 Mutex::Autolock autoLock(mLock);
688 INIT_CHECK();
689
690 status_t err = UNKNOWN_ERROR;
691 ProvideProvisionResponseResult result;
692 ::ndk::ScopedAStatus status = mPlugin->provideProvisionResponse(toStdVec(response), &result);
693
694 certificate = toVector(result.certificate);
695 wrappedKey = toVector(result.wrappedKey);
696 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
697 mMetrics.mProvideProvisionResponseCounter.Increment(err);
698 return err;
699}
700
701status_t DrmHalAidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
702 Mutex::Autolock autoLock(mLock);
703 INIT_CHECK();
704
705 std::vector<SecureStop> result;
706 ::ndk::ScopedAStatus status = mPlugin->getSecureStops(&result);
707
708 secureStops = toSecureStops(result);
709
710 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
711}
712
713status_t DrmHalAidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
714 Mutex::Autolock autoLock(mLock);
715 INIT_CHECK();
716
717 std::vector<SecureStopId> result;
718 ::ndk::ScopedAStatus status = mPlugin->getSecureStopIds(&result);
719
720 secureStopIds = toSecureStopIds(result);
721
722 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
723}
724
725status_t DrmHalAidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
726 Mutex::Autolock autoLock(mLock);
727 INIT_CHECK();
728
729 SecureStopId ssidAidl;
730 ssidAidl.secureStopId = toStdVec(ssid);
731
732 SecureStop result;
733 ::ndk::ScopedAStatus status = mPlugin->getSecureStop(ssidAidl, &result);
734
735 secureStop = toVector(result.opaqueData);
736
737 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
738}
739
740status_t DrmHalAidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
741 Mutex::Autolock autoLock(mLock);
742 INIT_CHECK();
743
744 OpaqueData ssId;
745 ssId.opaqueData = toStdVec(ssRelease);
746 ::ndk::ScopedAStatus status = mPlugin->releaseSecureStops(ssId);
747
748 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
749}
750
751status_t DrmHalAidl::removeSecureStop(Vector<uint8_t> const& ssid) {
752 Mutex::Autolock autoLock(mLock);
753
754 INIT_CHECK();
755
756 SecureStopId ssidAidl;
757 ssidAidl.secureStopId = toStdVec(ssid);
758 ::ndk::ScopedAStatus status = mPlugin->removeSecureStop(ssidAidl);
759 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
760}
761
762status_t DrmHalAidl::removeAllSecureStops() {
763 Mutex::Autolock autoLock(mLock);
764 INIT_CHECK();
765
766 ::ndk::ScopedAStatus status = mPlugin->releaseAllSecureStops();
767 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
768}
769
770status_t DrmHalAidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
771 DrmPlugin::HdcpLevel* max) const {
772 Mutex::Autolock autoLock(mLock);
773 INIT_CHECK();
774
775 if (connected == NULL || max == NULL) {
776 return BAD_VALUE;
777 }
778
779 *connected = DrmPlugin::kHdcpLevelUnknown;
780 *max = DrmPlugin::kHdcpLevelUnknown;
781
782 HdcpLevels lvlsAidl;
783 ::ndk::ScopedAStatus status = mPlugin->getHdcpLevels(&lvlsAidl);
784
785 *connected = toHdcpLevel(lvlsAidl.connectedLevel);
786 *max = toHdcpLevel(lvlsAidl.maxLevel);
787
788 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
789}
790
791status_t DrmHalAidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
792 Mutex::Autolock autoLock(mLock);
793 INIT_CHECK();
794
795 if (open == NULL || max == NULL) {
796 return BAD_VALUE;
797 }
798
799 *open = 0;
800 *max = 0;
801
802 NumberOfSessions result;
803 ::ndk::ScopedAStatus status = mPlugin->getNumberOfSessions(&result);
804
805 *open = result.currentSessions;
806 *max = result.maxSessions;
807
808 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
809}
810
811status_t DrmHalAidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
812 DrmPlugin::SecurityLevel* level) const {
813 Mutex::Autolock autoLock(mLock);
814 INIT_CHECK();
815
816 if (level == NULL) {
817 return BAD_VALUE;
818 }
819
820 *level = DrmPlugin::kSecurityLevelUnknown;
821
822 SecurityLevel result;
823 ::ndk::ScopedAStatus status = mPlugin->getSecurityLevel(toStdVec(sessionId), &result);
824
825 *level = toSecurityLevel(result);
826
827 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
828}
829
830status_t DrmHalAidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
831 Mutex::Autolock autoLock(mLock);
832 INIT_CHECK();
833
834 std::vector<KeySetId> result;
835 ::ndk::ScopedAStatus status = mPlugin->getOfflineLicenseKeySetIds(&result);
836
837 keySetIds = toKeySetIds(result);
838
839 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
840}
841
842status_t DrmHalAidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
843 Mutex::Autolock autoLock(mLock);
844 INIT_CHECK();
845
846 KeySetId keySetIdAidl;
847 keySetIdAidl.keySetId = toStdVec(keySetId);
848 ::ndk::ScopedAStatus status = mPlugin->removeOfflineLicense(keySetIdAidl);
849 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
850}
851
852status_t DrmHalAidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
853 DrmPlugin::OfflineLicenseState* licenseState) const {
854 Mutex::Autolock autoLock(mLock);
855
856 INIT_CHECK();
857 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
858
859 KeySetId keySetIdAidl;
860 keySetIdAidl.keySetId = toStdVec(keySetId);
861
862 OfflineLicenseState result;
863 ::ndk::ScopedAStatus status = mPlugin->getOfflineLicenseState(keySetIdAidl, &result);
864
865 *licenseState = toOfflineLicenseState(result);
866
867 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
868}
869
870status_t DrmHalAidl::getPropertyString(String8 const& name, String8& value) const {
871 Mutex::Autolock autoLock(mLock);
872 return getPropertyStringInternal(name, value);
873}
874
875status_t DrmHalAidl::getPropertyStringInternal(String8 const& name, String8& value) const {
876 // This function is internal to the class and should only be called while
877 // mLock is already held.
878 INIT_CHECK();
879
880 std::string result;
881 ::ndk::ScopedAStatus status = mPlugin->getPropertyString(toStdString(name), &result);
882
883 value = toString8(result);
884
885 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
886}
887
888status_t DrmHalAidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
889 Mutex::Autolock autoLock(mLock);
890 return getPropertyByteArrayInternal(name, value);
891}
892
893status_t DrmHalAidl::getPropertyByteArrayInternal(String8 const& name,
894 Vector<uint8_t>& value) const {
895 // This function is internal to the class and should only be called while
896 // mLock is already held.
897 INIT_CHECK();
898
899 status_t err = UNKNOWN_ERROR;
900
901 std::vector<uint8_t> result;
902 ::ndk::ScopedAStatus status = mPlugin->getPropertyByteArray(toStdString(name), &result);
903
904 value = toVector(result);
905 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
906 if (name == kPropertyDeviceUniqueId) {
907 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
908 }
909 return err;
910}
911
912status_t DrmHalAidl::setPropertyString(String8 const& name, String8 const& value) const {
913 Mutex::Autolock autoLock(mLock);
914 INIT_CHECK();
915
916 ::ndk::ScopedAStatus status = mPlugin->setPropertyString(toStdString(name), toStdString(value));
917 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
918}
919
920status_t DrmHalAidl::setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const {
921 Mutex::Autolock autoLock(mLock);
922 INIT_CHECK();
923
924 ::ndk::ScopedAStatus status = mPlugin->setPropertyByteArray(toStdString(name), toStdVec(value));
925 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
926}
927
928status_t DrmHalAidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
929 if (consumer == nullptr) {
930 return UNEXPECTED_NULL;
931 }
932 consumer->consumeFrameworkMetrics(mMetrics);
933
934 // Append vendor metrics if they are supported.
935
936 String8 vendor;
937 String8 description;
938 if (getPropertyStringInternal(String8("vendor"), vendor) != OK || vendor.isEmpty()) {
939 ALOGE("Get vendor failed or is empty");
940 vendor = "NONE";
941 }
942 if (getPropertyStringInternal(String8("description"), description) != OK ||
943 description.isEmpty()) {
944 ALOGE("Get description failed or is empty.");
945 description = "NONE";
946 }
947 vendor += ".";
948 vendor += description;
949
950 hidl_vec<DrmMetricGroupHidl> pluginMetrics;
951 status_t err = UNKNOWN_ERROR;
952
953 std::vector<DrmMetricGroupAidl> result;
954 ::ndk::ScopedAStatus status = mPlugin->getMetrics(&result);
955
956 if (status.isOk()) {
957 pluginMetrics = toDrmMetricGroupHidl(result);
958 consumer->consumeHidlMetrics(vendor, pluginMetrics);
959 }
960
961 err = status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
962
963 return err;
964}
965
966status_t DrmHalAidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
967 String8 const& algorithm) {
968 Mutex::Autolock autoLock(mLock);
969 INIT_CHECK();
970
971 DrmSessionManager::Instance()->useSession(sessionId);
972
973 ::ndk::ScopedAStatus status =
974 mPlugin->setCipherAlgorithm(toStdVec(sessionId), toStdString(algorithm));
975 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
976}
977
978status_t DrmHalAidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
979 Mutex::Autolock autoLock(mLock);
980 INIT_CHECK();
981
982 DrmSessionManager::Instance()->useSession(sessionId);
983
984 ::ndk::ScopedAStatus status =
985 mPlugin->setMacAlgorithm(toStdVec(sessionId), toStdString(algorithm));
986 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
987}
988
989status_t DrmHalAidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
990 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
991 Vector<uint8_t>& output) {
992 Mutex::Autolock autoLock(mLock);
993 INIT_CHECK();
994
995 DrmSessionManager::Instance()->useSession(sessionId);
996
997 std::vector<uint8_t> result;
998 ::ndk::ScopedAStatus status = mPlugin->encrypt(toStdVec(sessionId), toStdVec(keyId),
999 toStdVec(input), toStdVec(iv), &result);
1000
1001 output = toVector(result);
1002
1003 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
1004}
1005
1006status_t DrmHalAidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1007 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
1008 Vector<uint8_t>& output) {
1009 Mutex::Autolock autoLock(mLock);
1010 INIT_CHECK();
1011
1012 DrmSessionManager::Instance()->useSession(sessionId);
1013
1014 std::vector<uint8_t> result;
1015 ::ndk::ScopedAStatus status = mPlugin->decrypt(toStdVec(sessionId), toStdVec(keyId),
1016 toStdVec(input), toStdVec(iv), &result);
1017
1018 output = toVector(result);
1019
1020 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
1021}
1022
1023status_t DrmHalAidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1024 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
1025 Mutex::Autolock autoLock(mLock);
1026 INIT_CHECK();
1027
1028 DrmSessionManager::Instance()->useSession(sessionId);
1029
1030 std::vector<uint8_t> result;
1031 ::ndk::ScopedAStatus status =
1032 mPlugin->sign(toStdVec(sessionId), toStdVec(keyId), toStdVec(message), &result);
1033
1034 signature = toVector(result);
1035
1036 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
1037}
1038
1039status_t DrmHalAidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
1040 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
1041 bool& match) {
1042 Mutex::Autolock autoLock(mLock);
1043 INIT_CHECK();
1044
1045 DrmSessionManager::Instance()->useSession(sessionId);
1046
1047 ::ndk::ScopedAStatus status = mPlugin->verify(toStdVec(sessionId), toStdVec(keyId),
1048 toStdVec(message), toStdVec(signature), &match);
1049
1050 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
1051}
1052
1053status_t DrmHalAidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
1054 Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
1055 Vector<uint8_t>& signature) {
1056 Mutex::Autolock autoLock(mLock);
1057 INIT_CHECK();
1058
1059 DrmSessionManager::Instance()->useSession(sessionId);
1060
1061 std::vector<uint8_t> result;
1062 ::ndk::ScopedAStatus status =
1063 mPlugin->signRSA(toStdVec(sessionId), toStdString(algorithm), toStdVec(message),
1064 toStdVec(wrappedKey), &result);
1065
1066 signature = toVector(result);
1067
1068 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
1069}
1070
1071status_t DrmHalAidl::requiresSecureDecoder(const char* mime, bool* required) const {
1072 Mutex::Autolock autoLock(mLock);
1073 INIT_CHECK();
1074
1075 std::string mimeAidl(mime);
1076 ::ndk::ScopedAStatus status = mPlugin->requiresSecureDecoderDefault(mimeAidl, required);
1077 if (!status.isOk()) {
1078 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %d", status.getServiceSpecificError());
1079 return DEAD_OBJECT;
1080 }
1081
1082 return OK;
1083}
1084
1085status_t DrmHalAidl::requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
1086 bool* required) const {
1087 Mutex::Autolock autoLock(mLock);
1088 INIT_CHECK();
1089
1090 auto aLevel = toAidlSecurityLevel(securityLevel);
1091 std::string mimeAidl(mime);
1092 ::ndk::ScopedAStatus status = mPlugin->requiresSecureDecoder(mimeAidl, aLevel, required);
1093 if (!status.isOk()) {
1094 DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %d", status.getServiceSpecificError());
1095 return DEAD_OBJECT;
1096 }
1097
1098 return OK;
1099}
1100
1101status_t DrmHalAidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
1102 Mutex::Autolock autoLock(mLock);
1103 INIT_CHECK();
1104 std::string playbackIdAidl(playbackId);
1105 ::ndk::ScopedAStatus status = mPlugin->setPlaybackId(toStdVec(sessionId), playbackIdAidl);
1106 return status.isOk() ? toStatusTAidl(status.getServiceSpecificError()) : DEAD_OBJECT;
1107}
1108
1109status_t DrmHalAidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
1110 Mutex::Autolock autoLock(mLock);
1111 return DrmUtils::GetLogMessagesAidl<IDrmPluginAidl>(mPlugin, logs);
1112}
1113
1114void DrmHalAidl::closeOpenSessions() {
1115 Mutex::Autolock autoLock(mLock);
1116 auto openSessions = mOpenSessions;
1117 for (size_t i = 0; i < openSessions.size(); i++) {
1118 mLock.unlock();
1119 closeSession(openSessions[i]->mSessionId);
1120 mLock.lock();
1121 }
1122 mOpenSessions.clear();
1123}
1124
1125std::string DrmHalAidl::reportPluginMetrics() const {
1126 Vector<uint8_t> metricsVector;
1127 String8 vendor;
1128 String8 description;
1129 std::string metricsString;
1130 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1131 getPropertyStringInternal(String8("description"), description) == OK &&
1132 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1133 metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
1134 status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
1135 mMetrics.GetAppUid());
1136 if (res != OK) {
1137 ALOGE("Metrics were retrieved but could not be reported: %d", res);
1138 }
1139 }
1140 return metricsString;
1141}
1142
1143std::string DrmHalAidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
1144 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1145 mediametrics_setUid(item, mMetrics.GetAppUid());
1146 String8 vendor;
1147 String8 description;
1148 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1149 if (result != OK) {
1150 ALOGE("Failed to get vendor from drm plugin: %d", result);
1151 } else {
1152 mediametrics_setCString(item, "vendor", vendor.c_str());
1153 }
1154 result = getPropertyStringInternal(String8("description"), description);
1155 if (result != OK) {
1156 ALOGE("Failed to get description from drm plugin: %d", result);
1157 } else {
1158 mediametrics_setCString(item, "description", description.c_str());
1159 }
1160
1161 std::string serializedMetrics;
1162 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1163 if (result != OK) {
1164 ALOGE("Failed to serialize framework metrics: %d", result);
1165 }
1166 std::string b64EncodedMetrics =
1167 toBase64StringNoPad(serializedMetrics.data(), serializedMetrics.size());
1168 if (!b64EncodedMetrics.empty()) {
1169 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
1170 }
1171 if (!pluginMetrics.empty()) {
1172 mediametrics_setCString(item, "plugin_metrics", pluginMetrics.c_str());
1173 }
1174 if (!mediametrics_selfRecord(item)) {
1175 ALOGE("Failed to self record framework metrics");
1176 }
1177 mediametrics_delete(item);
1178 return serializedMetrics;
1179}
1180
1181void DrmHalAidl::cleanup() {
1182 closeOpenSessions();
1183
1184 Mutex::Autolock autoLock(mLock);
1185 reportFrameworkMetrics(reportPluginMetrics());
1186
1187 setListener(NULL);
1188 mInitCheck = NO_INIT;
1189 if (mPlugin != NULL) {
1190 if (!mPlugin->setListener(NULL).isOk()) {
1191 mInitCheck = DEAD_OBJECT;
1192 }
1193 }
1194
1195 mPlugin.reset();
1196}
1197
1198status_t DrmHalAidl::destroyPlugin() {
1199 cleanup();
1200 return OK;
1201}
1202
1203::ndk::ScopedAStatus DrmHalAidl::onEvent(EventTypeAidl eventTypeAidl,
1204 const std::vector<uint8_t>& sessionId,
1205 const std::vector<uint8_t>& data) {
1206 ::ndk::ScopedAStatus _aidl_status;
1207 mMetrics.mEventCounter.Increment((uint32_t)eventTypeAidl);
1208
1209 mEventLock.lock();
1210 sp<IDrmClient> listener = mListener;
1211 mEventLock.unlock();
1212
1213 if (listener != NULL) {
1214 Mutex::Autolock lock(mNotifyLock);
1215 DrmPlugin::EventType eventType;
1216 switch (eventTypeAidl) {
1217 case EventTypeAidl::PROVISION_REQUIRED:
1218 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
1219 break;
1220 case EventTypeAidl::KEY_NEEDED:
1221 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
1222 break;
1223 case EventTypeAidl::KEY_EXPIRED:
1224 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
1225 break;
1226 case EventTypeAidl::VENDOR_DEFINED:
1227 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
1228 break;
1229 case EventTypeAidl::SESSION_RECLAIMED:
1230 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
1231 break;
1232 default:
1233 return _aidl_status;
1234 }
1235
1236 listener->sendEvent(eventType, toHidlVec(toVector(sessionId)), toHidlVec(toVector(data)));
1237 }
1238
1239 return _aidl_status;
1240}
1241
1242::ndk::ScopedAStatus DrmHalAidl::onExpirationUpdate(const std::vector<uint8_t>& sessionId,
1243 int64_t expiryTimeInMS) {
1244 ::ndk::ScopedAStatus _aidl_status;
1245 mEventLock.lock();
1246 sp<IDrmClient> listener = mListener;
1247 mEventLock.unlock();
1248
1249 if (listener != NULL) {
1250 Mutex::Autolock lock(mNotifyLock);
1251 listener->sendExpirationUpdate(toHidlVec(toVector(sessionId)), expiryTimeInMS);
1252 }
1253
1254 return _aidl_status;
1255}
1256
1257::ndk::ScopedAStatus DrmHalAidl::onKeysChange(const std::vector<uint8_t>& sessionId,
1258 const std::vector<KeyStatus>& keyStatusListAidl,
1259 bool hasNewUsableKey) {
1260 ::ndk::ScopedAStatus _aidl_status;
1261 mEventLock.lock();
1262 sp<IDrmClient> listener = mListener;
1263 mEventLock.unlock();
1264
1265 if (listener != NULL) {
1266 std::vector<DrmKeyStatus> keyStatusList;
1267 size_t nKeys = keyStatusListAidl.size();
1268 for (size_t i = 0; i < nKeys; ++i) {
1269 const KeyStatus& keyStatus = keyStatusListAidl[i];
1270 uint32_t type;
1271 switch (keyStatus.type) {
1272 case KeyStatusType::USABLE:
1273 type = DrmPlugin::kKeyStatusType_Usable;
1274 break;
1275 case KeyStatusType::EXPIRED:
1276 type = DrmPlugin::kKeyStatusType_Expired;
1277 break;
1278 case KeyStatusType::OUTPUTNOTALLOWED:
1279 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
1280 break;
1281 case KeyStatusType::STATUSPENDING:
1282 type = DrmPlugin::kKeyStatusType_StatusPending;
1283 break;
1284 case KeyStatusType::USABLEINFUTURE:
1285 type = DrmPlugin::kKeyStatusType_UsableInFuture;
1286 break;
1287 case KeyStatusType::INTERNALERROR:
1288 default:
1289 type = DrmPlugin::kKeyStatusType_InternalError;
1290 break;
1291 }
1292 keyStatusList.push_back({type, toHidlVec(toVector(keyStatus.keyId))});
1293 mMetrics.mKeyStatusChangeCounter.Increment((uint32_t)keyStatus.type);
1294 }
1295
1296 Mutex::Autolock lock(mNotifyLock);
1297 listener->sendKeysChange(toHidlVec(toVector(sessionId)), keyStatusList, hasNewUsableKey);
1298 }
1299 else {
1300 // There's no listener. But we still want to count the key change
1301 // events.
1302 size_t nKeys = keyStatusListAidl.size();
1303
1304 for (size_t i = 0; i < nKeys; i++) {
1305 mMetrics.mKeyStatusChangeCounter.Increment((uint32_t)keyStatusListAidl[i].type);
1306 }
1307 }
1308
1309 return _aidl_status;
1310}
1311
1312::ndk::ScopedAStatus DrmHalAidl::onSessionLostState(const std::vector<uint8_t>& sessionId) {
1313 ::ndk::ScopedAStatus _aidl_status;
1314 mEventLock.lock();
1315 sp<IDrmClient> listener = mListener;
1316 mEventLock.unlock();
1317
1318 if (listener != NULL) {
1319 Mutex::Autolock lock(mNotifyLock);
1320 listener->sendSessionLostState(toHidlVec(toVector(sessionId)));
1321 }
1322
1323 return _aidl_status;
1324}
1325
1326} // namespace android