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