blob: 501471c5103e2f3db3190a9b57fab2fd7edc89ca [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"
Adam Stonefb679e32018-02-07 10:25:48 -080019#include <iomanip>
20
Jeff Tinkera53d6552017-01-20 00:31:46 -080021#include <utils/Log.h>
22
Robert Shih6152d7c2019-11-19 22:54:27 -080023#include <android/binder_manager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080024
Robert Shih0f3a8a02019-11-14 15:43:39 -080025#include <aidl/android/media/BnResourceManagerClient.h>
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070026#include <android/hardware/drm/1.2/types.h>
Peter Kalauskasca5642c2018-11-12 12:34:42 -080027#include <android/hidl/manager/1.2/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070028#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080029#include <media/EventMetric.h>
Robert Shih82ea6be2019-11-07 17:47:23 -080030#include <media/MediaMetrics.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070031#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080032#include <media/drm/DrmAPI.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080035#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080036#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080038#include <mediadrm/DrmHal.h>
39#include <mediadrm/DrmSessionClientInterface.h>
40#include <mediadrm/DrmSessionManager.h>
Robert Shih93538812019-11-12 12:21:35 -080041#include <mediadrm/IDrmMetricsConsumer.h>
Robert Shihc0d1d0e2019-11-24 13:21:04 -080042#include <mediadrm/DrmUtils.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080043
Robert Shih61e1c762019-10-31 21:26:58 -070044#include <vector>
45
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080047using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::KeyType;
49using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080050using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080051using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080052using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070053using drm::V1_1::HdcpLevel;
54using drm::V1_1::SecureStopRelease;
55using drm::V1_1::SecurityLevel;
56using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070057using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080058using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080059using ::android::hardware::hidl_array;
60using ::android::hardware::hidl_string;
61using ::android::hardware::hidl_vec;
62using ::android::hardware::Return;
63using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080064using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080065using ::android::sp;
66
Jeff Tinkerb8684f32018-12-12 08:41:31 -080067typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
68typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080069typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080070
Adam Stonecea91ce2018-01-22 19:23:28 -080071namespace {
72
73// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
74// in the MediaDrm API.
75constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080076constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080077
Adam Stone32494f52018-02-26 22:53:27 -080078template<typename T>
79std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070080 // Note that the base 64 conversion only works with arrays of single-byte
81 // values. If the source is empty or is not an array of single-byte values,
82 // return empty string.
83 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080084 return "";
85 }
Adam Stone32494f52018-02-26 22:53:27 -080086
87 android::AString outputString;
88 encodeBase64(data, size, &outputString);
89 // Remove trailing equals padding if it exists.
90 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
91 outputString.erase(outputString.size() - 1, 1);
92 }
93
94 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080095}
96
Adam Stone32494f52018-02-26 22:53:27 -080097} // anonymous namespace
98
Jeff Tinkera53d6552017-01-20 00:31:46 -080099namespace android {
100
Jeff Tinker6d998b62017-12-18 14:37:43 -0800101#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
102
Jeff Tinkera53d6552017-01-20 00:31:46 -0800103static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
104 Vector<uint8_t> vector;
105 vector.appendArray(vec.data(), vec.size());
106 return *const_cast<const Vector<uint8_t> *>(&vector);
107}
108
109static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
110 hidl_vec<uint8_t> vec;
111 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
112 return vec;
113}
114
115static String8 toString8(const hidl_string &string) {
116 return String8(string.c_str());
117}
118
119static hidl_string toHidlString(const String8& string) {
120 return hidl_string(string.string());
121}
122
Jeff Tinker6d998b62017-12-18 14:37:43 -0800123static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
124 switch(level) {
125 case SecurityLevel::SW_SECURE_CRYPTO:
126 return DrmPlugin::kSecurityLevelSwSecureCrypto;
127 case SecurityLevel::SW_SECURE_DECODE:
128 return DrmPlugin::kSecurityLevelSwSecureDecode;
129 case SecurityLevel::HW_SECURE_CRYPTO:
130 return DrmPlugin::kSecurityLevelHwSecureCrypto;
131 case SecurityLevel::HW_SECURE_DECODE:
132 return DrmPlugin::kSecurityLevelHwSecureDecode;
133 case SecurityLevel::HW_SECURE_ALL:
134 return DrmPlugin::kSecurityLevelHwSecureAll;
135 default:
136 return DrmPlugin::kSecurityLevelUnknown;
137 }
138}
139
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800140static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
141 switch(level) {
142 case DrmPlugin::kSecurityLevelSwSecureCrypto:
143 return SecurityLevel::SW_SECURE_CRYPTO;
144 case DrmPlugin::kSecurityLevelSwSecureDecode:
145 return SecurityLevel::SW_SECURE_DECODE;
146 case DrmPlugin::kSecurityLevelHwSecureCrypto:
147 return SecurityLevel::HW_SECURE_CRYPTO;
148 case DrmPlugin::kSecurityLevelHwSecureDecode:
149 return SecurityLevel::HW_SECURE_DECODE;
150 case DrmPlugin::kSecurityLevelHwSecureAll:
151 return SecurityLevel::HW_SECURE_ALL;
152 default:
153 return SecurityLevel::UNKNOWN;
154 }
155}
156
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700157static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
158 OfflineLicenseState licenseState) {
159 switch(licenseState) {
160 case OfflineLicenseState::USABLE:
161 return DrmPlugin::kOfflineLicenseStateUsable;
162 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800163 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700164 default:
165 return DrmPlugin::kOfflineLicenseStateUnknown;
166 }
167}
168
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800169static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800170 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800171 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800172 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800173 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800174 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800175 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800176 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800177 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800178 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800179 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800180 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800181 case HdcpLevel_V1_2::HDCP_V2_3:
182 return DrmPlugin::kHdcpV2_3;
183 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800184 return DrmPlugin::kHdcpNoOutput;
185 default:
186 return DrmPlugin::kHdcpLevelUnknown;
187 }
188}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800189static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
190 keyedVector) {
191 std::vector<KeyValue> stdKeyedVector;
192 for (size_t i = 0; i < keyedVector.size(); i++) {
193 KeyValue keyValue;
194 keyValue.key = toHidlString(keyedVector.keyAt(i));
195 keyValue.value = toHidlString(keyedVector.valueAt(i));
196 stdKeyedVector.push_back(keyValue);
197 }
198 return ::KeyedVector(stdKeyedVector);
199}
200
201static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
202 hKeyedVector) {
203 KeyedVector<String8, String8> keyedVector;
204 for (size_t i = 0; i < hKeyedVector.size(); i++) {
205 keyedVector.add(toString8(hKeyedVector[i].key),
206 toString8(hKeyedVector[i].value));
207 }
208 return keyedVector;
209}
210
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800211static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800212 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800213 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800214 for (size_t i = 0; i < hSecureStops.size(); i++) {
215 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
216 }
217 return secureStops;
218}
219
Jeff Tinker15177d72018-01-25 12:57:55 -0800220static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
221 hSecureStopIds) {
222 List<Vector<uint8_t>> secureStopIds;
223 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
224 secureStopIds.push_back(toVector(hSecureStopIds[i]));
225 }
226 return secureStopIds;
227}
228
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700229static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
230 hKeySetIds) {
231 List<Vector<uint8_t>> keySetIds;
232 for (size_t i = 0; i < hKeySetIds.size(); i++) {
233 keySetIds.push_back(toVector(hKeySetIds[i]));
234 }
235 return keySetIds;
236}
237
Jeff Tinkera53d6552017-01-20 00:31:46 -0800238static status_t toStatusT(Status status) {
239 switch (status) {
240 case Status::OK:
241 return OK;
242 break;
243 case Status::ERROR_DRM_NO_LICENSE:
244 return ERROR_DRM_NO_LICENSE;
245 break;
246 case Status::ERROR_DRM_LICENSE_EXPIRED:
247 return ERROR_DRM_LICENSE_EXPIRED;
248 break;
249 case Status::ERROR_DRM_SESSION_NOT_OPENED:
250 return ERROR_DRM_SESSION_NOT_OPENED;
251 break;
252 case Status::ERROR_DRM_CANNOT_HANDLE:
253 return ERROR_DRM_CANNOT_HANDLE;
254 break;
255 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800256 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800257 break;
258 case Status::BAD_VALUE:
259 return BAD_VALUE;
260 break;
261 case Status::ERROR_DRM_NOT_PROVISIONED:
262 return ERROR_DRM_NOT_PROVISIONED;
263 break;
264 case Status::ERROR_DRM_RESOURCE_BUSY:
265 return ERROR_DRM_RESOURCE_BUSY;
266 break;
267 case Status::ERROR_DRM_DEVICE_REVOKED:
268 return ERROR_DRM_DEVICE_REVOKED;
269 break;
270 case Status::ERROR_DRM_UNKNOWN:
271 default:
272 return ERROR_DRM_UNKNOWN;
273 break;
274 }
275}
276
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800277static status_t toStatusT_1_2(Status_V1_2 status) {
278 switch (status) {
279 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
280 return ERROR_DRM_RESOURCE_CONTENTION;
281 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
282 return ERROR_DRM_FRAME_TOO_LARGE;
283 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
284 return ERROR_DRM_INSUFFICIENT_SECURITY;
285 default:
286 return toStatusT(static_cast<Status>(status));
287 }
288}
289
Jeff Tinkera53d6552017-01-20 00:31:46 -0800290Mutex DrmHal::mLock;
291
Robert Shih0f3a8a02019-11-14 15:43:39 -0800292struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700293 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
294 : mSessionId(sessionId),
295 mDrm(drm) {}
296
Robert Shih0f3a8a02019-11-14 15:43:39 -0800297 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
298 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700299
300 const Vector<uint8_t> mSessionId;
301
Chong Zhang181e6952019-10-09 13:23:39 -0700302 virtual ~DrmSessionClient();
303
304private:
305 wp<DrmHal> mDrm;
306
307 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
308};
309
Robert Shih0f3a8a02019-11-14 15:43:39 -0800310::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
311 auto sessionId = mSessionId;
Robert Shihc3af31b2019-09-20 21:45:01 -0700312 sp<DrmHal> drm = mDrm.promote();
313 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700314 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800315 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800316 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800317 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700318 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700319 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800320 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700321 }
322 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800323 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700324 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800325 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700326}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800327
Robert Shih0f3a8a02019-11-14 15:43:39 -0800328::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700329 String8 name;
330 sp<DrmHal> drm = mDrm.promote();
331 if (drm == NULL) {
332 name.append("<deleted>");
333 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
334 || name.isEmpty()) {
335 name.append("<Get vendor failed or is empty>");
336 }
337 name.append("[");
338 for (size_t i = 0; i < mSessionId.size(); ++i) {
339 name.appendFormat("%02x", mSessionId[i]);
340 }
341 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700342 *_aidl_return = name;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800343 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700344}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800345
Robert Shihc3af31b2019-09-20 21:45:01 -0700346DrmHal::DrmSessionClient::~DrmSessionClient() {
347 DrmSessionManager::Instance()->removeSession(mSessionId);
348}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800349
350DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700351 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800352 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800353}
354
Jeff Tinker61332812017-05-15 16:53:10 -0700355void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800356 Mutex::Autolock autoLock(mLock);
357 auto openSessions = mOpenSessions;
358 for (size_t i = 0; i < openSessions.size(); i++) {
359 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700360 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800361 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700362 }
363 mOpenSessions.clear();
364}
365
Jeff Tinkera53d6552017-01-20 00:31:46 -0800366DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800367}
368
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800369void DrmHal::cleanup() {
370 closeOpenSessions();
371
372 Mutex::Autolock autoLock(mLock);
373 reportPluginMetrics();
374 reportFrameworkMetrics();
375
376 setListener(NULL);
377 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800378 if (mPluginV1_2 != NULL) {
379 if (!mPluginV1_2->setListener(NULL).isOk()) {
380 mInitCheck = DEAD_OBJECT;
381 }
382 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800383 if (!mPlugin->setListener(NULL).isOk()) {
384 mInitCheck = DEAD_OBJECT;
385 }
386 }
387 mPlugin.clear();
388 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700389 mPluginV1_2.clear();
Robert Shihfbe581e2021-01-14 05:12:04 -0800390 mPluginV1_4.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800391}
392
Robert Shihc0d1d0e2019-11-24 13:21:04 -0800393std::vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
394 std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800395 if (factories.size() == 0) {
396 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700397 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800398 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000399 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800400 factories.push_back(passthrough);
401 } else {
402 ALOGE("Failed to find any drm factories");
403 }
404 }
405 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800406}
407
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800408sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
409 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800410 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800411 mMetrics.SetAppPackageName(appPackageName);
Robert Shih6152d7c2019-11-19 22:54:27 -0800412 mMetrics.SetAppUid(AIBinder_getCallingUid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800413
414 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800415 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800416 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800417 if (status != Status::OK) {
418 ALOGE("Failed to make drm plugin");
419 return;
420 }
421 plugin = hPlugin;
422 }
423 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700424
425 if (!hResult.isOk()) {
426 ALOGE("createPlugin remote call failed");
427 }
428
Jeff Tinkera53d6552017-01-20 00:31:46 -0800429 return plugin;
430}
431
432status_t DrmHal::initCheck() const {
433 return mInitCheck;
434}
435
436status_t DrmHal::setListener(const sp<IDrmClient>& listener)
437{
438 Mutex::Autolock lock(mEventLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800439 mListener = listener;
440 return NO_ERROR;
441}
442
443Return<void> DrmHal::sendEvent(EventType hEventType,
444 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800445 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800446
447 mEventLock.lock();
448 sp<IDrmClient> listener = mListener;
449 mEventLock.unlock();
450
451 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800452 Mutex::Autolock lock(mNotifyLock);
453 DrmPlugin::EventType eventType;
454 switch(hEventType) {
455 case EventType::PROVISION_REQUIRED:
456 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
457 break;
458 case EventType::KEY_NEEDED:
459 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
460 break;
461 case EventType::KEY_EXPIRED:
462 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
463 break;
464 case EventType::VENDOR_DEFINED:
465 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
466 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700467 case EventType::SESSION_RECLAIMED:
468 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
469 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470 default:
471 return Void();
472 }
Robert Shih61e1c762019-10-31 21:26:58 -0700473 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800474 }
475 return Void();
476}
477
478Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
479 int64_t expiryTimeInMS) {
480
481 mEventLock.lock();
482 sp<IDrmClient> listener = mListener;
483 mEventLock.unlock();
484
485 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800486 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700487 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800488 }
489 return Void();
490}
491
492Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700493 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
494 std::vector<KeyStatus> keyStatusVec;
495 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
496 keyStatusVec.push_back({keyStatus_V1_0.keyId,
497 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
498 }
499 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
500 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
501}
502
503Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700504 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800505
506 mEventLock.lock();
507 sp<IDrmClient> listener = mListener;
508 mEventLock.unlock();
509
510 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700511 std::vector<DrmKeyStatus> keyStatusList;
512 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800513 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700514 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800515 uint32_t type;
516 switch(keyStatus.type) {
517 case KeyStatusType::USABLE:
518 type = DrmPlugin::kKeyStatusType_Usable;
519 break;
520 case KeyStatusType::EXPIRED:
521 type = DrmPlugin::kKeyStatusType_Expired;
522 break;
523 case KeyStatusType::OUTPUTNOTALLOWED:
524 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
525 break;
526 case KeyStatusType::STATUSPENDING:
527 type = DrmPlugin::kKeyStatusType_StatusPending;
528 break;
Robert Shiha5033262019-05-06 14:15:12 -0700529 case KeyStatusType::USABLEINFUTURE:
530 type = DrmPlugin::kKeyStatusType_UsableInFuture;
531 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800532 case KeyStatusType::INTERNALERROR:
533 default:
534 type = DrmPlugin::kKeyStatusType_InternalError;
535 break;
536 }
Robert Shih61e1c762019-10-31 21:26:58 -0700537 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800538 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800539 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800540
541 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700542 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800543 } else {
544 // There's no listener. But we still want to count the key change
545 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700546 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800547 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700548 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800549 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800550 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800551
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552 return Void();
553}
554
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800555Return<void> DrmHal::sendSessionLostState(
556 const hidl_vec<uint8_t>& sessionId) {
557
558 mEventLock.lock();
559 sp<IDrmClient> listener = mListener;
560 mEventLock.unlock();
561
562 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800563 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700564 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800565 }
566 return Void();
567}
568
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800569status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
570 const uint8_t uuid[16],
571 const String8 &mimeType,
572 DrmPlugin::SecurityLevel level,
573 bool *isSupported) {
574 *isSupported = false;
575
576 // handle default value cases
577 if (level == DrmPlugin::kSecurityLevelUnknown) {
578 if (mimeType == "") {
579 // isCryptoSchemeSupported(uuid)
580 *isSupported = true;
581 } else {
582 // isCryptoSchemeSupported(uuid, mimeType)
583 *isSupported = factory->isContentTypeSupported(mimeType.string());
584 }
585 return OK;
586 } else if (mimeType == "") {
587 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800588 }
589
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800590 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
591 if (factoryV1_2 == NULL) {
592 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800593 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800594 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
595 mimeType.string(), toHidlSecurityLevel(level));
596 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800597 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800598}
599
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800600status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
601 const String8 &mimeType,
602 DrmPlugin::SecurityLevel level,
603 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800604 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800605 *isSupported = false;
606 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
607 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
608 return matchMimeTypeAndSecurityLevel(mFactories[i],
609 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800610 }
611 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800612 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800613}
614
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800615status_t DrmHal::createPlugin(const uint8_t uuid[16],
616 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800617 Mutex::Autolock autoLock(mLock);
618
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800619 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800620 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800621 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
622 if (plugin != NULL) {
623 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800624 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700625 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Robert Shihfbe581e2021-01-14 05:12:04 -0800626 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800627 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800628 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800629 }
630 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800631
632 if (mPlugin == NULL) {
633 mInitCheck = ERROR_UNSUPPORTED;
634 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800635 mInitCheck = OK;
636 if (mPluginV1_2 != NULL) {
637 if (!mPluginV1_2->setListener(this).isOk()) {
638 mInitCheck = DEAD_OBJECT;
639 }
640 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700641 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800642 }
643 if (mInitCheck != OK) {
644 mPlugin.clear();
645 mPluginV1_1.clear();
646 mPluginV1_2.clear();
Robert Shihfbe581e2021-01-14 05:12:04 -0800647 mPluginV1_4.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700648 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800649 }
650
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800651
Jeff Tinkera53d6552017-01-20 00:31:46 -0800652 return mInitCheck;
653}
654
655status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800656 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800657 return OK;
658}
659
Jeff Tinker41d279a2018-02-11 19:52:08 +0000660status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
661 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800662 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800663 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800665 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000666 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000667
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800668 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000669 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800670 } else {
671 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
672 return ERROR_DRM_CANNOT_HANDLE;
673 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000674 }
675
676 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800677 bool retry = true;
678 do {
679 hidl_vec<uint8_t> hSessionId;
680
Jeff Tinker41d279a2018-02-11 19:52:08 +0000681 Return<void> hResult;
682 if (mPluginV1_1 == NULL || !setSecurityLevel) {
683 hResult = mPlugin->openSession(
684 [&](Status status,const hidl_vec<uint8_t>& id) {
685 if (status == Status::OK) {
686 sessionId = toVector(id);
687 }
688 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800689 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000690 );
691 } else {
692 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
693 [&](Status status, const hidl_vec<uint8_t>& id) {
694 if (status == Status::OK) {
695 sessionId = toVector(id);
696 }
697 err = toStatusT(status);
698 }
699 );
700 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800701
702 if (!hResult.isOk()) {
703 err = DEAD_OBJECT;
704 }
705
706 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
707 mLock.unlock();
708 // reclaimSession may call back to closeSession, since mLock is
709 // shared between Drm instances, we should unlock here to avoid
710 // deadlock.
Robert Shih6152d7c2019-11-19 22:54:27 -0800711 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800712 mLock.lock();
713 } else {
714 retry = false;
715 }
716 } while (retry);
717
718 if (err == OK) {
Steven Morelande0496a22020-02-13 13:13:52 -0800719 std::shared_ptr<DrmSessionClient> client =
720 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
Robert Shih6152d7c2019-11-19 22:54:27 -0800721 DrmSessionManager::Instance()->addSession(AIBinder_getCallingPid(),
Robert Shih0f3a8a02019-11-14 15:43:39 -0800722 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
723 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800724 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800725 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800726
Adam Stonef0e618d2018-01-17 19:20:41 -0800727 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800728 return err;
729}
730
731status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
732 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800733 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800734
Jeff Tinker319d5f42017-07-26 15:44:33 -0700735 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
736 if (status.isOk()) {
737 if (status == Status::OK) {
738 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800739 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
740 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
741 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700742 break;
743 }
Jeff Tinker61332812017-05-15 16:53:10 -0700744 }
745 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800746 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800747 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800748 mMetrics.mCloseSessionCounter.Increment(response);
749 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800750 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800751 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700752 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800753}
754
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800755static DrmPlugin::KeyRequestType toKeyRequestType(
756 KeyRequestType keyRequestType) {
757 switch (keyRequestType) {
758 case KeyRequestType::INITIAL:
759 return DrmPlugin::kKeyRequestType_Initial;
760 break;
761 case KeyRequestType::RENEWAL:
762 return DrmPlugin::kKeyRequestType_Renewal;
763 break;
764 case KeyRequestType::RELEASE:
765 return DrmPlugin::kKeyRequestType_Release;
766 break;
767 default:
768 return DrmPlugin::kKeyRequestType_Unknown;
769 break;
770 }
771}
772
773static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
774 KeyRequestType_V1_1 keyRequestType) {
775 switch (keyRequestType) {
776 case KeyRequestType_V1_1::NONE:
777 return DrmPlugin::kKeyRequestType_None;
778 break;
779 case KeyRequestType_V1_1::UPDATE:
780 return DrmPlugin::kKeyRequestType_Update;
781 break;
782 default:
783 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
784 break;
785 }
786}
787
Jeff Tinkera53d6552017-01-20 00:31:46 -0800788status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
789 Vector<uint8_t> const &initData, String8 const &mimeType,
790 DrmPlugin::KeyType keyType, KeyedVector<String8,
791 String8> const &optionalParameters, Vector<uint8_t> &request,
792 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
793 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800794 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800795 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800796
797 DrmSessionManager::Instance()->useSession(sessionId);
798
799 KeyType hKeyType;
800 if (keyType == DrmPlugin::kKeyType_Streaming) {
801 hKeyType = KeyType::STREAMING;
802 } else if (keyType == DrmPlugin::kKeyType_Offline) {
803 hKeyType = KeyType::OFFLINE;
804 } else if (keyType == DrmPlugin::kKeyType_Release) {
805 hKeyType = KeyType::RELEASE;
806 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800807 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800808 return BAD_VALUE;
809 }
810
811 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
812
813 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800814 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800815
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800816 if (mPluginV1_2 != NULL) {
817 hResult = mPluginV1_2->getKeyRequest_1_2(
818 toHidlVec(sessionId), toHidlVec(initData),
819 toHidlString(mimeType), hKeyType, hOptionalParameters,
820 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
821 KeyRequestType_V1_1 hKeyRequestType,
822 const hidl_string& hDefaultUrl) {
823 if (status == Status_V1_2::OK) {
824 request = toVector(hRequest);
825 defaultUrl = toString8(hDefaultUrl);
826 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
827 }
828 err = toStatusT_1_2(status);
829 });
830 } else if (mPluginV1_1 != NULL) {
831 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800832 toHidlVec(sessionId), toHidlVec(initData),
833 toHidlString(mimeType), hKeyType, hOptionalParameters,
834 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800835 KeyRequestType_V1_1 hKeyRequestType,
836 const hidl_string& hDefaultUrl) {
837 if (status == Status::OK) {
838 request = toVector(hRequest);
839 defaultUrl = toString8(hDefaultUrl);
840 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841 }
842 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800843 });
844 } else {
845 hResult = mPlugin->getKeyRequest(
846 toHidlVec(sessionId), toHidlVec(initData),
847 toHidlString(mimeType), hKeyType, hOptionalParameters,
848 [&](Status status, const hidl_vec<uint8_t>& hRequest,
849 KeyRequestType hKeyRequestType,
850 const hidl_string& hDefaultUrl) {
851 if (status == Status::OK) {
852 request = toVector(hRequest);
853 defaultUrl = toString8(hDefaultUrl);
854 *keyRequestType = toKeyRequestType(hKeyRequestType);
855 }
856 err = toStatusT(status);
857 });
858 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800859
Adam Stonef0e618d2018-01-17 19:20:41 -0800860 err = hResult.isOk() ? err : DEAD_OBJECT;
861 keyRequestTimer.SetAttribute(err);
862 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800863}
864
865status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
866 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
867 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800868 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700869 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800870
871 DrmSessionManager::Instance()->useSession(sessionId);
872
873 status_t err = UNKNOWN_ERROR;
874
875 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
876 toHidlVec(response),
877 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
878 if (status == Status::OK) {
879 keySetId = toVector(hKeySetId);
880 }
881 err = toStatusT(status);
882 }
883 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800884 err = hResult.isOk() ? err : DEAD_OBJECT;
885 keyResponseTimer.SetAttribute(err);
886 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800887}
888
889status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
890 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800891 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800892
Jeff Tinker58ad4752018-02-16 16:51:59 -0800893 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
894 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800895}
896
897status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
898 Vector<uint8_t> const &keySetId) {
899 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800900 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800901
902 DrmSessionManager::Instance()->useSession(sessionId);
903
Jeff Tinker58ad4752018-02-16 16:51:59 -0800904 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
905 toHidlVec(keySetId));
906 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800907}
908
909status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
910 KeyedVector<String8, String8> &infoMap) const {
911 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800912 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800913
914 DrmSessionManager::Instance()->useSession(sessionId);
915
916 ::KeyedVector hInfoMap;
917
918 status_t err = UNKNOWN_ERROR;
919
920 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
921 [&](Status status, const hidl_vec<KeyValue>& map) {
922 if (status == Status::OK) {
923 infoMap = toKeyedVector(map);
924 }
925 err = toStatusT(status);
926 }
927 );
928
929 return hResult.isOk() ? err : DEAD_OBJECT;
930}
931
932status_t DrmHal::getProvisionRequest(String8 const &certType,
933 String8 const &certAuthority, Vector<uint8_t> &request,
934 String8 &defaultUrl) {
935 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800936 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937
938 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800939 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800940
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800941 if (mPluginV1_2 != NULL) {
942 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
943 toHidlString(certType), toHidlString(certAuthority),
944 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
945 const hidl_string& hDefaultUrl) {
946 if (status == Status_V1_2::OK) {
947 request = toVector(hRequest);
948 defaultUrl = toString8(hDefaultUrl);
949 }
950 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800951 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800952 );
953 } else {
954 Return<void> hResult = mPlugin->getProvisionRequest(
955 toHidlString(certType), toHidlString(certAuthority),
956 [&](Status status, const hidl_vec<uint8_t>& hRequest,
957 const hidl_string& hDefaultUrl) {
958 if (status == Status::OK) {
959 request = toVector(hRequest);
960 defaultUrl = toString8(hDefaultUrl);
961 }
962 err = toStatusT(status);
963 }
964 );
965 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800966
Adam Stonecea91ce2018-01-22 19:23:28 -0800967 err = hResult.isOk() ? err : DEAD_OBJECT;
968 mMetrics.mGetProvisionRequestCounter.Increment(err);
969 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800970}
971
972status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800973 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800974 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800975 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800976
977 status_t err = UNKNOWN_ERROR;
978
979 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
980 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
981 const hidl_vec<uint8_t>& hWrappedKey) {
982 if (status == Status::OK) {
983 certificate = toVector(hCertificate);
984 wrappedKey = toVector(hWrappedKey);
985 }
986 err = toStatusT(status);
987 }
988 );
989
Adam Stonecea91ce2018-01-22 19:23:28 -0800990 err = hResult.isOk() ? err : DEAD_OBJECT;
991 mMetrics.mProvideProvisionResponseCounter.Increment(err);
992 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800993}
994
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800995status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800996 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800997 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800998
999 status_t err = UNKNOWN_ERROR;
1000
1001 Return<void> hResult = mPlugin->getSecureStops(
1002 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1003 if (status == Status::OK) {
1004 secureStops = toSecureStops(hSecureStops);
1005 }
1006 err = toStatusT(status);
1007 }
1008 );
1009
1010 return hResult.isOk() ? err : DEAD_OBJECT;
1011}
1012
1013
Jeff Tinker15177d72018-01-25 12:57:55 -08001014status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1015 Mutex::Autolock autoLock(mLock);
1016
1017 if (mInitCheck != OK) {
1018 return mInitCheck;
1019 }
1020
1021 if (mPluginV1_1 == NULL) {
1022 return ERROR_DRM_CANNOT_HANDLE;
1023 }
1024
1025 status_t err = UNKNOWN_ERROR;
1026
1027 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1028 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1029 if (status == Status::OK) {
1030 secureStopIds = toSecureStopIds(hSecureStopIds);
1031 }
1032 err = toStatusT(status);
1033 }
1034 );
1035
1036 return hResult.isOk() ? err : DEAD_OBJECT;
1037}
1038
1039
Jeff Tinkera53d6552017-01-20 00:31:46 -08001040status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1041 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001042 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001043
1044 status_t err = UNKNOWN_ERROR;
1045
1046 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1047 [&](Status status, const SecureStop& hSecureStop) {
1048 if (status == Status::OK) {
1049 secureStop = toVector(hSecureStop.opaqueData);
1050 }
1051 err = toStatusT(status);
1052 }
1053 );
1054
1055 return hResult.isOk() ? err : DEAD_OBJECT;
1056}
1057
1058status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1059 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001060 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001061
Jeff Tinker58ad4752018-02-16 16:51:59 -08001062 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001063 if (mPluginV1_1 != NULL) {
1064 SecureStopRelease secureStopRelease;
1065 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001066 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1067 } else {
1068 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001069 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001070 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001071}
1072
Jeff Tinker15177d72018-01-25 12:57:55 -08001073status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1074 Mutex::Autolock autoLock(mLock);
1075
1076 if (mInitCheck != OK) {
1077 return mInitCheck;
1078 }
1079
1080 if (mPluginV1_1 == NULL) {
1081 return ERROR_DRM_CANNOT_HANDLE;
1082 }
1083
Jeff Tinker58ad4752018-02-16 16:51:59 -08001084 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1085 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001086}
1087
1088status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001089 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001090 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001091
Jeff Tinker58ad4752018-02-16 16:51:59 -08001092 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001093 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001094 status = mPluginV1_1->removeAllSecureStops();
1095 } else {
1096 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001097 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001098 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001099}
1100
Jeff Tinker6d998b62017-12-18 14:37:43 -08001101status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1102 DrmPlugin::HdcpLevel *max) const {
1103 Mutex::Autolock autoLock(mLock);
1104 INIT_CHECK();
1105
1106 if (connected == NULL || max == NULL) {
1107 return BAD_VALUE;
1108 }
1109 status_t err = UNKNOWN_ERROR;
1110
Jeff Tinker6d998b62017-12-18 14:37:43 -08001111 *connected = DrmPlugin::kHdcpLevelUnknown;
1112 *max = DrmPlugin::kHdcpLevelUnknown;
1113
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001114 Return<void> hResult;
1115 if (mPluginV1_2 != NULL) {
1116 hResult = mPluginV1_2->getHdcpLevels_1_2(
1117 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1118 if (status == Status_V1_2::OK) {
1119 *connected = toHdcpLevel(hConnected);
1120 *max = toHdcpLevel(hMax);
1121 }
1122 err = toStatusT_1_2(status);
1123 });
1124 } else if (mPluginV1_1 != NULL) {
1125 hResult = mPluginV1_1->getHdcpLevels(
1126 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1127 if (status == Status::OK) {
1128 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1129 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1130 }
1131 err = toStatusT(status);
1132 });
1133 } else {
1134 return ERROR_DRM_CANNOT_HANDLE;
1135 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001136
1137 return hResult.isOk() ? err : DEAD_OBJECT;
1138}
1139
1140status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1141 Mutex::Autolock autoLock(mLock);
1142 INIT_CHECK();
1143
1144 if (open == NULL || max == NULL) {
1145 return BAD_VALUE;
1146 }
1147 status_t err = UNKNOWN_ERROR;
1148
1149 *open = 0;
1150 *max = 0;
1151
1152 if (mPluginV1_1 == NULL) {
1153 return ERROR_DRM_CANNOT_HANDLE;
1154 }
1155
1156 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1157 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1158 if (status == Status::OK) {
1159 *open = hOpen;
1160 *max = hMax;
1161 }
1162 err = toStatusT(status);
1163 }
1164 );
1165
1166 return hResult.isOk() ? err : DEAD_OBJECT;
1167}
1168
1169status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1170 DrmPlugin::SecurityLevel *level) const {
1171 Mutex::Autolock autoLock(mLock);
1172 INIT_CHECK();
1173
1174 if (level == NULL) {
1175 return BAD_VALUE;
1176 }
1177 status_t err = UNKNOWN_ERROR;
1178
1179 if (mPluginV1_1 == NULL) {
1180 return ERROR_DRM_CANNOT_HANDLE;
1181 }
1182
1183 *level = DrmPlugin::kSecurityLevelUnknown;
1184
1185 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1186 [&](Status status, SecurityLevel hLevel) {
1187 if (status == Status::OK) {
1188 *level = toSecurityLevel(hLevel);
1189 }
1190 err = toStatusT(status);
1191 }
1192 );
1193
1194 return hResult.isOk() ? err : DEAD_OBJECT;
1195}
1196
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001197status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1198 Mutex::Autolock autoLock(mLock);
1199
1200 if (mInitCheck != OK) {
1201 return mInitCheck;
1202 }
1203
1204 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001205 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001206 }
1207
1208 status_t err = UNKNOWN_ERROR;
1209
1210 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1211 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1212 if (status == Status::OK) {
1213 keySetIds = toKeySetIds(hKeySetIds);
1214 }
1215 err = toStatusT(status);
1216 }
1217 );
1218
1219 return hResult.isOk() ? err : DEAD_OBJECT;
1220}
1221
1222status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1223 Mutex::Autolock autoLock(mLock);
1224
1225 if (mInitCheck != OK) {
1226 return mInitCheck;
1227 }
1228
1229 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001230 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001231 }
1232
1233 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1234 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1235}
1236
1237status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1238 DrmPlugin::OfflineLicenseState *licenseState) const {
1239 Mutex::Autolock autoLock(mLock);
1240
1241 if (mInitCheck != OK) {
1242 return mInitCheck;
1243 }
1244
1245 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001246 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001247 }
1248 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1249
1250 status_t err = UNKNOWN_ERROR;
1251
1252 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1253 [&](Status status, OfflineLicenseState hLicenseState) {
1254 if (status == Status::OK) {
1255 *licenseState = toOfflineLicenseState(hLicenseState);
1256 }
1257 err = toStatusT(status);
1258 }
1259 );
1260
1261 return hResult.isOk() ? err : DEAD_OBJECT;
1262}
1263
Jeff Tinkera53d6552017-01-20 00:31:46 -08001264status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1265 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001266 return getPropertyStringInternal(name, value);
1267}
1268
1269status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1270 // This function is internal to the class and should only be called while
1271 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001272 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001273
1274 status_t err = UNKNOWN_ERROR;
1275
1276 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1277 [&](Status status, const hidl_string& hValue) {
1278 if (status == Status::OK) {
1279 value = toString8(hValue);
1280 }
1281 err = toStatusT(status);
1282 }
1283 );
1284
1285 return hResult.isOk() ? err : DEAD_OBJECT;
1286}
1287
1288status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1289 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001290 return getPropertyByteArrayInternal(name, value);
1291}
1292
1293status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1294 // This function is internal to the class and should only be called while
1295 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001296 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001297
1298 status_t err = UNKNOWN_ERROR;
1299
1300 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1301 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1302 if (status == Status::OK) {
1303 value = toVector(hValue);
1304 }
1305 err = toStatusT(status);
1306 }
1307 );
1308
Adam Stonecea91ce2018-01-22 19:23:28 -08001309 err = hResult.isOk() ? err : DEAD_OBJECT;
1310 if (name == kPropertyDeviceUniqueId) {
1311 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1312 }
1313 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001314}
1315
1316status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1317 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001318 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001319
Jeff Tinker58ad4752018-02-16 16:51:59 -08001320 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001321 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001322 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001323}
1324
1325status_t DrmHal::setPropertyByteArray(String8 const &name,
1326 Vector<uint8_t> const &value ) const {
1327 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001328 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001329
Jeff Tinker58ad4752018-02-16 16:51:59 -08001330 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001331 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001332 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001333}
1334
Robert Shih93538812019-11-12 12:21:35 -08001335status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
1336 if (consumer == nullptr) {
Adam Stone28f27c32018-02-05 15:07:48 -08001337 return UNEXPECTED_NULL;
1338 }
Robert Shih93538812019-11-12 12:21:35 -08001339 consumer->consumeFrameworkMetrics(mMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001340
1341 // Append vendor metrics if they are supported.
1342 if (mPluginV1_1 != NULL) {
1343 String8 vendor;
1344 String8 description;
1345 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1346 || vendor.isEmpty()) {
1347 ALOGE("Get vendor failed or is empty");
1348 vendor = "NONE";
1349 }
1350 if (getPropertyStringInternal(String8("description"), description) != OK
1351 || description.isEmpty()) {
1352 ALOGE("Get description failed or is empty.");
1353 description = "NONE";
1354 }
1355 vendor += ".";
1356 vendor += description;
1357
1358 hidl_vec<DrmMetricGroup> pluginMetrics;
1359 status_t err = UNKNOWN_ERROR;
1360
1361 Return<void> status = mPluginV1_1->getMetrics(
1362 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1363 if (status != Status::OK) {
1364 ALOGV("Error getting plugin metrics: %d", status);
1365 } else {
Robert Shih93538812019-11-12 12:21:35 -08001366 consumer->consumeHidlMetrics(vendor, pluginMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001367 }
1368 err = toStatusT(status);
1369 });
1370 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001371 }
1372
Adam Stoneab394d12017-12-22 12:34:20 -08001373 return OK;
1374}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001375
1376status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1377 String8 const &algorithm) {
1378 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001379 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001380
1381 DrmSessionManager::Instance()->useSession(sessionId);
1382
Jeff Tinkere6412942018-04-30 17:35:16 -07001383 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001384 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001385 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001386}
1387
1388status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1389 String8 const &algorithm) {
1390 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001391 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001392
1393 DrmSessionManager::Instance()->useSession(sessionId);
1394
Jeff Tinkere6412942018-04-30 17:35:16 -07001395 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001396 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001397 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001398}
1399
1400status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001401 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1402 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001403 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001404 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001405
1406 DrmSessionManager::Instance()->useSession(sessionId);
1407
1408 status_t err = UNKNOWN_ERROR;
1409
1410 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1411 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1412 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1413 if (status == Status::OK) {
1414 output = toVector(hOutput);
1415 }
1416 err = toStatusT(status);
1417 }
1418 );
1419
1420 return hResult.isOk() ? err : DEAD_OBJECT;
1421}
1422
1423status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001424 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1425 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001426 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001427 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001428
1429 DrmSessionManager::Instance()->useSession(sessionId);
1430
1431 status_t err = UNKNOWN_ERROR;
1432
1433 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1434 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1435 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1436 if (status == Status::OK) {
1437 output = toVector(hOutput);
1438 }
1439 err = toStatusT(status);
1440 }
1441 );
1442
1443 return hResult.isOk() ? err : DEAD_OBJECT;
1444}
1445
1446status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001447 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1448 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001450 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001451
1452 DrmSessionManager::Instance()->useSession(sessionId);
1453
1454 status_t err = UNKNOWN_ERROR;
1455
1456 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1457 toHidlVec(keyId), toHidlVec(message),
1458 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1459 if (status == Status::OK) {
1460 signature = toVector(hSignature);
1461 }
1462 err = toStatusT(status);
1463 }
1464 );
1465
1466 return hResult.isOk() ? err : DEAD_OBJECT;
1467}
1468
1469status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001470 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1471 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001472 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001473 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001474
1475 DrmSessionManager::Instance()->useSession(sessionId);
1476
1477 status_t err = UNKNOWN_ERROR;
1478
1479 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1480 toHidlVec(message), toHidlVec(signature),
1481 [&](Status status, bool hMatch) {
1482 if (status == Status::OK) {
1483 match = hMatch;
1484 } else {
1485 match = false;
1486 }
1487 err = toStatusT(status);
1488 }
1489 );
1490
1491 return hResult.isOk() ? err : DEAD_OBJECT;
1492}
1493
1494status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001495 String8 const &algorithm, Vector<uint8_t> const &message,
1496 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001497 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001498 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001499
Jeff Tinkera53d6552017-01-20 00:31:46 -08001500 DrmSessionManager::Instance()->useSession(sessionId);
1501
1502 status_t err = UNKNOWN_ERROR;
1503
1504 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1505 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1506 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1507 if (status == Status::OK) {
1508 signature = toVector(hSignature);
1509 }
1510 err = toStatusT(status);
1511 }
1512 );
1513
1514 return hResult.isOk() ? err : DEAD_OBJECT;
1515}
1516
Adam Stonefb679e32018-02-07 10:25:48 -08001517void DrmHal::reportFrameworkMetrics() const
1518{
Robert Shih82ea6be2019-11-07 17:47:23 -08001519 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1520 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001521 String8 vendor;
1522 String8 description;
1523 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1524 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001525 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001526 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001527 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001528 }
1529 result = getPropertyStringInternal(String8("description"), description);
1530 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001531 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001532 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001533 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001534 }
Adam Stoneab394d12017-12-22 12:34:20 -08001535
Adam Stonefb679e32018-02-07 10:25:48 -08001536 std::string serializedMetrics;
1537 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1538 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001539 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001540 }
Adam Stone32494f52018-02-26 22:53:27 -08001541 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1542 serializedMetrics.size());
1543 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001544 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001545 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001546 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001547 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001548 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001549 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001550}
1551
1552void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001553{
Adam Stone32494f52018-02-26 22:53:27 -08001554 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001555 String8 vendor;
1556 String8 description;
1557 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1558 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001559 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1560 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1561 metricsVector.size());
1562 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001563 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001564 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001565 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001566 }
1567 }
1568}
1569
Robert Shihfbe581e2021-01-14 05:12:04 -08001570bool DrmHal::requiresSecureDecoder(const char *mime) const {
1571 Mutex::Autolock autoLock(mLock);
1572 if (mPluginV1_4 == NULL) {
1573 return false;
1574 }
1575 return mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1576}
1577
1578bool DrmHal::requiresSecureDecoder(const char *mime,
1579 DrmPlugin::SecurityLevel securityLevel) const {
1580 Mutex::Autolock autoLock(mLock);
1581 if (mPluginV1_4 == NULL) {
1582 return false;
1583 }
1584 auto hLevel = toHidlSecurityLevel(securityLevel);
1585 return mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1586}
1587
Robert Shih726afea2021-01-17 23:41:12 -08001588status_t DrmHal::setPlaybackId(Vector<uint8_t> const &sessionId, const char *playbackId) {
1589 Mutex::Autolock autoLock(mLock);
1590 if (mPluginV1_4 == NULL) {
1591 return ERROR_UNSUPPORTED;
1592 }
1593 drm::V1_0::Status err = mPluginV1_4->setPlaybackId(
1594 toHidlVec(sessionId),
1595 hidl_string(playbackId));
1596 return toStatusT(err);
1597}
1598
Jeff Tinkera53d6552017-01-20 00:31:46 -08001599} // namespace android