blob: f33f5f101179e3b9e8aa3dd182293b87d029e975 [file] [log] [blame]
Jeff Tinkera53d6552017-01-20 00:31:46 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmHal"
Jeff Tinkera53d6552017-01-20 00:31:46 -080019
Robert Shih0f3a8a02019-11-14 15:43:39 -080020#include <aidl/android/media/BnResourceManagerClient.h>
Robert Shihbd790122021-03-01 20:45:31 -080021#include <android/binder_manager.h>
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070022#include <android/hardware/drm/1.2/types.h>
Peter Kalauskasca5642c2018-11-12 12:34:42 -080023#include <android/hidl/manager/1.2/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070024#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080025#include <media/EventMetric.h>
Robert Shih82ea6be2019-11-07 17:47:23 -080026#include <media/MediaMetrics.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070027#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080028#include <media/drm/DrmAPI.h>
29#include <media/stagefright/foundation/ADebug.h>
30#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080031#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080032#include <media/stagefright/foundation/hexdump.h>
33#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080034#include <mediadrm/DrmHal.h>
35#include <mediadrm/DrmSessionClientInterface.h>
36#include <mediadrm/DrmSessionManager.h>
Robert Shih93538812019-11-12 12:21:35 -080037#include <mediadrm/IDrmMetricsConsumer.h>
Robert Shihc0d1d0e2019-11-24 13:21:04 -080038#include <mediadrm/DrmUtils.h>
Robert Shihbd790122021-03-01 20:45:31 -080039#include <utils/Log.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080040
Robert Shihbd790122021-03-01 20:45:31 -080041#include <iomanip>
Robert Shih61e1c762019-10-31 21:26:58 -070042#include <vector>
43
Jeff Tinker6d998b62017-12-18 14:37:43 -080044using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080045using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::KeyType;
47using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080049using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080050using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070051using drm::V1_1::HdcpLevel;
52using drm::V1_1::SecureStopRelease;
53using drm::V1_1::SecurityLevel;
54using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070055using drm::V1_2::KeyStatusType;
Robert Shih5944a0b2021-02-10 04:26:33 -080056using ::android::DrmUtils::toStatusT;
Adam Stone28f27c32018-02-05 15:07:48 -080057using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080058using ::android::hardware::hidl_array;
59using ::android::hardware::hidl_string;
60using ::android::hardware::hidl_vec;
61using ::android::hardware::Return;
62using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080063using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080064using ::android::sp;
65
Jeff Tinkerb8684f32018-12-12 08:41:31 -080066typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
67typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080068typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080069
Adam Stonecea91ce2018-01-22 19:23:28 -080070namespace {
71
72// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
73// in the MediaDrm API.
74constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080075constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080076
Adam Stone32494f52018-02-26 22:53:27 -080077template<typename T>
78std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070079 // Note that the base 64 conversion only works with arrays of single-byte
80 // values. If the source is empty or is not an array of single-byte values,
81 // return empty string.
82 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080083 return "";
84 }
Adam Stone32494f52018-02-26 22:53:27 -080085
86 android::AString outputString;
87 encodeBase64(data, size, &outputString);
88 // Remove trailing equals padding if it exists.
89 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
90 outputString.erase(outputString.size() - 1, 1);
91 }
92
93 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080094}
95
Adam Stone32494f52018-02-26 22:53:27 -080096} // anonymous namespace
97
Jeff Tinkera53d6552017-01-20 00:31:46 -080098namespace android {
99
Jeff Tinker6d998b62017-12-18 14:37:43 -0800100#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
101
Jeff Tinkera53d6552017-01-20 00:31:46 -0800102static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
103 Vector<uint8_t> vector;
104 vector.appendArray(vec.data(), vec.size());
105 return *const_cast<const Vector<uint8_t> *>(&vector);
106}
107
108static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
109 hidl_vec<uint8_t> vec;
110 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
111 return vec;
112}
113
114static String8 toString8(const hidl_string &string) {
115 return String8(string.c_str());
116}
117
118static hidl_string toHidlString(const String8& string) {
119 return hidl_string(string.string());
120}
121
Jeff Tinker6d998b62017-12-18 14:37:43 -0800122static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
123 switch(level) {
124 case SecurityLevel::SW_SECURE_CRYPTO:
125 return DrmPlugin::kSecurityLevelSwSecureCrypto;
126 case SecurityLevel::SW_SECURE_DECODE:
127 return DrmPlugin::kSecurityLevelSwSecureDecode;
128 case SecurityLevel::HW_SECURE_CRYPTO:
129 return DrmPlugin::kSecurityLevelHwSecureCrypto;
130 case SecurityLevel::HW_SECURE_DECODE:
131 return DrmPlugin::kSecurityLevelHwSecureDecode;
132 case SecurityLevel::HW_SECURE_ALL:
133 return DrmPlugin::kSecurityLevelHwSecureAll;
134 default:
135 return DrmPlugin::kSecurityLevelUnknown;
136 }
137}
138
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800139static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
140 switch(level) {
141 case DrmPlugin::kSecurityLevelSwSecureCrypto:
142 return SecurityLevel::SW_SECURE_CRYPTO;
143 case DrmPlugin::kSecurityLevelSwSecureDecode:
144 return SecurityLevel::SW_SECURE_DECODE;
145 case DrmPlugin::kSecurityLevelHwSecureCrypto:
146 return SecurityLevel::HW_SECURE_CRYPTO;
147 case DrmPlugin::kSecurityLevelHwSecureDecode:
148 return SecurityLevel::HW_SECURE_DECODE;
149 case DrmPlugin::kSecurityLevelHwSecureAll:
150 return SecurityLevel::HW_SECURE_ALL;
151 default:
152 return SecurityLevel::UNKNOWN;
153 }
154}
155
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700156static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
157 OfflineLicenseState licenseState) {
158 switch(licenseState) {
159 case OfflineLicenseState::USABLE:
160 return DrmPlugin::kOfflineLicenseStateUsable;
161 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800162 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700163 default:
164 return DrmPlugin::kOfflineLicenseStateUnknown;
165 }
166}
167
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800168static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800169 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800170 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800171 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800172 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800173 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800174 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800175 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800176 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800177 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800178 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800179 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800180 case HdcpLevel_V1_2::HDCP_V2_3:
181 return DrmPlugin::kHdcpV2_3;
182 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800183 return DrmPlugin::kHdcpNoOutput;
184 default:
185 return DrmPlugin::kHdcpLevelUnknown;
186 }
187}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800188static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
189 keyedVector) {
190 std::vector<KeyValue> stdKeyedVector;
191 for (size_t i = 0; i < keyedVector.size(); i++) {
192 KeyValue keyValue;
193 keyValue.key = toHidlString(keyedVector.keyAt(i));
194 keyValue.value = toHidlString(keyedVector.valueAt(i));
195 stdKeyedVector.push_back(keyValue);
196 }
197 return ::KeyedVector(stdKeyedVector);
198}
199
200static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
201 hKeyedVector) {
202 KeyedVector<String8, String8> keyedVector;
203 for (size_t i = 0; i < hKeyedVector.size(); i++) {
204 keyedVector.add(toString8(hKeyedVector[i].key),
205 toString8(hKeyedVector[i].value));
206 }
207 return keyedVector;
208}
209
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800210static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800211 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800212 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800213 for (size_t i = 0; i < hSecureStops.size(); i++) {
214 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
215 }
216 return secureStops;
217}
218
Jeff Tinker15177d72018-01-25 12:57:55 -0800219static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
220 hSecureStopIds) {
221 List<Vector<uint8_t>> secureStopIds;
222 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
223 secureStopIds.push_back(toVector(hSecureStopIds[i]));
224 }
225 return secureStopIds;
226}
227
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700228static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
229 hKeySetIds) {
230 List<Vector<uint8_t>> keySetIds;
231 for (size_t i = 0; i < hKeySetIds.size(); i++) {
232 keySetIds.push_back(toVector(hKeySetIds[i]));
233 }
234 return keySetIds;
235}
236
Jeff Tinkera53d6552017-01-20 00:31:46 -0800237Mutex DrmHal::mLock;
238
Robert Shih0f3a8a02019-11-14 15:43:39 -0800239struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700240 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
241 : mSessionId(sessionId),
242 mDrm(drm) {}
243
Robert Shih0f3a8a02019-11-14 15:43:39 -0800244 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
245 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700246
247 const Vector<uint8_t> mSessionId;
248
Chong Zhang181e6952019-10-09 13:23:39 -0700249 virtual ~DrmSessionClient();
250
251private:
252 wp<DrmHal> mDrm;
253
254 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
255};
256
Robert Shih0f3a8a02019-11-14 15:43:39 -0800257::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
258 auto sessionId = mSessionId;
Robert Shihc3af31b2019-09-20 21:45:01 -0700259 sp<DrmHal> drm = mDrm.promote();
260 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700261 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800262 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800263 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800264 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700265 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700266 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800267 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700268 }
269 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800270 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700271 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800272 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700273}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800274
Robert Shih0f3a8a02019-11-14 15:43:39 -0800275::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700276 String8 name;
277 sp<DrmHal> drm = mDrm.promote();
278 if (drm == NULL) {
279 name.append("<deleted>");
280 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
281 || name.isEmpty()) {
282 name.append("<Get vendor failed or is empty>");
283 }
284 name.append("[");
285 for (size_t i = 0; i < mSessionId.size(); ++i) {
286 name.appendFormat("%02x", mSessionId[i]);
287 }
288 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700289 *_aidl_return = name;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800290 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700291}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800292
Robert Shihc3af31b2019-09-20 21:45:01 -0700293DrmHal::DrmSessionClient::~DrmSessionClient() {
294 DrmSessionManager::Instance()->removeSession(mSessionId);
295}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800296
297DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700298 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800299 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800300}
301
Jeff Tinker61332812017-05-15 16:53:10 -0700302void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800303 Mutex::Autolock autoLock(mLock);
304 auto openSessions = mOpenSessions;
305 for (size_t i = 0; i < openSessions.size(); i++) {
306 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700307 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800308 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700309 }
310 mOpenSessions.clear();
311}
312
Jeff Tinkera53d6552017-01-20 00:31:46 -0800313DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800314}
315
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800316void DrmHal::cleanup() {
317 closeOpenSessions();
318
319 Mutex::Autolock autoLock(mLock);
320 reportPluginMetrics();
321 reportFrameworkMetrics();
322
323 setListener(NULL);
324 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800325 if (mPluginV1_2 != NULL) {
326 if (!mPluginV1_2->setListener(NULL).isOk()) {
327 mInitCheck = DEAD_OBJECT;
328 }
329 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800330 if (!mPlugin->setListener(NULL).isOk()) {
331 mInitCheck = DEAD_OBJECT;
332 }
333 }
334 mPlugin.clear();
335 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700336 mPluginV1_2.clear();
Robert Shihfbe581e2021-01-14 05:12:04 -0800337 mPluginV1_4.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800338}
339
Robert Shihc0d1d0e2019-11-24 13:21:04 -0800340std::vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
341 std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800342 if (factories.size() == 0) {
343 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700344 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800345 if (passthrough != NULL) {
Robert Shih8635cb12021-02-26 07:57:55 -0800346 DrmUtils::LOG2BI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800347 factories.push_back(passthrough);
348 } else {
Robert Shih8635cb12021-02-26 07:57:55 -0800349 DrmUtils::LOG2BE("Failed to find any drm factories");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800350 }
351 }
352 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800353}
354
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800355sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
356 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800357 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800358 mMetrics.SetAppPackageName(appPackageName);
Robert Shih6152d7c2019-11-19 22:54:27 -0800359 mMetrics.SetAppUid(AIBinder_getCallingUid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800360
361 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800362 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800363 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800364 if (status != Status::OK) {
Robert Shihbd790122021-03-01 20:45:31 -0800365 DrmUtils::LOG2BE(uuid, "Failed to make drm plugin: %d", status);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800366 return;
367 }
368 plugin = hPlugin;
369 }
370 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700371
372 if (!hResult.isOk()) {
Robert Shihbd790122021-03-01 20:45:31 -0800373 DrmUtils::LOG2BE(uuid, "createPlugin remote call failed: %s",
374 hResult.description().c_str());
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700375 }
376
Jeff Tinkera53d6552017-01-20 00:31:46 -0800377 return plugin;
378}
379
380status_t DrmHal::initCheck() const {
381 return mInitCheck;
382}
383
384status_t DrmHal::setListener(const sp<IDrmClient>& listener)
385{
386 Mutex::Autolock lock(mEventLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800387 mListener = listener;
388 return NO_ERROR;
389}
390
391Return<void> DrmHal::sendEvent(EventType hEventType,
392 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800393 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800394
395 mEventLock.lock();
396 sp<IDrmClient> listener = mListener;
397 mEventLock.unlock();
398
399 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800400 Mutex::Autolock lock(mNotifyLock);
401 DrmPlugin::EventType eventType;
402 switch(hEventType) {
403 case EventType::PROVISION_REQUIRED:
404 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
405 break;
406 case EventType::KEY_NEEDED:
407 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
408 break;
409 case EventType::KEY_EXPIRED:
410 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
411 break;
412 case EventType::VENDOR_DEFINED:
413 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
414 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700415 case EventType::SESSION_RECLAIMED:
416 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
417 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800418 default:
419 return Void();
420 }
Robert Shih61e1c762019-10-31 21:26:58 -0700421 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800422 }
423 return Void();
424}
425
426Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
427 int64_t expiryTimeInMS) {
428
429 mEventLock.lock();
430 sp<IDrmClient> listener = mListener;
431 mEventLock.unlock();
432
433 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800434 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700435 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800436 }
437 return Void();
438}
439
440Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700441 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
442 std::vector<KeyStatus> keyStatusVec;
443 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
444 keyStatusVec.push_back({keyStatus_V1_0.keyId,
445 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
446 }
447 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
448 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
449}
450
451Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700452 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800453
454 mEventLock.lock();
455 sp<IDrmClient> listener = mListener;
456 mEventLock.unlock();
457
458 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700459 std::vector<DrmKeyStatus> keyStatusList;
460 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800461 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700462 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800463 uint32_t type;
464 switch(keyStatus.type) {
465 case KeyStatusType::USABLE:
466 type = DrmPlugin::kKeyStatusType_Usable;
467 break;
468 case KeyStatusType::EXPIRED:
469 type = DrmPlugin::kKeyStatusType_Expired;
470 break;
471 case KeyStatusType::OUTPUTNOTALLOWED:
472 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
473 break;
474 case KeyStatusType::STATUSPENDING:
475 type = DrmPlugin::kKeyStatusType_StatusPending;
476 break;
Robert Shiha5033262019-05-06 14:15:12 -0700477 case KeyStatusType::USABLEINFUTURE:
478 type = DrmPlugin::kKeyStatusType_UsableInFuture;
479 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800480 case KeyStatusType::INTERNALERROR:
481 default:
482 type = DrmPlugin::kKeyStatusType_InternalError;
483 break;
484 }
Robert Shih61e1c762019-10-31 21:26:58 -0700485 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800486 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800487 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800488
489 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700490 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800491 } else {
492 // There's no listener. But we still want to count the key change
493 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700494 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800495 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700496 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800497 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800498 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800499
Jeff Tinkera53d6552017-01-20 00:31:46 -0800500 return Void();
501}
502
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800503Return<void> DrmHal::sendSessionLostState(
504 const hidl_vec<uint8_t>& sessionId) {
505
506 mEventLock.lock();
507 sp<IDrmClient> listener = mListener;
508 mEventLock.unlock();
509
510 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800511 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700512 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800513 }
514 return Void();
515}
516
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800517status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
518 const uint8_t uuid[16],
519 const String8 &mimeType,
520 DrmPlugin::SecurityLevel level,
521 bool *isSupported) {
522 *isSupported = false;
523
524 // handle default value cases
525 if (level == DrmPlugin::kSecurityLevelUnknown) {
526 if (mimeType == "") {
527 // isCryptoSchemeSupported(uuid)
528 *isSupported = true;
529 } else {
530 // isCryptoSchemeSupported(uuid, mimeType)
531 *isSupported = factory->isContentTypeSupported(mimeType.string());
532 }
533 return OK;
534 } else if (mimeType == "") {
535 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800536 }
537
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800538 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
539 if (factoryV1_2 == NULL) {
540 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800541 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800542 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
543 mimeType.string(), toHidlSecurityLevel(level));
544 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800545 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800546}
547
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800548status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
549 const String8 &mimeType,
550 DrmPlugin::SecurityLevel level,
551 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800553 *isSupported = false;
554 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
555 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
556 return matchMimeTypeAndSecurityLevel(mFactories[i],
557 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800558 }
559 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800560 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800561}
562
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800563status_t DrmHal::createPlugin(const uint8_t uuid[16],
564 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800565 Mutex::Autolock autoLock(mLock);
566
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800567 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Robert Shih8635cb12021-02-26 07:57:55 -0800568 auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
569 if (hResult.isOk() && hResult) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800570 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
571 if (plugin != NULL) {
572 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800573 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700574 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Robert Shihfbe581e2021-01-14 05:12:04 -0800575 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800576 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800577 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800578 }
579 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800580
581 if (mPlugin == NULL) {
Robert Shihbd790122021-03-01 20:45:31 -0800582 DrmUtils::LOG2BE(uuid, "No supported hal instance found");
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583 mInitCheck = ERROR_UNSUPPORTED;
584 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800585 mInitCheck = OK;
586 if (mPluginV1_2 != NULL) {
587 if (!mPluginV1_2->setListener(this).isOk()) {
588 mInitCheck = DEAD_OBJECT;
589 }
590 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700591 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800592 }
593 if (mInitCheck != OK) {
594 mPlugin.clear();
595 mPluginV1_1.clear();
596 mPluginV1_2.clear();
Robert Shihfbe581e2021-01-14 05:12:04 -0800597 mPluginV1_4.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700598 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800599 }
600
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800601
Jeff Tinkera53d6552017-01-20 00:31:46 -0800602 return mInitCheck;
603}
604
605status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800606 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800607 return OK;
608}
609
Jeff Tinker41d279a2018-02-11 19:52:08 +0000610status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
611 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800612 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800613 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800614
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800615 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000616 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000617
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800618 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000619 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800620 } else {
621 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
622 return ERROR_DRM_CANNOT_HANDLE;
623 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000624 }
625
626 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800627 bool retry = true;
628 do {
629 hidl_vec<uint8_t> hSessionId;
630
Jeff Tinker41d279a2018-02-11 19:52:08 +0000631 Return<void> hResult;
632 if (mPluginV1_1 == NULL || !setSecurityLevel) {
633 hResult = mPlugin->openSession(
634 [&](Status status,const hidl_vec<uint8_t>& id) {
635 if (status == Status::OK) {
636 sessionId = toVector(id);
637 }
638 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800639 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000640 );
641 } else {
642 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
643 [&](Status status, const hidl_vec<uint8_t>& id) {
644 if (status == Status::OK) {
645 sessionId = toVector(id);
646 }
647 err = toStatusT(status);
648 }
649 );
650 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800651
652 if (!hResult.isOk()) {
653 err = DEAD_OBJECT;
654 }
655
656 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
657 mLock.unlock();
658 // reclaimSession may call back to closeSession, since mLock is
659 // shared between Drm instances, we should unlock here to avoid
660 // deadlock.
Robert Shih6152d7c2019-11-19 22:54:27 -0800661 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800662 mLock.lock();
663 } else {
664 retry = false;
665 }
666 } while (retry);
667
668 if (err == OK) {
Steven Morelande0496a22020-02-13 13:13:52 -0800669 std::shared_ptr<DrmSessionClient> client =
670 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
Robert Shih6152d7c2019-11-19 22:54:27 -0800671 DrmSessionManager::Instance()->addSession(AIBinder_getCallingPid(),
Robert Shih0f3a8a02019-11-14 15:43:39 -0800672 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
673 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800674 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800675 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800676
Adam Stonef0e618d2018-01-17 19:20:41 -0800677 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800678 return err;
679}
680
681status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
682 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800683 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800684
Jeff Tinker319d5f42017-07-26 15:44:33 -0700685 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
686 if (status.isOk()) {
687 if (status == Status::OK) {
688 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800689 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
690 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
691 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700692 break;
693 }
Jeff Tinker61332812017-05-15 16:53:10 -0700694 }
695 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800696 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800697 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800698 mMetrics.mCloseSessionCounter.Increment(response);
699 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800700 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800701 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700702 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800703}
704
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800705static DrmPlugin::KeyRequestType toKeyRequestType(
706 KeyRequestType keyRequestType) {
707 switch (keyRequestType) {
708 case KeyRequestType::INITIAL:
709 return DrmPlugin::kKeyRequestType_Initial;
710 break;
711 case KeyRequestType::RENEWAL:
712 return DrmPlugin::kKeyRequestType_Renewal;
713 break;
714 case KeyRequestType::RELEASE:
715 return DrmPlugin::kKeyRequestType_Release;
716 break;
717 default:
718 return DrmPlugin::kKeyRequestType_Unknown;
719 break;
720 }
721}
722
723static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
724 KeyRequestType_V1_1 keyRequestType) {
725 switch (keyRequestType) {
726 case KeyRequestType_V1_1::NONE:
727 return DrmPlugin::kKeyRequestType_None;
728 break;
729 case KeyRequestType_V1_1::UPDATE:
730 return DrmPlugin::kKeyRequestType_Update;
731 break;
732 default:
733 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
734 break;
735 }
736}
737
Jeff Tinkera53d6552017-01-20 00:31:46 -0800738status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
739 Vector<uint8_t> const &initData, String8 const &mimeType,
740 DrmPlugin::KeyType keyType, KeyedVector<String8,
741 String8> const &optionalParameters, Vector<uint8_t> &request,
742 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
743 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800744 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800745 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800746
747 DrmSessionManager::Instance()->useSession(sessionId);
748
749 KeyType hKeyType;
750 if (keyType == DrmPlugin::kKeyType_Streaming) {
751 hKeyType = KeyType::STREAMING;
752 } else if (keyType == DrmPlugin::kKeyType_Offline) {
753 hKeyType = KeyType::OFFLINE;
754 } else if (keyType == DrmPlugin::kKeyType_Release) {
755 hKeyType = KeyType::RELEASE;
756 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800757 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800758 return BAD_VALUE;
759 }
760
761 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
762
763 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800764 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800765
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800766 if (mPluginV1_2 != NULL) {
767 hResult = mPluginV1_2->getKeyRequest_1_2(
768 toHidlVec(sessionId), toHidlVec(initData),
769 toHidlString(mimeType), hKeyType, hOptionalParameters,
770 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
771 KeyRequestType_V1_1 hKeyRequestType,
772 const hidl_string& hDefaultUrl) {
773 if (status == Status_V1_2::OK) {
774 request = toVector(hRequest);
775 defaultUrl = toString8(hDefaultUrl);
776 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
777 }
Robert Shih5944a0b2021-02-10 04:26:33 -0800778 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800779 });
780 } else if (mPluginV1_1 != NULL) {
781 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800782 toHidlVec(sessionId), toHidlVec(initData),
783 toHidlString(mimeType), hKeyType, hOptionalParameters,
784 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800785 KeyRequestType_V1_1 hKeyRequestType,
786 const hidl_string& hDefaultUrl) {
787 if (status == Status::OK) {
788 request = toVector(hRequest);
789 defaultUrl = toString8(hDefaultUrl);
790 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800791 }
792 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800793 });
794 } else {
795 hResult = mPlugin->getKeyRequest(
796 toHidlVec(sessionId), toHidlVec(initData),
797 toHidlString(mimeType), hKeyType, hOptionalParameters,
798 [&](Status status, const hidl_vec<uint8_t>& hRequest,
799 KeyRequestType hKeyRequestType,
800 const hidl_string& hDefaultUrl) {
801 if (status == Status::OK) {
802 request = toVector(hRequest);
803 defaultUrl = toString8(hDefaultUrl);
804 *keyRequestType = toKeyRequestType(hKeyRequestType);
805 }
806 err = toStatusT(status);
807 });
808 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800809
Adam Stonef0e618d2018-01-17 19:20:41 -0800810 err = hResult.isOk() ? err : DEAD_OBJECT;
811 keyRequestTimer.SetAttribute(err);
812 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800813}
814
815status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
816 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
817 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800818 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700819 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800820
821 DrmSessionManager::Instance()->useSession(sessionId);
822
823 status_t err = UNKNOWN_ERROR;
824
825 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
826 toHidlVec(response),
827 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
828 if (status == Status::OK) {
829 keySetId = toVector(hKeySetId);
830 }
831 err = toStatusT(status);
832 }
833 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800834 err = hResult.isOk() ? err : DEAD_OBJECT;
835 keyResponseTimer.SetAttribute(err);
836 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800837}
838
839status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
840 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800841 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800842
Jeff Tinker58ad4752018-02-16 16:51:59 -0800843 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
844 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800845}
846
847status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
848 Vector<uint8_t> const &keySetId) {
849 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800850 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800851
852 DrmSessionManager::Instance()->useSession(sessionId);
853
Jeff Tinker58ad4752018-02-16 16:51:59 -0800854 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
855 toHidlVec(keySetId));
856 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800857}
858
859status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
860 KeyedVector<String8, String8> &infoMap) const {
861 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800862 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800863
864 DrmSessionManager::Instance()->useSession(sessionId);
865
866 ::KeyedVector hInfoMap;
867
868 status_t err = UNKNOWN_ERROR;
869
870 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
871 [&](Status status, const hidl_vec<KeyValue>& map) {
872 if (status == Status::OK) {
873 infoMap = toKeyedVector(map);
874 }
875 err = toStatusT(status);
876 }
877 );
878
879 return hResult.isOk() ? err : DEAD_OBJECT;
880}
881
882status_t DrmHal::getProvisionRequest(String8 const &certType,
883 String8 const &certAuthority, Vector<uint8_t> &request,
884 String8 &defaultUrl) {
885 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800886 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800887
888 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800889 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800890
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800891 if (mPluginV1_2 != NULL) {
892 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
893 toHidlString(certType), toHidlString(certAuthority),
894 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
895 const hidl_string& hDefaultUrl) {
896 if (status == Status_V1_2::OK) {
897 request = toVector(hRequest);
898 defaultUrl = toString8(hDefaultUrl);
899 }
Robert Shih5944a0b2021-02-10 04:26:33 -0800900 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800901 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800902 );
903 } else {
904 Return<void> hResult = mPlugin->getProvisionRequest(
905 toHidlString(certType), toHidlString(certAuthority),
906 [&](Status status, const hidl_vec<uint8_t>& hRequest,
907 const hidl_string& hDefaultUrl) {
908 if (status == Status::OK) {
909 request = toVector(hRequest);
910 defaultUrl = toString8(hDefaultUrl);
911 }
912 err = toStatusT(status);
913 }
914 );
915 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800916
Adam Stonecea91ce2018-01-22 19:23:28 -0800917 err = hResult.isOk() ? err : DEAD_OBJECT;
918 mMetrics.mGetProvisionRequestCounter.Increment(err);
919 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800920}
921
922status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800923 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800924 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800925 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800926
927 status_t err = UNKNOWN_ERROR;
928
929 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
930 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
931 const hidl_vec<uint8_t>& hWrappedKey) {
932 if (status == Status::OK) {
933 certificate = toVector(hCertificate);
934 wrappedKey = toVector(hWrappedKey);
935 }
936 err = toStatusT(status);
937 }
938 );
939
Adam Stonecea91ce2018-01-22 19:23:28 -0800940 err = hResult.isOk() ? err : DEAD_OBJECT;
941 mMetrics.mProvideProvisionResponseCounter.Increment(err);
942 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800943}
944
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800945status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800946 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800947 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800948
949 status_t err = UNKNOWN_ERROR;
950
951 Return<void> hResult = mPlugin->getSecureStops(
952 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
953 if (status == Status::OK) {
954 secureStops = toSecureStops(hSecureStops);
955 }
956 err = toStatusT(status);
957 }
958 );
959
960 return hResult.isOk() ? err : DEAD_OBJECT;
961}
962
963
Jeff Tinker15177d72018-01-25 12:57:55 -0800964status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
965 Mutex::Autolock autoLock(mLock);
966
967 if (mInitCheck != OK) {
968 return mInitCheck;
969 }
970
971 if (mPluginV1_1 == NULL) {
972 return ERROR_DRM_CANNOT_HANDLE;
973 }
974
975 status_t err = UNKNOWN_ERROR;
976
977 Return<void> hResult = mPluginV1_1->getSecureStopIds(
978 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
979 if (status == Status::OK) {
980 secureStopIds = toSecureStopIds(hSecureStopIds);
981 }
982 err = toStatusT(status);
983 }
984 );
985
986 return hResult.isOk() ? err : DEAD_OBJECT;
987}
988
989
Jeff Tinkera53d6552017-01-20 00:31:46 -0800990status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
991 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800992 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800993
994 status_t err = UNKNOWN_ERROR;
995
996 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
997 [&](Status status, const SecureStop& hSecureStop) {
998 if (status == Status::OK) {
999 secureStop = toVector(hSecureStop.opaqueData);
1000 }
1001 err = toStatusT(status);
1002 }
1003 );
1004
1005 return hResult.isOk() ? err : DEAD_OBJECT;
1006}
1007
1008status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1009 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001010 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001011
Jeff Tinker58ad4752018-02-16 16:51:59 -08001012 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001013 if (mPluginV1_1 != NULL) {
1014 SecureStopRelease secureStopRelease;
1015 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001016 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1017 } else {
1018 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001019 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001020 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001021}
1022
Jeff Tinker15177d72018-01-25 12:57:55 -08001023status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1024 Mutex::Autolock autoLock(mLock);
1025
1026 if (mInitCheck != OK) {
1027 return mInitCheck;
1028 }
1029
1030 if (mPluginV1_1 == NULL) {
1031 return ERROR_DRM_CANNOT_HANDLE;
1032 }
1033
Jeff Tinker58ad4752018-02-16 16:51:59 -08001034 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1035 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001036}
1037
1038status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001039 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001040 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001041
Jeff Tinker58ad4752018-02-16 16:51:59 -08001042 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001043 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001044 status = mPluginV1_1->removeAllSecureStops();
1045 } else {
1046 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001047 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001048 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001049}
1050
Jeff Tinker6d998b62017-12-18 14:37:43 -08001051status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1052 DrmPlugin::HdcpLevel *max) const {
1053 Mutex::Autolock autoLock(mLock);
1054 INIT_CHECK();
1055
1056 if (connected == NULL || max == NULL) {
1057 return BAD_VALUE;
1058 }
1059 status_t err = UNKNOWN_ERROR;
1060
Jeff Tinker6d998b62017-12-18 14:37:43 -08001061 *connected = DrmPlugin::kHdcpLevelUnknown;
1062 *max = DrmPlugin::kHdcpLevelUnknown;
1063
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001064 Return<void> hResult;
1065 if (mPluginV1_2 != NULL) {
1066 hResult = mPluginV1_2->getHdcpLevels_1_2(
1067 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1068 if (status == Status_V1_2::OK) {
1069 *connected = toHdcpLevel(hConnected);
1070 *max = toHdcpLevel(hMax);
1071 }
Robert Shih5944a0b2021-02-10 04:26:33 -08001072 err = toStatusT(status);
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001073 });
1074 } else if (mPluginV1_1 != NULL) {
1075 hResult = mPluginV1_1->getHdcpLevels(
1076 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1077 if (status == Status::OK) {
1078 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1079 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1080 }
1081 err = toStatusT(status);
1082 });
1083 } else {
1084 return ERROR_DRM_CANNOT_HANDLE;
1085 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001086
1087 return hResult.isOk() ? err : DEAD_OBJECT;
1088}
1089
1090status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1091 Mutex::Autolock autoLock(mLock);
1092 INIT_CHECK();
1093
1094 if (open == NULL || max == NULL) {
1095 return BAD_VALUE;
1096 }
1097 status_t err = UNKNOWN_ERROR;
1098
1099 *open = 0;
1100 *max = 0;
1101
1102 if (mPluginV1_1 == NULL) {
1103 return ERROR_DRM_CANNOT_HANDLE;
1104 }
1105
1106 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1107 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1108 if (status == Status::OK) {
1109 *open = hOpen;
1110 *max = hMax;
1111 }
1112 err = toStatusT(status);
1113 }
1114 );
1115
1116 return hResult.isOk() ? err : DEAD_OBJECT;
1117}
1118
1119status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1120 DrmPlugin::SecurityLevel *level) const {
1121 Mutex::Autolock autoLock(mLock);
1122 INIT_CHECK();
1123
1124 if (level == NULL) {
1125 return BAD_VALUE;
1126 }
1127 status_t err = UNKNOWN_ERROR;
1128
1129 if (mPluginV1_1 == NULL) {
1130 return ERROR_DRM_CANNOT_HANDLE;
1131 }
1132
1133 *level = DrmPlugin::kSecurityLevelUnknown;
1134
1135 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1136 [&](Status status, SecurityLevel hLevel) {
1137 if (status == Status::OK) {
1138 *level = toSecurityLevel(hLevel);
1139 }
1140 err = toStatusT(status);
1141 }
1142 );
1143
1144 return hResult.isOk() ? err : DEAD_OBJECT;
1145}
1146
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001147status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1148 Mutex::Autolock autoLock(mLock);
1149
1150 if (mInitCheck != OK) {
1151 return mInitCheck;
1152 }
1153
1154 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001155 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001156 }
1157
1158 status_t err = UNKNOWN_ERROR;
1159
1160 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1161 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1162 if (status == Status::OK) {
1163 keySetIds = toKeySetIds(hKeySetIds);
1164 }
1165 err = toStatusT(status);
1166 }
1167 );
1168
1169 return hResult.isOk() ? err : DEAD_OBJECT;
1170}
1171
1172status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1173 Mutex::Autolock autoLock(mLock);
1174
1175 if (mInitCheck != OK) {
1176 return mInitCheck;
1177 }
1178
1179 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001180 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001181 }
1182
1183 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1184 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1185}
1186
1187status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1188 DrmPlugin::OfflineLicenseState *licenseState) const {
1189 Mutex::Autolock autoLock(mLock);
1190
1191 if (mInitCheck != OK) {
1192 return mInitCheck;
1193 }
1194
1195 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001196 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001197 }
1198 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1199
1200 status_t err = UNKNOWN_ERROR;
1201
1202 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1203 [&](Status status, OfflineLicenseState hLicenseState) {
1204 if (status == Status::OK) {
1205 *licenseState = toOfflineLicenseState(hLicenseState);
1206 }
1207 err = toStatusT(status);
1208 }
1209 );
1210
1211 return hResult.isOk() ? err : DEAD_OBJECT;
1212}
1213
Jeff Tinkera53d6552017-01-20 00:31:46 -08001214status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1215 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001216 return getPropertyStringInternal(name, value);
1217}
1218
1219status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1220 // This function is internal to the class and should only be called while
1221 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001222 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001223
1224 status_t err = UNKNOWN_ERROR;
1225
1226 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1227 [&](Status status, const hidl_string& hValue) {
1228 if (status == Status::OK) {
1229 value = toString8(hValue);
1230 }
1231 err = toStatusT(status);
1232 }
1233 );
1234
1235 return hResult.isOk() ? err : DEAD_OBJECT;
1236}
1237
1238status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1239 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001240 return getPropertyByteArrayInternal(name, value);
1241}
1242
1243status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1244 // This function is internal to the class and should only be called while
1245 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001246 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001247
1248 status_t err = UNKNOWN_ERROR;
1249
1250 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1251 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1252 if (status == Status::OK) {
1253 value = toVector(hValue);
1254 }
1255 err = toStatusT(status);
1256 }
1257 );
1258
Adam Stonecea91ce2018-01-22 19:23:28 -08001259 err = hResult.isOk() ? err : DEAD_OBJECT;
1260 if (name == kPropertyDeviceUniqueId) {
1261 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1262 }
1263 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001264}
1265
1266status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1267 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001268 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001269
Jeff Tinker58ad4752018-02-16 16:51:59 -08001270 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001271 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001272 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001273}
1274
1275status_t DrmHal::setPropertyByteArray(String8 const &name,
1276 Vector<uint8_t> const &value ) const {
1277 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001278 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001279
Jeff Tinker58ad4752018-02-16 16:51:59 -08001280 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001281 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001282 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001283}
1284
Robert Shih93538812019-11-12 12:21:35 -08001285status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
1286 if (consumer == nullptr) {
Adam Stone28f27c32018-02-05 15:07:48 -08001287 return UNEXPECTED_NULL;
1288 }
Robert Shih93538812019-11-12 12:21:35 -08001289 consumer->consumeFrameworkMetrics(mMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001290
1291 // Append vendor metrics if they are supported.
1292 if (mPluginV1_1 != NULL) {
1293 String8 vendor;
1294 String8 description;
1295 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1296 || vendor.isEmpty()) {
1297 ALOGE("Get vendor failed or is empty");
1298 vendor = "NONE";
1299 }
1300 if (getPropertyStringInternal(String8("description"), description) != OK
1301 || description.isEmpty()) {
1302 ALOGE("Get description failed or is empty.");
1303 description = "NONE";
1304 }
1305 vendor += ".";
1306 vendor += description;
1307
1308 hidl_vec<DrmMetricGroup> pluginMetrics;
1309 status_t err = UNKNOWN_ERROR;
1310
1311 Return<void> status = mPluginV1_1->getMetrics(
1312 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1313 if (status != Status::OK) {
1314 ALOGV("Error getting plugin metrics: %d", status);
1315 } else {
Robert Shih93538812019-11-12 12:21:35 -08001316 consumer->consumeHidlMetrics(vendor, pluginMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001317 }
1318 err = toStatusT(status);
1319 });
1320 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001321 }
1322
Adam Stoneab394d12017-12-22 12:34:20 -08001323 return OK;
1324}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001325
1326status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1327 String8 const &algorithm) {
1328 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001329 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001330
1331 DrmSessionManager::Instance()->useSession(sessionId);
1332
Jeff Tinkere6412942018-04-30 17:35:16 -07001333 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001334 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001335 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001336}
1337
1338status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1339 String8 const &algorithm) {
1340 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001341 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001342
1343 DrmSessionManager::Instance()->useSession(sessionId);
1344
Jeff Tinkere6412942018-04-30 17:35:16 -07001345 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001346 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001347 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001348}
1349
1350status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001351 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1352 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001353 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001354 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001355
1356 DrmSessionManager::Instance()->useSession(sessionId);
1357
1358 status_t err = UNKNOWN_ERROR;
1359
1360 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1361 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1362 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1363 if (status == Status::OK) {
1364 output = toVector(hOutput);
1365 }
1366 err = toStatusT(status);
1367 }
1368 );
1369
1370 return hResult.isOk() ? err : DEAD_OBJECT;
1371}
1372
1373status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001374 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1375 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001376 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001377 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001378
1379 DrmSessionManager::Instance()->useSession(sessionId);
1380
1381 status_t err = UNKNOWN_ERROR;
1382
1383 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1384 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1385 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1386 if (status == Status::OK) {
1387 output = toVector(hOutput);
1388 }
1389 err = toStatusT(status);
1390 }
1391 );
1392
1393 return hResult.isOk() ? err : DEAD_OBJECT;
1394}
1395
1396status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001397 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1398 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001399 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001400 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001401
1402 DrmSessionManager::Instance()->useSession(sessionId);
1403
1404 status_t err = UNKNOWN_ERROR;
1405
1406 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1407 toHidlVec(keyId), toHidlVec(message),
1408 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1409 if (status == Status::OK) {
1410 signature = toVector(hSignature);
1411 }
1412 err = toStatusT(status);
1413 }
1414 );
1415
1416 return hResult.isOk() ? err : DEAD_OBJECT;
1417}
1418
1419status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001420 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1421 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001422 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001423 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001424
1425 DrmSessionManager::Instance()->useSession(sessionId);
1426
1427 status_t err = UNKNOWN_ERROR;
1428
1429 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1430 toHidlVec(message), toHidlVec(signature),
1431 [&](Status status, bool hMatch) {
1432 if (status == Status::OK) {
1433 match = hMatch;
1434 } else {
1435 match = false;
1436 }
1437 err = toStatusT(status);
1438 }
1439 );
1440
1441 return hResult.isOk() ? err : DEAD_OBJECT;
1442}
1443
1444status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001445 String8 const &algorithm, Vector<uint8_t> const &message,
1446 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001447 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001448 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449
Jeff Tinkera53d6552017-01-20 00:31:46 -08001450 DrmSessionManager::Instance()->useSession(sessionId);
1451
1452 status_t err = UNKNOWN_ERROR;
1453
1454 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1455 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1456 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1457 if (status == Status::OK) {
1458 signature = toVector(hSignature);
1459 }
1460 err = toStatusT(status);
1461 }
1462 );
1463
1464 return hResult.isOk() ? err : DEAD_OBJECT;
1465}
1466
Adam Stonefb679e32018-02-07 10:25:48 -08001467void DrmHal::reportFrameworkMetrics() const
1468{
Robert Shih82ea6be2019-11-07 17:47:23 -08001469 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1470 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001471 String8 vendor;
1472 String8 description;
1473 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1474 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001475 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001476 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001477 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001478 }
1479 result = getPropertyStringInternal(String8("description"), description);
1480 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001481 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001482 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001483 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001484 }
Adam Stoneab394d12017-12-22 12:34:20 -08001485
Adam Stonefb679e32018-02-07 10:25:48 -08001486 std::string serializedMetrics;
1487 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1488 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001489 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001490 }
Adam Stone32494f52018-02-26 22:53:27 -08001491 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1492 serializedMetrics.size());
1493 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001494 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001495 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001496 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001497 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001498 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001499 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001500}
1501
1502void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001503{
Adam Stone32494f52018-02-26 22:53:27 -08001504 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001505 String8 vendor;
1506 String8 description;
1507 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1508 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001509 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1510 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1511 metricsVector.size());
1512 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001513 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001514 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001515 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001516 }
1517 }
1518}
1519
Robert Shihfbe581e2021-01-14 05:12:04 -08001520bool DrmHal::requiresSecureDecoder(const char *mime) const {
1521 Mutex::Autolock autoLock(mLock);
1522 if (mPluginV1_4 == NULL) {
1523 return false;
1524 }
1525 return mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1526}
1527
1528bool DrmHal::requiresSecureDecoder(const char *mime,
1529 DrmPlugin::SecurityLevel securityLevel) const {
1530 Mutex::Autolock autoLock(mLock);
1531 if (mPluginV1_4 == NULL) {
1532 return false;
1533 }
1534 auto hLevel = toHidlSecurityLevel(securityLevel);
1535 return mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1536}
1537
Robert Shih726afea2021-01-17 23:41:12 -08001538status_t DrmHal::setPlaybackId(Vector<uint8_t> const &sessionId, const char *playbackId) {
1539 Mutex::Autolock autoLock(mLock);
1540 if (mPluginV1_4 == NULL) {
1541 return ERROR_UNSUPPORTED;
1542 }
1543 drm::V1_0::Status err = mPluginV1_4->setPlaybackId(
1544 toHidlVec(sessionId),
1545 hidl_string(playbackId));
1546 return toStatusT(err);
1547}
1548
Robert Shih9afca952021-02-12 01:36:06 -08001549status_t DrmHal::getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const {
1550 Mutex::Autolock autoLock(mLock);
1551 return DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs);
1552}
1553
Jeff Tinkera53d6552017-01-20 00:31:46 -08001554} // namespace android