blob: 40077f928c14b22a7ce841340c29f10bbcd594cd [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
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080025
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>
Chong Zhang181e6952019-10-09 13:23:39 -070028#include <android/media/BnResourceManagerClient.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070029#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080030#include <media/EventMetric.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 inline int getCallingPid() {
102 return IPCThreadState::self()->getCallingPid();
103}
104
105static bool checkPermission(const char* permissionString) {
106 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
107 bool ok = checkCallingPermission(String16(permissionString));
108 if (!ok) ALOGE("Request requires %s", permissionString);
109 return ok;
110}
111
112static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
113 Vector<uint8_t> vector;
114 vector.appendArray(vec.data(), vec.size());
115 return *const_cast<const Vector<uint8_t> *>(&vector);
116}
117
118static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
119 hidl_vec<uint8_t> vec;
120 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
121 return vec;
122}
123
124static String8 toString8(const hidl_string &string) {
125 return String8(string.c_str());
126}
127
128static hidl_string toHidlString(const String8& string) {
129 return hidl_string(string.string());
130}
131
Jeff Tinker6d998b62017-12-18 14:37:43 -0800132static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
133 switch(level) {
134 case SecurityLevel::SW_SECURE_CRYPTO:
135 return DrmPlugin::kSecurityLevelSwSecureCrypto;
136 case SecurityLevel::SW_SECURE_DECODE:
137 return DrmPlugin::kSecurityLevelSwSecureDecode;
138 case SecurityLevel::HW_SECURE_CRYPTO:
139 return DrmPlugin::kSecurityLevelHwSecureCrypto;
140 case SecurityLevel::HW_SECURE_DECODE:
141 return DrmPlugin::kSecurityLevelHwSecureDecode;
142 case SecurityLevel::HW_SECURE_ALL:
143 return DrmPlugin::kSecurityLevelHwSecureAll;
144 default:
145 return DrmPlugin::kSecurityLevelUnknown;
146 }
147}
148
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800149static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
150 switch(level) {
151 case DrmPlugin::kSecurityLevelSwSecureCrypto:
152 return SecurityLevel::SW_SECURE_CRYPTO;
153 case DrmPlugin::kSecurityLevelSwSecureDecode:
154 return SecurityLevel::SW_SECURE_DECODE;
155 case DrmPlugin::kSecurityLevelHwSecureCrypto:
156 return SecurityLevel::HW_SECURE_CRYPTO;
157 case DrmPlugin::kSecurityLevelHwSecureDecode:
158 return SecurityLevel::HW_SECURE_DECODE;
159 case DrmPlugin::kSecurityLevelHwSecureAll:
160 return SecurityLevel::HW_SECURE_ALL;
161 default:
162 return SecurityLevel::UNKNOWN;
163 }
164}
165
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700166static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
167 OfflineLicenseState licenseState) {
168 switch(licenseState) {
169 case OfflineLicenseState::USABLE:
170 return DrmPlugin::kOfflineLicenseStateUsable;
171 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800172 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700173 default:
174 return DrmPlugin::kOfflineLicenseStateUnknown;
175 }
176}
177
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800178static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800179 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800180 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800181 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800182 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800183 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800184 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800185 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800186 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800187 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800188 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800189 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800190 case HdcpLevel_V1_2::HDCP_V2_3:
191 return DrmPlugin::kHdcpV2_3;
192 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800193 return DrmPlugin::kHdcpNoOutput;
194 default:
195 return DrmPlugin::kHdcpLevelUnknown;
196 }
197}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800198static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
199 keyedVector) {
200 std::vector<KeyValue> stdKeyedVector;
201 for (size_t i = 0; i < keyedVector.size(); i++) {
202 KeyValue keyValue;
203 keyValue.key = toHidlString(keyedVector.keyAt(i));
204 keyValue.value = toHidlString(keyedVector.valueAt(i));
205 stdKeyedVector.push_back(keyValue);
206 }
207 return ::KeyedVector(stdKeyedVector);
208}
209
210static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
211 hKeyedVector) {
212 KeyedVector<String8, String8> keyedVector;
213 for (size_t i = 0; i < hKeyedVector.size(); i++) {
214 keyedVector.add(toString8(hKeyedVector[i].key),
215 toString8(hKeyedVector[i].value));
216 }
217 return keyedVector;
218}
219
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800220static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800221 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800222 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800223 for (size_t i = 0; i < hSecureStops.size(); i++) {
224 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
225 }
226 return secureStops;
227}
228
Jeff Tinker15177d72018-01-25 12:57:55 -0800229static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
230 hSecureStopIds) {
231 List<Vector<uint8_t>> secureStopIds;
232 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
233 secureStopIds.push_back(toVector(hSecureStopIds[i]));
234 }
235 return secureStopIds;
236}
237
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700238static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
239 hKeySetIds) {
240 List<Vector<uint8_t>> keySetIds;
241 for (size_t i = 0; i < hKeySetIds.size(); i++) {
242 keySetIds.push_back(toVector(hKeySetIds[i]));
243 }
244 return keySetIds;
245}
246
Jeff Tinkera53d6552017-01-20 00:31:46 -0800247static status_t toStatusT(Status status) {
248 switch (status) {
249 case Status::OK:
250 return OK;
251 break;
252 case Status::ERROR_DRM_NO_LICENSE:
253 return ERROR_DRM_NO_LICENSE;
254 break;
255 case Status::ERROR_DRM_LICENSE_EXPIRED:
256 return ERROR_DRM_LICENSE_EXPIRED;
257 break;
258 case Status::ERROR_DRM_SESSION_NOT_OPENED:
259 return ERROR_DRM_SESSION_NOT_OPENED;
260 break;
261 case Status::ERROR_DRM_CANNOT_HANDLE:
262 return ERROR_DRM_CANNOT_HANDLE;
263 break;
264 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800265 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800266 break;
267 case Status::BAD_VALUE:
268 return BAD_VALUE;
269 break;
270 case Status::ERROR_DRM_NOT_PROVISIONED:
271 return ERROR_DRM_NOT_PROVISIONED;
272 break;
273 case Status::ERROR_DRM_RESOURCE_BUSY:
274 return ERROR_DRM_RESOURCE_BUSY;
275 break;
276 case Status::ERROR_DRM_DEVICE_REVOKED:
277 return ERROR_DRM_DEVICE_REVOKED;
278 break;
279 case Status::ERROR_DRM_UNKNOWN:
280 default:
281 return ERROR_DRM_UNKNOWN;
282 break;
283 }
284}
285
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800286static status_t toStatusT_1_2(Status_V1_2 status) {
287 switch (status) {
288 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
289 return ERROR_DRM_RESOURCE_CONTENTION;
290 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
291 return ERROR_DRM_FRAME_TOO_LARGE;
292 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
293 return ERROR_DRM_INSUFFICIENT_SECURITY;
294 default:
295 return toStatusT(static_cast<Status>(status));
296 }
297}
298
Jeff Tinkera53d6552017-01-20 00:31:46 -0800299Mutex DrmHal::mLock;
300
Chong Zhang181e6952019-10-09 13:23:39 -0700301struct DrmHal::DrmSessionClient : public android::media::BnResourceManagerClient {
302 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
303 : mSessionId(sessionId),
304 mDrm(drm) {}
305
306 ::android::binder::Status reclaimResource(bool* _aidl_return) override;
307 ::android::binder::Status getName(::std::string* _aidl_return) override;
308
309 const Vector<uint8_t> mSessionId;
310
311protected:
312 virtual ~DrmSessionClient();
313
314private:
315 wp<DrmHal> mDrm;
316
317 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
318};
319
320::android::binder::Status DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700321 sp<DrmHal> drm = mDrm.promote();
322 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700323 *_aidl_return = true;
324 return ::android::binder::Status::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800325 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700326 status_t err = drm->closeSession(mSessionId);
327 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700328 *_aidl_return = false;
329 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700330 }
331 drm->sendEvent(EventType::SESSION_RECLAIMED,
332 toHidlVec(mSessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700333 *_aidl_return = true;
334 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700335}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800336
Chong Zhang181e6952019-10-09 13:23:39 -0700337::android::binder::Status DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700338 String8 name;
339 sp<DrmHal> drm = mDrm.promote();
340 if (drm == NULL) {
341 name.append("<deleted>");
342 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
343 || name.isEmpty()) {
344 name.append("<Get vendor failed or is empty>");
345 }
346 name.append("[");
347 for (size_t i = 0; i < mSessionId.size(); ++i) {
348 name.appendFormat("%02x", mSessionId[i]);
349 }
350 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700351 *_aidl_return = name;
352 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700353}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800354
Robert Shihc3af31b2019-09-20 21:45:01 -0700355DrmHal::DrmSessionClient::~DrmSessionClient() {
356 DrmSessionManager::Instance()->removeSession(mSessionId);
357}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800358
359DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700360 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800361 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800362}
363
Jeff Tinker61332812017-05-15 16:53:10 -0700364void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800365 Mutex::Autolock autoLock(mLock);
366 auto openSessions = mOpenSessions;
367 for (size_t i = 0; i < openSessions.size(); i++) {
368 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700369 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800370 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700371 }
372 mOpenSessions.clear();
373}
374
Jeff Tinkera53d6552017-01-20 00:31:46 -0800375DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800376}
377
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800378void DrmHal::cleanup() {
379 closeOpenSessions();
380
381 Mutex::Autolock autoLock(mLock);
382 reportPluginMetrics();
383 reportFrameworkMetrics();
384
385 setListener(NULL);
386 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800387 if (mPluginV1_2 != NULL) {
388 if (!mPluginV1_2->setListener(NULL).isOk()) {
389 mInitCheck = DEAD_OBJECT;
390 }
391 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800392 if (!mPlugin->setListener(NULL).isOk()) {
393 mInitCheck = DEAD_OBJECT;
394 }
395 }
396 mPlugin.clear();
397 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700398 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800399}
400
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800401Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
402 Vector<sp<IDrmFactory>> factories;
403
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800404 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800405
406 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800407 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800408 [&factories](const hidl_vec<hidl_string> &registered) {
409 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000410 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800411 if (factory != NULL) {
412 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000413 }
414 }
415 }
416 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800417 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000418 [&factories](const hidl_vec<hidl_string> &registered) {
419 for (const auto &instance : registered) {
420 auto factory = drm::V1_1::IDrmFactory::getService(instance);
421 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000422 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800423 }
424 }
425 }
426 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700427 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700428 [&factories](const hidl_vec<hidl_string> &registered) {
429 for (const auto &instance : registered) {
430 auto factory = drm::V1_2::IDrmFactory::getService(instance);
431 if (factory != NULL) {
432 factories.push_back(factory);
433 }
434 }
435 }
436 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800438
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800439 if (factories.size() == 0) {
440 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700441 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800442 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000443 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800444 factories.push_back(passthrough);
445 } else {
446 ALOGE("Failed to find any drm factories");
447 }
448 }
449 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800450}
451
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800452sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
453 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800454 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800455 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800456
457 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800458 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800459 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800460 if (status != Status::OK) {
461 ALOGE("Failed to make drm plugin");
462 return;
463 }
464 plugin = hPlugin;
465 }
466 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700467
468 if (!hResult.isOk()) {
469 ALOGE("createPlugin remote call failed");
470 }
471
Jeff Tinkera53d6552017-01-20 00:31:46 -0800472 return plugin;
473}
474
475status_t DrmHal::initCheck() const {
476 return mInitCheck;
477}
478
479status_t DrmHal::setListener(const sp<IDrmClient>& listener)
480{
481 Mutex::Autolock lock(mEventLock);
482 if (mListener != NULL){
483 IInterface::asBinder(mListener)->unlinkToDeath(this);
484 }
485 if (listener != NULL) {
486 IInterface::asBinder(listener)->linkToDeath(this);
487 }
488 mListener = listener;
489 return NO_ERROR;
490}
491
492Return<void> DrmHal::sendEvent(EventType hEventType,
493 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800494 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800495
496 mEventLock.lock();
497 sp<IDrmClient> listener = mListener;
498 mEventLock.unlock();
499
500 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800501 Mutex::Autolock lock(mNotifyLock);
502 DrmPlugin::EventType eventType;
503 switch(hEventType) {
504 case EventType::PROVISION_REQUIRED:
505 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
506 break;
507 case EventType::KEY_NEEDED:
508 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
509 break;
510 case EventType::KEY_EXPIRED:
511 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
512 break;
513 case EventType::VENDOR_DEFINED:
514 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
515 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700516 case EventType::SESSION_RECLAIMED:
517 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
518 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800519 default:
520 return Void();
521 }
Robert Shih61e1c762019-10-31 21:26:58 -0700522 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800523 }
524 return Void();
525}
526
527Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
528 int64_t expiryTimeInMS) {
529
530 mEventLock.lock();
531 sp<IDrmClient> listener = mListener;
532 mEventLock.unlock();
533
534 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800535 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700536 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800537 }
538 return Void();
539}
540
541Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700542 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
543 std::vector<KeyStatus> keyStatusVec;
544 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
545 keyStatusVec.push_back({keyStatus_V1_0.keyId,
546 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
547 }
548 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
549 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
550}
551
552Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700553 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800554
555 mEventLock.lock();
556 sp<IDrmClient> listener = mListener;
557 mEventLock.unlock();
558
559 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700560 std::vector<DrmKeyStatus> keyStatusList;
561 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800562 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700563 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800564 uint32_t type;
565 switch(keyStatus.type) {
566 case KeyStatusType::USABLE:
567 type = DrmPlugin::kKeyStatusType_Usable;
568 break;
569 case KeyStatusType::EXPIRED:
570 type = DrmPlugin::kKeyStatusType_Expired;
571 break;
572 case KeyStatusType::OUTPUTNOTALLOWED:
573 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
574 break;
575 case KeyStatusType::STATUSPENDING:
576 type = DrmPlugin::kKeyStatusType_StatusPending;
577 break;
Robert Shiha5033262019-05-06 14:15:12 -0700578 case KeyStatusType::USABLEINFUTURE:
579 type = DrmPlugin::kKeyStatusType_UsableInFuture;
580 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800581 case KeyStatusType::INTERNALERROR:
582 default:
583 type = DrmPlugin::kKeyStatusType_InternalError;
584 break;
585 }
Robert Shih61e1c762019-10-31 21:26:58 -0700586 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800587 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800588 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800589
590 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700591 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800592 } else {
593 // There's no listener. But we still want to count the key change
594 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700595 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800596 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700597 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800598 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800599 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800600
Jeff Tinkera53d6552017-01-20 00:31:46 -0800601 return Void();
602}
603
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800604Return<void> DrmHal::sendSessionLostState(
605 const hidl_vec<uint8_t>& sessionId) {
606
607 mEventLock.lock();
608 sp<IDrmClient> listener = mListener;
609 mEventLock.unlock();
610
611 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800612 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700613 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800614 }
615 return Void();
616}
617
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800618status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
619 const uint8_t uuid[16],
620 const String8 &mimeType,
621 DrmPlugin::SecurityLevel level,
622 bool *isSupported) {
623 *isSupported = false;
624
625 // handle default value cases
626 if (level == DrmPlugin::kSecurityLevelUnknown) {
627 if (mimeType == "") {
628 // isCryptoSchemeSupported(uuid)
629 *isSupported = true;
630 } else {
631 // isCryptoSchemeSupported(uuid, mimeType)
632 *isSupported = factory->isContentTypeSupported(mimeType.string());
633 }
634 return OK;
635 } else if (mimeType == "") {
636 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800637 }
638
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800639 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
640 if (factoryV1_2 == NULL) {
641 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800642 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800643 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
644 mimeType.string(), toHidlSecurityLevel(level));
645 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800646 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800647}
648
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800649status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
650 const String8 &mimeType,
651 DrmPlugin::SecurityLevel level,
652 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800653 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800654 *isSupported = false;
655 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
656 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
657 return matchMimeTypeAndSecurityLevel(mFactories[i],
658 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800659 }
660 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800661 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800662}
663
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800664status_t DrmHal::createPlugin(const uint8_t uuid[16],
665 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800666 Mutex::Autolock autoLock(mLock);
667
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800668 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800669 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800670 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
671 if (plugin != NULL) {
672 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800673 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700674 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800675 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800676 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800677 }
678 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800679
680 if (mPlugin == NULL) {
681 mInitCheck = ERROR_UNSUPPORTED;
682 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800683 mInitCheck = OK;
684 if (mPluginV1_2 != NULL) {
685 if (!mPluginV1_2->setListener(this).isOk()) {
686 mInitCheck = DEAD_OBJECT;
687 }
688 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700689 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800690 }
691 if (mInitCheck != OK) {
692 mPlugin.clear();
693 mPluginV1_1.clear();
694 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700695 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800696 }
697
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800698
Jeff Tinkera53d6552017-01-20 00:31:46 -0800699 return mInitCheck;
700}
701
702status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800703 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800704 return OK;
705}
706
Jeff Tinker41d279a2018-02-11 19:52:08 +0000707status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
708 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800709 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800710 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800711
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800712 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000713 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000714
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800715 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000716 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800717 } else {
718 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
719 return ERROR_DRM_CANNOT_HANDLE;
720 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000721 }
722
723 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800724 bool retry = true;
725 do {
726 hidl_vec<uint8_t> hSessionId;
727
Jeff Tinker41d279a2018-02-11 19:52:08 +0000728 Return<void> hResult;
729 if (mPluginV1_1 == NULL || !setSecurityLevel) {
730 hResult = mPlugin->openSession(
731 [&](Status status,const hidl_vec<uint8_t>& id) {
732 if (status == Status::OK) {
733 sessionId = toVector(id);
734 }
735 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800736 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000737 );
738 } else {
739 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
740 [&](Status status, const hidl_vec<uint8_t>& id) {
741 if (status == Status::OK) {
742 sessionId = toVector(id);
743 }
744 err = toStatusT(status);
745 }
746 );
747 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800748
749 if (!hResult.isOk()) {
750 err = DEAD_OBJECT;
751 }
752
753 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
754 mLock.unlock();
755 // reclaimSession may call back to closeSession, since mLock is
756 // shared between Drm instances, we should unlock here to avoid
757 // deadlock.
758 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
759 mLock.lock();
760 } else {
761 retry = false;
762 }
763 } while (retry);
764
765 if (err == OK) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700766 sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
767 DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
768 mOpenSessions.push(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800769 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800770 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800771
Adam Stonef0e618d2018-01-17 19:20:41 -0800772 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773 return err;
774}
775
776status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
777 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800778 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800779
Jeff Tinker319d5f42017-07-26 15:44:33 -0700780 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
781 if (status.isOk()) {
782 if (status == Status::OK) {
783 DrmSessionManager::Instance()->removeSession(sessionId);
784 for (size_t i = 0; i < mOpenSessions.size(); i++) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700785 if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700786 mOpenSessions.removeAt(i);
787 break;
788 }
Jeff Tinker61332812017-05-15 16:53:10 -0700789 }
790 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800791 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800792 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800793 mMetrics.mCloseSessionCounter.Increment(response);
794 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800795 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800796 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700797 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800798}
799
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800800static DrmPlugin::KeyRequestType toKeyRequestType(
801 KeyRequestType keyRequestType) {
802 switch (keyRequestType) {
803 case KeyRequestType::INITIAL:
804 return DrmPlugin::kKeyRequestType_Initial;
805 break;
806 case KeyRequestType::RENEWAL:
807 return DrmPlugin::kKeyRequestType_Renewal;
808 break;
809 case KeyRequestType::RELEASE:
810 return DrmPlugin::kKeyRequestType_Release;
811 break;
812 default:
813 return DrmPlugin::kKeyRequestType_Unknown;
814 break;
815 }
816}
817
818static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
819 KeyRequestType_V1_1 keyRequestType) {
820 switch (keyRequestType) {
821 case KeyRequestType_V1_1::NONE:
822 return DrmPlugin::kKeyRequestType_None;
823 break;
824 case KeyRequestType_V1_1::UPDATE:
825 return DrmPlugin::kKeyRequestType_Update;
826 break;
827 default:
828 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
829 break;
830 }
831}
832
Jeff Tinkera53d6552017-01-20 00:31:46 -0800833status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
834 Vector<uint8_t> const &initData, String8 const &mimeType,
835 DrmPlugin::KeyType keyType, KeyedVector<String8,
836 String8> const &optionalParameters, Vector<uint8_t> &request,
837 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
838 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800839 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800840 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841
842 DrmSessionManager::Instance()->useSession(sessionId);
843
844 KeyType hKeyType;
845 if (keyType == DrmPlugin::kKeyType_Streaming) {
846 hKeyType = KeyType::STREAMING;
847 } else if (keyType == DrmPlugin::kKeyType_Offline) {
848 hKeyType = KeyType::OFFLINE;
849 } else if (keyType == DrmPlugin::kKeyType_Release) {
850 hKeyType = KeyType::RELEASE;
851 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800852 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800853 return BAD_VALUE;
854 }
855
856 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
857
858 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800859 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800860
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800861 if (mPluginV1_2 != NULL) {
862 hResult = mPluginV1_2->getKeyRequest_1_2(
863 toHidlVec(sessionId), toHidlVec(initData),
864 toHidlString(mimeType), hKeyType, hOptionalParameters,
865 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
866 KeyRequestType_V1_1 hKeyRequestType,
867 const hidl_string& hDefaultUrl) {
868 if (status == Status_V1_2::OK) {
869 request = toVector(hRequest);
870 defaultUrl = toString8(hDefaultUrl);
871 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
872 }
873 err = toStatusT_1_2(status);
874 });
875 } else if (mPluginV1_1 != NULL) {
876 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800877 toHidlVec(sessionId), toHidlVec(initData),
878 toHidlString(mimeType), hKeyType, hOptionalParameters,
879 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800880 KeyRequestType_V1_1 hKeyRequestType,
881 const hidl_string& hDefaultUrl) {
882 if (status == Status::OK) {
883 request = toVector(hRequest);
884 defaultUrl = toString8(hDefaultUrl);
885 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800886 }
887 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800888 });
889 } else {
890 hResult = mPlugin->getKeyRequest(
891 toHidlVec(sessionId), toHidlVec(initData),
892 toHidlString(mimeType), hKeyType, hOptionalParameters,
893 [&](Status status, const hidl_vec<uint8_t>& hRequest,
894 KeyRequestType hKeyRequestType,
895 const hidl_string& hDefaultUrl) {
896 if (status == Status::OK) {
897 request = toVector(hRequest);
898 defaultUrl = toString8(hDefaultUrl);
899 *keyRequestType = toKeyRequestType(hKeyRequestType);
900 }
901 err = toStatusT(status);
902 });
903 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800904
Adam Stonef0e618d2018-01-17 19:20:41 -0800905 err = hResult.isOk() ? err : DEAD_OBJECT;
906 keyRequestTimer.SetAttribute(err);
907 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800908}
909
910status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
911 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
912 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800913 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700914 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800915
916 DrmSessionManager::Instance()->useSession(sessionId);
917
918 status_t err = UNKNOWN_ERROR;
919
920 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
921 toHidlVec(response),
922 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
923 if (status == Status::OK) {
924 keySetId = toVector(hKeySetId);
925 }
926 err = toStatusT(status);
927 }
928 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800929 err = hResult.isOk() ? err : DEAD_OBJECT;
930 keyResponseTimer.SetAttribute(err);
931 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932}
933
934status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
935 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800936 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937
Jeff Tinker58ad4752018-02-16 16:51:59 -0800938 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
939 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800940}
941
942status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
943 Vector<uint8_t> const &keySetId) {
944 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800945 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800946
947 DrmSessionManager::Instance()->useSession(sessionId);
948
Jeff Tinker58ad4752018-02-16 16:51:59 -0800949 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
950 toHidlVec(keySetId));
951 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800952}
953
954status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
955 KeyedVector<String8, String8> &infoMap) const {
956 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800957 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800958
959 DrmSessionManager::Instance()->useSession(sessionId);
960
961 ::KeyedVector hInfoMap;
962
963 status_t err = UNKNOWN_ERROR;
964
965 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
966 [&](Status status, const hidl_vec<KeyValue>& map) {
967 if (status == Status::OK) {
968 infoMap = toKeyedVector(map);
969 }
970 err = toStatusT(status);
971 }
972 );
973
974 return hResult.isOk() ? err : DEAD_OBJECT;
975}
976
977status_t DrmHal::getProvisionRequest(String8 const &certType,
978 String8 const &certAuthority, Vector<uint8_t> &request,
979 String8 &defaultUrl) {
980 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800981 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800982
983 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800984 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800985
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800986 if (mPluginV1_2 != NULL) {
987 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
988 toHidlString(certType), toHidlString(certAuthority),
989 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
990 const hidl_string& hDefaultUrl) {
991 if (status == Status_V1_2::OK) {
992 request = toVector(hRequest);
993 defaultUrl = toString8(hDefaultUrl);
994 }
995 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800996 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800997 );
998 } else {
999 Return<void> hResult = mPlugin->getProvisionRequest(
1000 toHidlString(certType), toHidlString(certAuthority),
1001 [&](Status status, const hidl_vec<uint8_t>& hRequest,
1002 const hidl_string& hDefaultUrl) {
1003 if (status == Status::OK) {
1004 request = toVector(hRequest);
1005 defaultUrl = toString8(hDefaultUrl);
1006 }
1007 err = toStatusT(status);
1008 }
1009 );
1010 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001011
Adam Stonecea91ce2018-01-22 19:23:28 -08001012 err = hResult.isOk() ? err : DEAD_OBJECT;
1013 mMetrics.mGetProvisionRequestCounter.Increment(err);
1014 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001015}
1016
1017status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001018 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001019 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001020 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001021
1022 status_t err = UNKNOWN_ERROR;
1023
1024 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1025 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1026 const hidl_vec<uint8_t>& hWrappedKey) {
1027 if (status == Status::OK) {
1028 certificate = toVector(hCertificate);
1029 wrappedKey = toVector(hWrappedKey);
1030 }
1031 err = toStatusT(status);
1032 }
1033 );
1034
Adam Stonecea91ce2018-01-22 19:23:28 -08001035 err = hResult.isOk() ? err : DEAD_OBJECT;
1036 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1037 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001038}
1039
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001040status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001041 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->getSecureStops(
1047 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1048 if (status == Status::OK) {
1049 secureStops = toSecureStops(hSecureStops);
1050 }
1051 err = toStatusT(status);
1052 }
1053 );
1054
1055 return hResult.isOk() ? err : DEAD_OBJECT;
1056}
1057
1058
Jeff Tinker15177d72018-01-25 12:57:55 -08001059status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1060 Mutex::Autolock autoLock(mLock);
1061
1062 if (mInitCheck != OK) {
1063 return mInitCheck;
1064 }
1065
1066 if (mPluginV1_1 == NULL) {
1067 return ERROR_DRM_CANNOT_HANDLE;
1068 }
1069
1070 status_t err = UNKNOWN_ERROR;
1071
1072 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1073 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1074 if (status == Status::OK) {
1075 secureStopIds = toSecureStopIds(hSecureStopIds);
1076 }
1077 err = toStatusT(status);
1078 }
1079 );
1080
1081 return hResult.isOk() ? err : DEAD_OBJECT;
1082}
1083
1084
Jeff Tinkera53d6552017-01-20 00:31:46 -08001085status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1086 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001087 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001088
1089 status_t err = UNKNOWN_ERROR;
1090
1091 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1092 [&](Status status, const SecureStop& hSecureStop) {
1093 if (status == Status::OK) {
1094 secureStop = toVector(hSecureStop.opaqueData);
1095 }
1096 err = toStatusT(status);
1097 }
1098 );
1099
1100 return hResult.isOk() ? err : DEAD_OBJECT;
1101}
1102
1103status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1104 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001105 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001106
Jeff Tinker58ad4752018-02-16 16:51:59 -08001107 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001108 if (mPluginV1_1 != NULL) {
1109 SecureStopRelease secureStopRelease;
1110 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001111 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1112 } else {
1113 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001114 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001115 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001116}
1117
Jeff Tinker15177d72018-01-25 12:57:55 -08001118status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1119 Mutex::Autolock autoLock(mLock);
1120
1121 if (mInitCheck != OK) {
1122 return mInitCheck;
1123 }
1124
1125 if (mPluginV1_1 == NULL) {
1126 return ERROR_DRM_CANNOT_HANDLE;
1127 }
1128
Jeff Tinker58ad4752018-02-16 16:51:59 -08001129 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1130 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001131}
1132
1133status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001134 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001135 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001136
Jeff Tinker58ad4752018-02-16 16:51:59 -08001137 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001138 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001139 status = mPluginV1_1->removeAllSecureStops();
1140 } else {
1141 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001142 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001143 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001144}
1145
Jeff Tinker6d998b62017-12-18 14:37:43 -08001146status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1147 DrmPlugin::HdcpLevel *max) const {
1148 Mutex::Autolock autoLock(mLock);
1149 INIT_CHECK();
1150
1151 if (connected == NULL || max == NULL) {
1152 return BAD_VALUE;
1153 }
1154 status_t err = UNKNOWN_ERROR;
1155
Jeff Tinker6d998b62017-12-18 14:37:43 -08001156 *connected = DrmPlugin::kHdcpLevelUnknown;
1157 *max = DrmPlugin::kHdcpLevelUnknown;
1158
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001159 Return<void> hResult;
1160 if (mPluginV1_2 != NULL) {
1161 hResult = mPluginV1_2->getHdcpLevels_1_2(
1162 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1163 if (status == Status_V1_2::OK) {
1164 *connected = toHdcpLevel(hConnected);
1165 *max = toHdcpLevel(hMax);
1166 }
1167 err = toStatusT_1_2(status);
1168 });
1169 } else if (mPluginV1_1 != NULL) {
1170 hResult = mPluginV1_1->getHdcpLevels(
1171 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1172 if (status == Status::OK) {
1173 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1174 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1175 }
1176 err = toStatusT(status);
1177 });
1178 } else {
1179 return ERROR_DRM_CANNOT_HANDLE;
1180 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001181
1182 return hResult.isOk() ? err : DEAD_OBJECT;
1183}
1184
1185status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1186 Mutex::Autolock autoLock(mLock);
1187 INIT_CHECK();
1188
1189 if (open == NULL || max == NULL) {
1190 return BAD_VALUE;
1191 }
1192 status_t err = UNKNOWN_ERROR;
1193
1194 *open = 0;
1195 *max = 0;
1196
1197 if (mPluginV1_1 == NULL) {
1198 return ERROR_DRM_CANNOT_HANDLE;
1199 }
1200
1201 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1202 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1203 if (status == Status::OK) {
1204 *open = hOpen;
1205 *max = hMax;
1206 }
1207 err = toStatusT(status);
1208 }
1209 );
1210
1211 return hResult.isOk() ? err : DEAD_OBJECT;
1212}
1213
1214status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1215 DrmPlugin::SecurityLevel *level) const {
1216 Mutex::Autolock autoLock(mLock);
1217 INIT_CHECK();
1218
1219 if (level == NULL) {
1220 return BAD_VALUE;
1221 }
1222 status_t err = UNKNOWN_ERROR;
1223
1224 if (mPluginV1_1 == NULL) {
1225 return ERROR_DRM_CANNOT_HANDLE;
1226 }
1227
1228 *level = DrmPlugin::kSecurityLevelUnknown;
1229
1230 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1231 [&](Status status, SecurityLevel hLevel) {
1232 if (status == Status::OK) {
1233 *level = toSecurityLevel(hLevel);
1234 }
1235 err = toStatusT(status);
1236 }
1237 );
1238
1239 return hResult.isOk() ? err : DEAD_OBJECT;
1240}
1241
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001242status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1243 Mutex::Autolock autoLock(mLock);
1244
1245 if (mInitCheck != OK) {
1246 return mInitCheck;
1247 }
1248
1249 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001250 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001251 }
1252
1253 status_t err = UNKNOWN_ERROR;
1254
1255 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1256 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1257 if (status == Status::OK) {
1258 keySetIds = toKeySetIds(hKeySetIds);
1259 }
1260 err = toStatusT(status);
1261 }
1262 );
1263
1264 return hResult.isOk() ? err : DEAD_OBJECT;
1265}
1266
1267status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1268 Mutex::Autolock autoLock(mLock);
1269
1270 if (mInitCheck != OK) {
1271 return mInitCheck;
1272 }
1273
1274 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001275 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001276 }
1277
1278 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1279 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1280}
1281
1282status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1283 DrmPlugin::OfflineLicenseState *licenseState) const {
1284 Mutex::Autolock autoLock(mLock);
1285
1286 if (mInitCheck != OK) {
1287 return mInitCheck;
1288 }
1289
1290 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001291 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001292 }
1293 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1294
1295 status_t err = UNKNOWN_ERROR;
1296
1297 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1298 [&](Status status, OfflineLicenseState hLicenseState) {
1299 if (status == Status::OK) {
1300 *licenseState = toOfflineLicenseState(hLicenseState);
1301 }
1302 err = toStatusT(status);
1303 }
1304 );
1305
1306 return hResult.isOk() ? err : DEAD_OBJECT;
1307}
1308
Jeff Tinkera53d6552017-01-20 00:31:46 -08001309status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1310 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001311 return getPropertyStringInternal(name, value);
1312}
1313
1314status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1315 // This function is internal to the class and should only be called while
1316 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001317 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001318
1319 status_t err = UNKNOWN_ERROR;
1320
1321 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1322 [&](Status status, const hidl_string& hValue) {
1323 if (status == Status::OK) {
1324 value = toString8(hValue);
1325 }
1326 err = toStatusT(status);
1327 }
1328 );
1329
1330 return hResult.isOk() ? err : DEAD_OBJECT;
1331}
1332
1333status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1334 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001335 return getPropertyByteArrayInternal(name, value);
1336}
1337
1338status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1339 // This function is internal to the class and should only be called while
1340 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001341 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001342
1343 status_t err = UNKNOWN_ERROR;
1344
1345 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1346 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1347 if (status == Status::OK) {
1348 value = toVector(hValue);
1349 }
1350 err = toStatusT(status);
1351 }
1352 );
1353
Adam Stonecea91ce2018-01-22 19:23:28 -08001354 err = hResult.isOk() ? err : DEAD_OBJECT;
1355 if (name == kPropertyDeviceUniqueId) {
1356 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1357 }
1358 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001359}
1360
1361status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1362 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001363 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001364
Jeff Tinker58ad4752018-02-16 16:51:59 -08001365 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001366 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001367 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001368}
1369
1370status_t DrmHal::setPropertyByteArray(String8 const &name,
1371 Vector<uint8_t> const &value ) const {
1372 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001373 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001374
Jeff Tinker58ad4752018-02-16 16:51:59 -08001375 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001376 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001377 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001378}
1379
Adam Stone28f27c32018-02-05 15:07:48 -08001380status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1381 if (metrics == nullptr) {
1382 return UNEXPECTED_NULL;
1383 }
1384 mMetrics.Export(metrics);
1385
1386 // Append vendor metrics if they are supported.
1387 if (mPluginV1_1 != NULL) {
1388 String8 vendor;
1389 String8 description;
1390 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1391 || vendor.isEmpty()) {
1392 ALOGE("Get vendor failed or is empty");
1393 vendor = "NONE";
1394 }
1395 if (getPropertyStringInternal(String8("description"), description) != OK
1396 || description.isEmpty()) {
1397 ALOGE("Get description failed or is empty.");
1398 description = "NONE";
1399 }
1400 vendor += ".";
1401 vendor += description;
1402
1403 hidl_vec<DrmMetricGroup> pluginMetrics;
1404 status_t err = UNKNOWN_ERROR;
1405
1406 Return<void> status = mPluginV1_1->getMetrics(
1407 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1408 if (status != Status::OK) {
1409 ALOGV("Error getting plugin metrics: %d", status);
1410 } else {
1411 PersistableBundle pluginBundle;
1412 if (MediaDrmMetrics::HidlMetricsToBundle(
1413 pluginMetrics, &pluginBundle) == OK) {
1414 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1415 }
1416 }
1417 err = toStatusT(status);
1418 });
1419 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001420 }
1421
Adam Stoneab394d12017-12-22 12:34:20 -08001422 return OK;
1423}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001424
1425status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1426 String8 const &algorithm) {
1427 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001428 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001429
1430 DrmSessionManager::Instance()->useSession(sessionId);
1431
Jeff Tinkere6412942018-04-30 17:35:16 -07001432 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001433 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001434 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001435}
1436
1437status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1438 String8 const &algorithm) {
1439 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001440 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001441
1442 DrmSessionManager::Instance()->useSession(sessionId);
1443
Jeff Tinkere6412942018-04-30 17:35:16 -07001444 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001445 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001446 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001447}
1448
1449status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001450 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1451 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001452 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001453 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001454
1455 DrmSessionManager::Instance()->useSession(sessionId);
1456
1457 status_t err = UNKNOWN_ERROR;
1458
1459 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1460 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1461 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1462 if (status == Status::OK) {
1463 output = toVector(hOutput);
1464 }
1465 err = toStatusT(status);
1466 }
1467 );
1468
1469 return hResult.isOk() ? err : DEAD_OBJECT;
1470}
1471
1472status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001473 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1474 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001475 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001476 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001477
1478 DrmSessionManager::Instance()->useSession(sessionId);
1479
1480 status_t err = UNKNOWN_ERROR;
1481
1482 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1483 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1484 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1485 if (status == Status::OK) {
1486 output = toVector(hOutput);
1487 }
1488 err = toStatusT(status);
1489 }
1490 );
1491
1492 return hResult.isOk() ? err : DEAD_OBJECT;
1493}
1494
1495status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001496 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1497 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001498 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001499 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001500
1501 DrmSessionManager::Instance()->useSession(sessionId);
1502
1503 status_t err = UNKNOWN_ERROR;
1504
1505 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1506 toHidlVec(keyId), toHidlVec(message),
1507 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1508 if (status == Status::OK) {
1509 signature = toVector(hSignature);
1510 }
1511 err = toStatusT(status);
1512 }
1513 );
1514
1515 return hResult.isOk() ? err : DEAD_OBJECT;
1516}
1517
1518status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001519 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1520 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001521 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001522 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001523
1524 DrmSessionManager::Instance()->useSession(sessionId);
1525
1526 status_t err = UNKNOWN_ERROR;
1527
1528 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1529 toHidlVec(message), toHidlVec(signature),
1530 [&](Status status, bool hMatch) {
1531 if (status == Status::OK) {
1532 match = hMatch;
1533 } else {
1534 match = false;
1535 }
1536 err = toStatusT(status);
1537 }
1538 );
1539
1540 return hResult.isOk() ? err : DEAD_OBJECT;
1541}
1542
1543status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001544 String8 const &algorithm, Vector<uint8_t> const &message,
1545 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001546 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001547 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001548
1549 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1550 return -EPERM;
1551 }
1552
1553 DrmSessionManager::Instance()->useSession(sessionId);
1554
1555 status_t err = UNKNOWN_ERROR;
1556
1557 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1558 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1559 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1560 if (status == Status::OK) {
1561 signature = toVector(hSignature);
1562 }
1563 err = toStatusT(status);
1564 }
1565 );
1566
1567 return hResult.isOk() ? err : DEAD_OBJECT;
1568}
1569
1570void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1571{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001572 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001573}
1574
Adam Stonefb679e32018-02-07 10:25:48 -08001575void DrmHal::reportFrameworkMetrics() const
1576{
Ray Essick6a305222019-01-28 20:33:18 -08001577 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
Ray Essick6a305222019-01-28 20:33:18 -08001578 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001579 String8 vendor;
1580 String8 description;
1581 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1582 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001583 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001584 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001585 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001586 }
1587 result = getPropertyStringInternal(String8("description"), description);
1588 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001589 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001590 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001591 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001592 }
Adam Stoneab394d12017-12-22 12:34:20 -08001593
Adam Stonefb679e32018-02-07 10:25:48 -08001594 std::string serializedMetrics;
1595 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1596 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001597 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001598 }
Adam Stone32494f52018-02-26 22:53:27 -08001599 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1600 serializedMetrics.size());
1601 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001602 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001603 }
Ray Essick6a305222019-01-28 20:33:18 -08001604 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001605 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001606 }
1607}
1608
1609void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001610{
Adam Stone32494f52018-02-26 22:53:27 -08001611 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001612 String8 vendor;
1613 String8 description;
1614 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1615 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001616 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1617 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1618 metricsVector.size());
1619 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1620 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001621 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001622 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001623 }
1624 }
1625}
1626
Jeff Tinkera53d6552017-01-20 00:31:46 -08001627} // namespace android