blob: f3028d843349647ccbed413798fef2f3feb77d6c [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>
Jeff Tinkera53d6552017-01-20 00:31:46 -080041
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;
Adam Stone28f27c32018-02-05 15:07:48 -080056using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080057using ::android::hardware::hidl_array;
58using ::android::hardware::hidl_string;
59using ::android::hardware::hidl_vec;
60using ::android::hardware::Return;
61using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080062using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080063using ::android::sp;
64
Jeff Tinkerb8684f32018-12-12 08:41:31 -080065typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
66typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080067typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080068
Adam Stonecea91ce2018-01-22 19:23:28 -080069namespace {
70
71// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
72// in the MediaDrm API.
73constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080074constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080075
Adam Stone32494f52018-02-26 22:53:27 -080076template<typename T>
77std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070078 // Note that the base 64 conversion only works with arrays of single-byte
79 // values. If the source is empty or is not an array of single-byte values,
80 // return empty string.
81 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080082 return "";
83 }
Adam Stone32494f52018-02-26 22:53:27 -080084
85 android::AString outputString;
86 encodeBase64(data, size, &outputString);
87 // Remove trailing equals padding if it exists.
88 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
89 outputString.erase(outputString.size() - 1, 1);
90 }
91
92 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080093}
94
Adam Stone32494f52018-02-26 22:53:27 -080095} // anonymous namespace
96
Jeff Tinkera53d6552017-01-20 00:31:46 -080097namespace android {
98
Jeff Tinker6d998b62017-12-18 14:37:43 -080099#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
100
Jeff Tinkera53d6552017-01-20 00:31:46 -0800101static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
102 Vector<uint8_t> vector;
103 vector.appendArray(vec.data(), vec.size());
104 return *const_cast<const Vector<uint8_t> *>(&vector);
105}
106
107static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
108 hidl_vec<uint8_t> vec;
109 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
110 return vec;
111}
112
113static String8 toString8(const hidl_string &string) {
114 return String8(string.c_str());
115}
116
117static hidl_string toHidlString(const String8& string) {
118 return hidl_string(string.string());
119}
120
Jeff Tinker6d998b62017-12-18 14:37:43 -0800121static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
122 switch(level) {
123 case SecurityLevel::SW_SECURE_CRYPTO:
124 return DrmPlugin::kSecurityLevelSwSecureCrypto;
125 case SecurityLevel::SW_SECURE_DECODE:
126 return DrmPlugin::kSecurityLevelSwSecureDecode;
127 case SecurityLevel::HW_SECURE_CRYPTO:
128 return DrmPlugin::kSecurityLevelHwSecureCrypto;
129 case SecurityLevel::HW_SECURE_DECODE:
130 return DrmPlugin::kSecurityLevelHwSecureDecode;
131 case SecurityLevel::HW_SECURE_ALL:
132 return DrmPlugin::kSecurityLevelHwSecureAll;
133 default:
134 return DrmPlugin::kSecurityLevelUnknown;
135 }
136}
137
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800138static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
139 switch(level) {
140 case DrmPlugin::kSecurityLevelSwSecureCrypto:
141 return SecurityLevel::SW_SECURE_CRYPTO;
142 case DrmPlugin::kSecurityLevelSwSecureDecode:
143 return SecurityLevel::SW_SECURE_DECODE;
144 case DrmPlugin::kSecurityLevelHwSecureCrypto:
145 return SecurityLevel::HW_SECURE_CRYPTO;
146 case DrmPlugin::kSecurityLevelHwSecureDecode:
147 return SecurityLevel::HW_SECURE_DECODE;
148 case DrmPlugin::kSecurityLevelHwSecureAll:
149 return SecurityLevel::HW_SECURE_ALL;
150 default:
151 return SecurityLevel::UNKNOWN;
152 }
153}
154
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700155static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
156 OfflineLicenseState licenseState) {
157 switch(licenseState) {
158 case OfflineLicenseState::USABLE:
159 return DrmPlugin::kOfflineLicenseStateUsable;
160 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800161 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700162 default:
163 return DrmPlugin::kOfflineLicenseStateUnknown;
164 }
165}
166
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800167static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800168 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800169 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800170 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800171 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800172 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800173 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800174 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800175 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800176 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800177 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800178 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800179 case HdcpLevel_V1_2::HDCP_V2_3:
180 return DrmPlugin::kHdcpV2_3;
181 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800182 return DrmPlugin::kHdcpNoOutput;
183 default:
184 return DrmPlugin::kHdcpLevelUnknown;
185 }
186}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800187static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
188 keyedVector) {
189 std::vector<KeyValue> stdKeyedVector;
190 for (size_t i = 0; i < keyedVector.size(); i++) {
191 KeyValue keyValue;
192 keyValue.key = toHidlString(keyedVector.keyAt(i));
193 keyValue.value = toHidlString(keyedVector.valueAt(i));
194 stdKeyedVector.push_back(keyValue);
195 }
196 return ::KeyedVector(stdKeyedVector);
197}
198
199static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
200 hKeyedVector) {
201 KeyedVector<String8, String8> keyedVector;
202 for (size_t i = 0; i < hKeyedVector.size(); i++) {
203 keyedVector.add(toString8(hKeyedVector[i].key),
204 toString8(hKeyedVector[i].value));
205 }
206 return keyedVector;
207}
208
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800209static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800210 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800211 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800212 for (size_t i = 0; i < hSecureStops.size(); i++) {
213 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
214 }
215 return secureStops;
216}
217
Jeff Tinker15177d72018-01-25 12:57:55 -0800218static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
219 hSecureStopIds) {
220 List<Vector<uint8_t>> secureStopIds;
221 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
222 secureStopIds.push_back(toVector(hSecureStopIds[i]));
223 }
224 return secureStopIds;
225}
226
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700227static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
228 hKeySetIds) {
229 List<Vector<uint8_t>> keySetIds;
230 for (size_t i = 0; i < hKeySetIds.size(); i++) {
231 keySetIds.push_back(toVector(hKeySetIds[i]));
232 }
233 return keySetIds;
234}
235
Jeff Tinkera53d6552017-01-20 00:31:46 -0800236static status_t toStatusT(Status status) {
237 switch (status) {
238 case Status::OK:
239 return OK;
240 break;
241 case Status::ERROR_DRM_NO_LICENSE:
242 return ERROR_DRM_NO_LICENSE;
243 break;
244 case Status::ERROR_DRM_LICENSE_EXPIRED:
245 return ERROR_DRM_LICENSE_EXPIRED;
246 break;
247 case Status::ERROR_DRM_SESSION_NOT_OPENED:
248 return ERROR_DRM_SESSION_NOT_OPENED;
249 break;
250 case Status::ERROR_DRM_CANNOT_HANDLE:
251 return ERROR_DRM_CANNOT_HANDLE;
252 break;
253 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800254 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800255 break;
256 case Status::BAD_VALUE:
257 return BAD_VALUE;
258 break;
259 case Status::ERROR_DRM_NOT_PROVISIONED:
260 return ERROR_DRM_NOT_PROVISIONED;
261 break;
262 case Status::ERROR_DRM_RESOURCE_BUSY:
263 return ERROR_DRM_RESOURCE_BUSY;
264 break;
265 case Status::ERROR_DRM_DEVICE_REVOKED:
266 return ERROR_DRM_DEVICE_REVOKED;
267 break;
268 case Status::ERROR_DRM_UNKNOWN:
269 default:
270 return ERROR_DRM_UNKNOWN;
271 break;
272 }
273}
274
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800275static status_t toStatusT_1_2(Status_V1_2 status) {
276 switch (status) {
277 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
278 return ERROR_DRM_RESOURCE_CONTENTION;
279 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
280 return ERROR_DRM_FRAME_TOO_LARGE;
281 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
282 return ERROR_DRM_INSUFFICIENT_SECURITY;
283 default:
284 return toStatusT(static_cast<Status>(status));
285 }
286}
287
Jeff Tinkera53d6552017-01-20 00:31:46 -0800288Mutex DrmHal::mLock;
289
Robert Shih0f3a8a02019-11-14 15:43:39 -0800290struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700291 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
292 : mSessionId(sessionId),
293 mDrm(drm) {}
294
Robert Shih0f3a8a02019-11-14 15:43:39 -0800295 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
296 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700297
298 const Vector<uint8_t> mSessionId;
299
Chong Zhang181e6952019-10-09 13:23:39 -0700300 virtual ~DrmSessionClient();
301
302private:
303 wp<DrmHal> mDrm;
304
305 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
306};
307
Robert Shih0f3a8a02019-11-14 15:43:39 -0800308::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
309 auto sessionId = mSessionId;
Robert Shihc3af31b2019-09-20 21:45:01 -0700310 sp<DrmHal> drm = mDrm.promote();
311 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700312 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800313 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800314 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800315 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700316 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700317 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800318 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700319 }
320 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800321 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700322 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800323 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700324}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800325
Robert Shih0f3a8a02019-11-14 15:43:39 -0800326::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700327 String8 name;
328 sp<DrmHal> drm = mDrm.promote();
329 if (drm == NULL) {
330 name.append("<deleted>");
331 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
332 || name.isEmpty()) {
333 name.append("<Get vendor failed or is empty>");
334 }
335 name.append("[");
336 for (size_t i = 0; i < mSessionId.size(); ++i) {
337 name.appendFormat("%02x", mSessionId[i]);
338 }
339 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700340 *_aidl_return = name;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800341 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700342}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800343
Robert Shihc3af31b2019-09-20 21:45:01 -0700344DrmHal::DrmSessionClient::~DrmSessionClient() {
345 DrmSessionManager::Instance()->removeSession(mSessionId);
346}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800347
348DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700349 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800350 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800351}
352
Jeff Tinker61332812017-05-15 16:53:10 -0700353void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800354 Mutex::Autolock autoLock(mLock);
355 auto openSessions = mOpenSessions;
356 for (size_t i = 0; i < openSessions.size(); i++) {
357 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700358 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800359 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700360 }
361 mOpenSessions.clear();
362}
363
Jeff Tinkera53d6552017-01-20 00:31:46 -0800364DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800365}
366
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800367void DrmHal::cleanup() {
368 closeOpenSessions();
369
370 Mutex::Autolock autoLock(mLock);
371 reportPluginMetrics();
372 reportFrameworkMetrics();
373
374 setListener(NULL);
375 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800376 if (mPluginV1_2 != NULL) {
377 if (!mPluginV1_2->setListener(NULL).isOk()) {
378 mInitCheck = DEAD_OBJECT;
379 }
380 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800381 if (!mPlugin->setListener(NULL).isOk()) {
382 mInitCheck = DEAD_OBJECT;
383 }
384 }
385 mPlugin.clear();
386 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700387 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800388}
389
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800390Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
391 Vector<sp<IDrmFactory>> factories;
392
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800393 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800394
395 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800396 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800397 [&factories](const hidl_vec<hidl_string> &registered) {
398 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000399 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800400 if (factory != NULL) {
401 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000402 }
403 }
404 }
405 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800406 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000407 [&factories](const hidl_vec<hidl_string> &registered) {
408 for (const auto &instance : registered) {
409 auto factory = drm::V1_1::IDrmFactory::getService(instance);
410 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000411 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800412 }
413 }
414 }
415 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700416 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700417 [&factories](const hidl_vec<hidl_string> &registered) {
418 for (const auto &instance : registered) {
419 auto factory = drm::V1_2::IDrmFactory::getService(instance);
420 if (factory != NULL) {
421 factories.push_back(factory);
422 }
423 }
424 }
425 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800426 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800427
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800428 if (factories.size() == 0) {
429 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700430 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800431 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000432 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800433 factories.push_back(passthrough);
434 } else {
435 ALOGE("Failed to find any drm factories");
436 }
437 }
438 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800439}
440
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800441sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
442 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800443 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800444 mMetrics.SetAppPackageName(appPackageName);
Robert Shih6152d7c2019-11-19 22:54:27 -0800445 mMetrics.SetAppUid(AIBinder_getCallingUid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800446
447 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800448 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800449 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800450 if (status != Status::OK) {
451 ALOGE("Failed to make drm plugin");
452 return;
453 }
454 plugin = hPlugin;
455 }
456 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700457
458 if (!hResult.isOk()) {
459 ALOGE("createPlugin remote call failed");
460 }
461
Jeff Tinkera53d6552017-01-20 00:31:46 -0800462 return plugin;
463}
464
465status_t DrmHal::initCheck() const {
466 return mInitCheck;
467}
468
469status_t DrmHal::setListener(const sp<IDrmClient>& listener)
470{
471 Mutex::Autolock lock(mEventLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800472 mListener = listener;
473 return NO_ERROR;
474}
475
476Return<void> DrmHal::sendEvent(EventType hEventType,
477 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800478 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800479
480 mEventLock.lock();
481 sp<IDrmClient> listener = mListener;
482 mEventLock.unlock();
483
484 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800485 Mutex::Autolock lock(mNotifyLock);
486 DrmPlugin::EventType eventType;
487 switch(hEventType) {
488 case EventType::PROVISION_REQUIRED:
489 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
490 break;
491 case EventType::KEY_NEEDED:
492 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
493 break;
494 case EventType::KEY_EXPIRED:
495 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
496 break;
497 case EventType::VENDOR_DEFINED:
498 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
499 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700500 case EventType::SESSION_RECLAIMED:
501 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
502 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800503 default:
504 return Void();
505 }
Robert Shih61e1c762019-10-31 21:26:58 -0700506 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800507 }
508 return Void();
509}
510
511Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
512 int64_t expiryTimeInMS) {
513
514 mEventLock.lock();
515 sp<IDrmClient> listener = mListener;
516 mEventLock.unlock();
517
518 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800519 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700520 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800521 }
522 return Void();
523}
524
525Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700526 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
527 std::vector<KeyStatus> keyStatusVec;
528 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
529 keyStatusVec.push_back({keyStatus_V1_0.keyId,
530 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
531 }
532 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
533 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
534}
535
536Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700537 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800538
539 mEventLock.lock();
540 sp<IDrmClient> listener = mListener;
541 mEventLock.unlock();
542
543 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700544 std::vector<DrmKeyStatus> keyStatusList;
545 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800546 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700547 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800548 uint32_t type;
549 switch(keyStatus.type) {
550 case KeyStatusType::USABLE:
551 type = DrmPlugin::kKeyStatusType_Usable;
552 break;
553 case KeyStatusType::EXPIRED:
554 type = DrmPlugin::kKeyStatusType_Expired;
555 break;
556 case KeyStatusType::OUTPUTNOTALLOWED:
557 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
558 break;
559 case KeyStatusType::STATUSPENDING:
560 type = DrmPlugin::kKeyStatusType_StatusPending;
561 break;
Robert Shiha5033262019-05-06 14:15:12 -0700562 case KeyStatusType::USABLEINFUTURE:
563 type = DrmPlugin::kKeyStatusType_UsableInFuture;
564 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800565 case KeyStatusType::INTERNALERROR:
566 default:
567 type = DrmPlugin::kKeyStatusType_InternalError;
568 break;
569 }
Robert Shih61e1c762019-10-31 21:26:58 -0700570 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800571 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800572 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800573
574 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700575 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800576 } else {
577 // There's no listener. But we still want to count the key change
578 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700579 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800580 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700581 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800582 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800584
Jeff Tinkera53d6552017-01-20 00:31:46 -0800585 return Void();
586}
587
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800588Return<void> DrmHal::sendSessionLostState(
589 const hidl_vec<uint8_t>& sessionId) {
590
591 mEventLock.lock();
592 sp<IDrmClient> listener = mListener;
593 mEventLock.unlock();
594
595 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800596 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700597 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800598 }
599 return Void();
600}
601
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800602status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
603 const uint8_t uuid[16],
604 const String8 &mimeType,
605 DrmPlugin::SecurityLevel level,
606 bool *isSupported) {
607 *isSupported = false;
608
609 // handle default value cases
610 if (level == DrmPlugin::kSecurityLevelUnknown) {
611 if (mimeType == "") {
612 // isCryptoSchemeSupported(uuid)
613 *isSupported = true;
614 } else {
615 // isCryptoSchemeSupported(uuid, mimeType)
616 *isSupported = factory->isContentTypeSupported(mimeType.string());
617 }
618 return OK;
619 } else if (mimeType == "") {
620 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800621 }
622
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800623 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
624 if (factoryV1_2 == NULL) {
625 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800626 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800627 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
628 mimeType.string(), toHidlSecurityLevel(level));
629 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800630 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800631}
632
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800633status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
634 const String8 &mimeType,
635 DrmPlugin::SecurityLevel level,
636 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800637 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800638 *isSupported = false;
639 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
640 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
641 return matchMimeTypeAndSecurityLevel(mFactories[i],
642 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800643 }
644 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800645 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800646}
647
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800648status_t DrmHal::createPlugin(const uint8_t uuid[16],
649 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800650 Mutex::Autolock autoLock(mLock);
651
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800652 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800653 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800654 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
655 if (plugin != NULL) {
656 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800657 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700658 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800659 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800660 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800661 }
662 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800663
664 if (mPlugin == NULL) {
665 mInitCheck = ERROR_UNSUPPORTED;
666 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800667 mInitCheck = OK;
668 if (mPluginV1_2 != NULL) {
669 if (!mPluginV1_2->setListener(this).isOk()) {
670 mInitCheck = DEAD_OBJECT;
671 }
672 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700673 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800674 }
675 if (mInitCheck != OK) {
676 mPlugin.clear();
677 mPluginV1_1.clear();
678 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700679 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800680 }
681
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800682
Jeff Tinkera53d6552017-01-20 00:31:46 -0800683 return mInitCheck;
684}
685
686status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800687 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800688 return OK;
689}
690
Jeff Tinker41d279a2018-02-11 19:52:08 +0000691status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
692 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800693 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800694 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800695
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800696 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000697 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000698
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800699 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000700 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800701 } else {
702 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
703 return ERROR_DRM_CANNOT_HANDLE;
704 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000705 }
706
707 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800708 bool retry = true;
709 do {
710 hidl_vec<uint8_t> hSessionId;
711
Jeff Tinker41d279a2018-02-11 19:52:08 +0000712 Return<void> hResult;
713 if (mPluginV1_1 == NULL || !setSecurityLevel) {
714 hResult = mPlugin->openSession(
715 [&](Status status,const hidl_vec<uint8_t>& id) {
716 if (status == Status::OK) {
717 sessionId = toVector(id);
718 }
719 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800720 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000721 );
722 } else {
723 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
724 [&](Status status, const hidl_vec<uint8_t>& id) {
725 if (status == Status::OK) {
726 sessionId = toVector(id);
727 }
728 err = toStatusT(status);
729 }
730 );
731 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800732
733 if (!hResult.isOk()) {
734 err = DEAD_OBJECT;
735 }
736
737 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
738 mLock.unlock();
739 // reclaimSession may call back to closeSession, since mLock is
740 // shared between Drm instances, we should unlock here to avoid
741 // deadlock.
Robert Shih6152d7c2019-11-19 22:54:27 -0800742 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800743 mLock.lock();
744 } else {
745 retry = false;
746 }
747 } while (retry);
748
749 if (err == OK) {
Robert Shih0f3a8a02019-11-14 15:43:39 -0800750 std::shared_ptr<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
Robert Shih6152d7c2019-11-19 22:54:27 -0800751 DrmSessionManager::Instance()->addSession(AIBinder_getCallingPid(),
Robert Shih0f3a8a02019-11-14 15:43:39 -0800752 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
753 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800754 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800755 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800756
Adam Stonef0e618d2018-01-17 19:20:41 -0800757 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800758 return err;
759}
760
761status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
762 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800763 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800764
Jeff Tinker319d5f42017-07-26 15:44:33 -0700765 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
766 if (status.isOk()) {
767 if (status == Status::OK) {
768 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800769 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
770 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
771 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700772 break;
773 }
Jeff Tinker61332812017-05-15 16:53:10 -0700774 }
775 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800776 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800777 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800778 mMetrics.mCloseSessionCounter.Increment(response);
779 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800780 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800781 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700782 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800783}
784
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800785static DrmPlugin::KeyRequestType toKeyRequestType(
786 KeyRequestType keyRequestType) {
787 switch (keyRequestType) {
788 case KeyRequestType::INITIAL:
789 return DrmPlugin::kKeyRequestType_Initial;
790 break;
791 case KeyRequestType::RENEWAL:
792 return DrmPlugin::kKeyRequestType_Renewal;
793 break;
794 case KeyRequestType::RELEASE:
795 return DrmPlugin::kKeyRequestType_Release;
796 break;
797 default:
798 return DrmPlugin::kKeyRequestType_Unknown;
799 break;
800 }
801}
802
803static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
804 KeyRequestType_V1_1 keyRequestType) {
805 switch (keyRequestType) {
806 case KeyRequestType_V1_1::NONE:
807 return DrmPlugin::kKeyRequestType_None;
808 break;
809 case KeyRequestType_V1_1::UPDATE:
810 return DrmPlugin::kKeyRequestType_Update;
811 break;
812 default:
813 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
814 break;
815 }
816}
817
Jeff Tinkera53d6552017-01-20 00:31:46 -0800818status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
819 Vector<uint8_t> const &initData, String8 const &mimeType,
820 DrmPlugin::KeyType keyType, KeyedVector<String8,
821 String8> const &optionalParameters, Vector<uint8_t> &request,
822 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
823 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800824 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800825 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800826
827 DrmSessionManager::Instance()->useSession(sessionId);
828
829 KeyType hKeyType;
830 if (keyType == DrmPlugin::kKeyType_Streaming) {
831 hKeyType = KeyType::STREAMING;
832 } else if (keyType == DrmPlugin::kKeyType_Offline) {
833 hKeyType = KeyType::OFFLINE;
834 } else if (keyType == DrmPlugin::kKeyType_Release) {
835 hKeyType = KeyType::RELEASE;
836 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800837 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800838 return BAD_VALUE;
839 }
840
841 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
842
843 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800844 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800845
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800846 if (mPluginV1_2 != NULL) {
847 hResult = mPluginV1_2->getKeyRequest_1_2(
848 toHidlVec(sessionId), toHidlVec(initData),
849 toHidlString(mimeType), hKeyType, hOptionalParameters,
850 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
851 KeyRequestType_V1_1 hKeyRequestType,
852 const hidl_string& hDefaultUrl) {
853 if (status == Status_V1_2::OK) {
854 request = toVector(hRequest);
855 defaultUrl = toString8(hDefaultUrl);
856 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
857 }
858 err = toStatusT_1_2(status);
859 });
860 } else if (mPluginV1_1 != NULL) {
861 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800862 toHidlVec(sessionId), toHidlVec(initData),
863 toHidlString(mimeType), hKeyType, hOptionalParameters,
864 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800865 KeyRequestType_V1_1 hKeyRequestType,
866 const hidl_string& hDefaultUrl) {
867 if (status == Status::OK) {
868 request = toVector(hRequest);
869 defaultUrl = toString8(hDefaultUrl);
870 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800871 }
872 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800873 });
874 } else {
875 hResult = mPlugin->getKeyRequest(
876 toHidlVec(sessionId), toHidlVec(initData),
877 toHidlString(mimeType), hKeyType, hOptionalParameters,
878 [&](Status status, const hidl_vec<uint8_t>& hRequest,
879 KeyRequestType hKeyRequestType,
880 const hidl_string& hDefaultUrl) {
881 if (status == Status::OK) {
882 request = toVector(hRequest);
883 defaultUrl = toString8(hDefaultUrl);
884 *keyRequestType = toKeyRequestType(hKeyRequestType);
885 }
886 err = toStatusT(status);
887 });
888 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800889
Adam Stonef0e618d2018-01-17 19:20:41 -0800890 err = hResult.isOk() ? err : DEAD_OBJECT;
891 keyRequestTimer.SetAttribute(err);
892 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800893}
894
895status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
896 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
897 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800898 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700899 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800900
901 DrmSessionManager::Instance()->useSession(sessionId);
902
903 status_t err = UNKNOWN_ERROR;
904
905 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
906 toHidlVec(response),
907 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
908 if (status == Status::OK) {
909 keySetId = toVector(hKeySetId);
910 }
911 err = toStatusT(status);
912 }
913 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800914 err = hResult.isOk() ? err : DEAD_OBJECT;
915 keyResponseTimer.SetAttribute(err);
916 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800917}
918
919status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
920 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800921 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800922
Jeff Tinker58ad4752018-02-16 16:51:59 -0800923 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
924 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800925}
926
927status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
928 Vector<uint8_t> const &keySetId) {
929 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800930 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800931
932 DrmSessionManager::Instance()->useSession(sessionId);
933
Jeff Tinker58ad4752018-02-16 16:51:59 -0800934 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
935 toHidlVec(keySetId));
936 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937}
938
939status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
940 KeyedVector<String8, String8> &infoMap) const {
941 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800942 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800943
944 DrmSessionManager::Instance()->useSession(sessionId);
945
946 ::KeyedVector hInfoMap;
947
948 status_t err = UNKNOWN_ERROR;
949
950 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
951 [&](Status status, const hidl_vec<KeyValue>& map) {
952 if (status == Status::OK) {
953 infoMap = toKeyedVector(map);
954 }
955 err = toStatusT(status);
956 }
957 );
958
959 return hResult.isOk() ? err : DEAD_OBJECT;
960}
961
962status_t DrmHal::getProvisionRequest(String8 const &certType,
963 String8 const &certAuthority, Vector<uint8_t> &request,
964 String8 &defaultUrl) {
965 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800966 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800967
968 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800969 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800970
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800971 if (mPluginV1_2 != NULL) {
972 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
973 toHidlString(certType), toHidlString(certAuthority),
974 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
975 const hidl_string& hDefaultUrl) {
976 if (status == Status_V1_2::OK) {
977 request = toVector(hRequest);
978 defaultUrl = toString8(hDefaultUrl);
979 }
980 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800981 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800982 );
983 } else {
984 Return<void> hResult = mPlugin->getProvisionRequest(
985 toHidlString(certType), toHidlString(certAuthority),
986 [&](Status status, const hidl_vec<uint8_t>& hRequest,
987 const hidl_string& hDefaultUrl) {
988 if (status == Status::OK) {
989 request = toVector(hRequest);
990 defaultUrl = toString8(hDefaultUrl);
991 }
992 err = toStatusT(status);
993 }
994 );
995 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800996
Adam Stonecea91ce2018-01-22 19:23:28 -0800997 err = hResult.isOk() ? err : DEAD_OBJECT;
998 mMetrics.mGetProvisionRequestCounter.Increment(err);
999 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001000}
1001
1002status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001003 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001004 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001005 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001006
1007 status_t err = UNKNOWN_ERROR;
1008
1009 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1010 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1011 const hidl_vec<uint8_t>& hWrappedKey) {
1012 if (status == Status::OK) {
1013 certificate = toVector(hCertificate);
1014 wrappedKey = toVector(hWrappedKey);
1015 }
1016 err = toStatusT(status);
1017 }
1018 );
1019
Adam Stonecea91ce2018-01-22 19:23:28 -08001020 err = hResult.isOk() ? err : DEAD_OBJECT;
1021 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1022 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001023}
1024
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001025status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001026 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001027 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001028
1029 status_t err = UNKNOWN_ERROR;
1030
1031 Return<void> hResult = mPlugin->getSecureStops(
1032 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1033 if (status == Status::OK) {
1034 secureStops = toSecureStops(hSecureStops);
1035 }
1036 err = toStatusT(status);
1037 }
1038 );
1039
1040 return hResult.isOk() ? err : DEAD_OBJECT;
1041}
1042
1043
Jeff Tinker15177d72018-01-25 12:57:55 -08001044status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1045 Mutex::Autolock autoLock(mLock);
1046
1047 if (mInitCheck != OK) {
1048 return mInitCheck;
1049 }
1050
1051 if (mPluginV1_1 == NULL) {
1052 return ERROR_DRM_CANNOT_HANDLE;
1053 }
1054
1055 status_t err = UNKNOWN_ERROR;
1056
1057 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1058 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1059 if (status == Status::OK) {
1060 secureStopIds = toSecureStopIds(hSecureStopIds);
1061 }
1062 err = toStatusT(status);
1063 }
1064 );
1065
1066 return hResult.isOk() ? err : DEAD_OBJECT;
1067}
1068
1069
Jeff Tinkera53d6552017-01-20 00:31:46 -08001070status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1071 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001072 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001073
1074 status_t err = UNKNOWN_ERROR;
1075
1076 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1077 [&](Status status, const SecureStop& hSecureStop) {
1078 if (status == Status::OK) {
1079 secureStop = toVector(hSecureStop.opaqueData);
1080 }
1081 err = toStatusT(status);
1082 }
1083 );
1084
1085 return hResult.isOk() ? err : DEAD_OBJECT;
1086}
1087
1088status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1089 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) {
1094 SecureStopRelease secureStopRelease;
1095 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001096 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1097 } else {
1098 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001099 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001100 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001101}
1102
Jeff Tinker15177d72018-01-25 12:57:55 -08001103status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1104 Mutex::Autolock autoLock(mLock);
1105
1106 if (mInitCheck != OK) {
1107 return mInitCheck;
1108 }
1109
1110 if (mPluginV1_1 == NULL) {
1111 return ERROR_DRM_CANNOT_HANDLE;
1112 }
1113
Jeff Tinker58ad4752018-02-16 16:51:59 -08001114 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1115 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001116}
1117
1118status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001119 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001120 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001121
Jeff Tinker58ad4752018-02-16 16:51:59 -08001122 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001123 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001124 status = mPluginV1_1->removeAllSecureStops();
1125 } else {
1126 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001127 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001128 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001129}
1130
Jeff Tinker6d998b62017-12-18 14:37:43 -08001131status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1132 DrmPlugin::HdcpLevel *max) const {
1133 Mutex::Autolock autoLock(mLock);
1134 INIT_CHECK();
1135
1136 if (connected == NULL || max == NULL) {
1137 return BAD_VALUE;
1138 }
1139 status_t err = UNKNOWN_ERROR;
1140
Jeff Tinker6d998b62017-12-18 14:37:43 -08001141 *connected = DrmPlugin::kHdcpLevelUnknown;
1142 *max = DrmPlugin::kHdcpLevelUnknown;
1143
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001144 Return<void> hResult;
1145 if (mPluginV1_2 != NULL) {
1146 hResult = mPluginV1_2->getHdcpLevels_1_2(
1147 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1148 if (status == Status_V1_2::OK) {
1149 *connected = toHdcpLevel(hConnected);
1150 *max = toHdcpLevel(hMax);
1151 }
1152 err = toStatusT_1_2(status);
1153 });
1154 } else if (mPluginV1_1 != NULL) {
1155 hResult = mPluginV1_1->getHdcpLevels(
1156 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1157 if (status == Status::OK) {
1158 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1159 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1160 }
1161 err = toStatusT(status);
1162 });
1163 } else {
1164 return ERROR_DRM_CANNOT_HANDLE;
1165 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001166
1167 return hResult.isOk() ? err : DEAD_OBJECT;
1168}
1169
1170status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1171 Mutex::Autolock autoLock(mLock);
1172 INIT_CHECK();
1173
1174 if (open == NULL || max == NULL) {
1175 return BAD_VALUE;
1176 }
1177 status_t err = UNKNOWN_ERROR;
1178
1179 *open = 0;
1180 *max = 0;
1181
1182 if (mPluginV1_1 == NULL) {
1183 return ERROR_DRM_CANNOT_HANDLE;
1184 }
1185
1186 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1187 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1188 if (status == Status::OK) {
1189 *open = hOpen;
1190 *max = hMax;
1191 }
1192 err = toStatusT(status);
1193 }
1194 );
1195
1196 return hResult.isOk() ? err : DEAD_OBJECT;
1197}
1198
1199status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1200 DrmPlugin::SecurityLevel *level) const {
1201 Mutex::Autolock autoLock(mLock);
1202 INIT_CHECK();
1203
1204 if (level == NULL) {
1205 return BAD_VALUE;
1206 }
1207 status_t err = UNKNOWN_ERROR;
1208
1209 if (mPluginV1_1 == NULL) {
1210 return ERROR_DRM_CANNOT_HANDLE;
1211 }
1212
1213 *level = DrmPlugin::kSecurityLevelUnknown;
1214
1215 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1216 [&](Status status, SecurityLevel hLevel) {
1217 if (status == Status::OK) {
1218 *level = toSecurityLevel(hLevel);
1219 }
1220 err = toStatusT(status);
1221 }
1222 );
1223
1224 return hResult.isOk() ? err : DEAD_OBJECT;
1225}
1226
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001227status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1228 Mutex::Autolock autoLock(mLock);
1229
1230 if (mInitCheck != OK) {
1231 return mInitCheck;
1232 }
1233
1234 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001235 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001236 }
1237
1238 status_t err = UNKNOWN_ERROR;
1239
1240 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1241 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1242 if (status == Status::OK) {
1243 keySetIds = toKeySetIds(hKeySetIds);
1244 }
1245 err = toStatusT(status);
1246 }
1247 );
1248
1249 return hResult.isOk() ? err : DEAD_OBJECT;
1250}
1251
1252status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1253 Mutex::Autolock autoLock(mLock);
1254
1255 if (mInitCheck != OK) {
1256 return mInitCheck;
1257 }
1258
1259 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001260 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001261 }
1262
1263 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1264 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1265}
1266
1267status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1268 DrmPlugin::OfflineLicenseState *licenseState) const {
1269 Mutex::Autolock autoLock(mLock);
1270
1271 if (mInitCheck != OK) {
1272 return mInitCheck;
1273 }
1274
1275 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001276 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001277 }
1278 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1279
1280 status_t err = UNKNOWN_ERROR;
1281
1282 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1283 [&](Status status, OfflineLicenseState hLicenseState) {
1284 if (status == Status::OK) {
1285 *licenseState = toOfflineLicenseState(hLicenseState);
1286 }
1287 err = toStatusT(status);
1288 }
1289 );
1290
1291 return hResult.isOk() ? err : DEAD_OBJECT;
1292}
1293
Jeff Tinkera53d6552017-01-20 00:31:46 -08001294status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1295 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001296 return getPropertyStringInternal(name, value);
1297}
1298
1299status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1300 // This function is internal to the class and should only be called while
1301 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001302 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001303
1304 status_t err = UNKNOWN_ERROR;
1305
1306 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1307 [&](Status status, const hidl_string& hValue) {
1308 if (status == Status::OK) {
1309 value = toString8(hValue);
1310 }
1311 err = toStatusT(status);
1312 }
1313 );
1314
1315 return hResult.isOk() ? err : DEAD_OBJECT;
1316}
1317
1318status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1319 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001320 return getPropertyByteArrayInternal(name, value);
1321}
1322
1323status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1324 // This function is internal to the class and should only be called while
1325 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001326 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001327
1328 status_t err = UNKNOWN_ERROR;
1329
1330 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1331 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1332 if (status == Status::OK) {
1333 value = toVector(hValue);
1334 }
1335 err = toStatusT(status);
1336 }
1337 );
1338
Adam Stonecea91ce2018-01-22 19:23:28 -08001339 err = hResult.isOk() ? err : DEAD_OBJECT;
1340 if (name == kPropertyDeviceUniqueId) {
1341 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1342 }
1343 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001344}
1345
1346status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1347 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001348 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001349
Jeff Tinker58ad4752018-02-16 16:51:59 -08001350 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001351 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001352 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001353}
1354
1355status_t DrmHal::setPropertyByteArray(String8 const &name,
1356 Vector<uint8_t> const &value ) const {
1357 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001358 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001359
Jeff Tinker58ad4752018-02-16 16:51:59 -08001360 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001361 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001362 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001363}
1364
Adam Stone28f27c32018-02-05 15:07:48 -08001365status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1366 if (metrics == nullptr) {
1367 return UNEXPECTED_NULL;
1368 }
1369 mMetrics.Export(metrics);
1370
1371 // Append vendor metrics if they are supported.
1372 if (mPluginV1_1 != NULL) {
1373 String8 vendor;
1374 String8 description;
1375 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1376 || vendor.isEmpty()) {
1377 ALOGE("Get vendor failed or is empty");
1378 vendor = "NONE";
1379 }
1380 if (getPropertyStringInternal(String8("description"), description) != OK
1381 || description.isEmpty()) {
1382 ALOGE("Get description failed or is empty.");
1383 description = "NONE";
1384 }
1385 vendor += ".";
1386 vendor += description;
1387
1388 hidl_vec<DrmMetricGroup> pluginMetrics;
1389 status_t err = UNKNOWN_ERROR;
1390
1391 Return<void> status = mPluginV1_1->getMetrics(
1392 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1393 if (status != Status::OK) {
1394 ALOGV("Error getting plugin metrics: %d", status);
1395 } else {
1396 PersistableBundle pluginBundle;
1397 if (MediaDrmMetrics::HidlMetricsToBundle(
1398 pluginMetrics, &pluginBundle) == OK) {
1399 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1400 }
1401 }
1402 err = toStatusT(status);
1403 });
1404 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001405 }
1406
Adam Stoneab394d12017-12-22 12:34:20 -08001407 return OK;
1408}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001409
1410status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1411 String8 const &algorithm) {
1412 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001413 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001414
1415 DrmSessionManager::Instance()->useSession(sessionId);
1416
Jeff Tinkere6412942018-04-30 17:35:16 -07001417 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001418 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001419 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001420}
1421
1422status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1423 String8 const &algorithm) {
1424 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001425 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001426
1427 DrmSessionManager::Instance()->useSession(sessionId);
1428
Jeff Tinkere6412942018-04-30 17:35:16 -07001429 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001430 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001431 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001432}
1433
1434status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001435 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1436 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001437 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001438 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001439
1440 DrmSessionManager::Instance()->useSession(sessionId);
1441
1442 status_t err = UNKNOWN_ERROR;
1443
1444 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1445 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1446 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1447 if (status == Status::OK) {
1448 output = toVector(hOutput);
1449 }
1450 err = toStatusT(status);
1451 }
1452 );
1453
1454 return hResult.isOk() ? err : DEAD_OBJECT;
1455}
1456
1457status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001458 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1459 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001460 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001461 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001462
1463 DrmSessionManager::Instance()->useSession(sessionId);
1464
1465 status_t err = UNKNOWN_ERROR;
1466
1467 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1468 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1469 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1470 if (status == Status::OK) {
1471 output = toVector(hOutput);
1472 }
1473 err = toStatusT(status);
1474 }
1475 );
1476
1477 return hResult.isOk() ? err : DEAD_OBJECT;
1478}
1479
1480status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001481 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1482 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001483 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001484 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001485
1486 DrmSessionManager::Instance()->useSession(sessionId);
1487
1488 status_t err = UNKNOWN_ERROR;
1489
1490 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1491 toHidlVec(keyId), toHidlVec(message),
1492 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1493 if (status == Status::OK) {
1494 signature = toVector(hSignature);
1495 }
1496 err = toStatusT(status);
1497 }
1498 );
1499
1500 return hResult.isOk() ? err : DEAD_OBJECT;
1501}
1502
1503status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001504 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1505 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001506 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001507 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001508
1509 DrmSessionManager::Instance()->useSession(sessionId);
1510
1511 status_t err = UNKNOWN_ERROR;
1512
1513 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1514 toHidlVec(message), toHidlVec(signature),
1515 [&](Status status, bool hMatch) {
1516 if (status == Status::OK) {
1517 match = hMatch;
1518 } else {
1519 match = false;
1520 }
1521 err = toStatusT(status);
1522 }
1523 );
1524
1525 return hResult.isOk() ? err : DEAD_OBJECT;
1526}
1527
1528status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001529 String8 const &algorithm, Vector<uint8_t> const &message,
1530 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001531 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001532 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001533
Jeff Tinkera53d6552017-01-20 00:31:46 -08001534 DrmSessionManager::Instance()->useSession(sessionId);
1535
1536 status_t err = UNKNOWN_ERROR;
1537
1538 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1539 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1540 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1541 if (status == Status::OK) {
1542 signature = toVector(hSignature);
1543 }
1544 err = toStatusT(status);
1545 }
1546 );
1547
1548 return hResult.isOk() ? err : DEAD_OBJECT;
1549}
1550
Adam Stonefb679e32018-02-07 10:25:48 -08001551void DrmHal::reportFrameworkMetrics() const
1552{
Robert Shih82ea6be2019-11-07 17:47:23 -08001553 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1554 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001555 String8 vendor;
1556 String8 description;
1557 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1558 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001559 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001560 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001561 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001562 }
1563 result = getPropertyStringInternal(String8("description"), description);
1564 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001565 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001566 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001567 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001568 }
Adam Stoneab394d12017-12-22 12:34:20 -08001569
Adam Stonefb679e32018-02-07 10:25:48 -08001570 std::string serializedMetrics;
1571 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1572 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001573 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001574 }
Adam Stone32494f52018-02-26 22:53:27 -08001575 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1576 serializedMetrics.size());
1577 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001578 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001579 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001580 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001581 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001582 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001583 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001584}
1585
1586void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001587{
Adam Stone32494f52018-02-26 22:53:27 -08001588 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001589 String8 vendor;
1590 String8 description;
1591 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1592 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001593 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1594 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1595 metricsVector.size());
1596 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001597 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001598 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001599 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001600 }
1601 }
1602}
1603
Jeff Tinkera53d6552017-01-20 00:31:46 -08001604} // namespace android