blob: 7cfe90061fccd67b4599598087fec569df033749 [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>
Jeff Tinker593111f2017-05-25 16:00:21 -070028#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080029#include <media/EventMetric.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070030#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080031#include <media/drm/DrmAPI.h>
32#include <media/stagefright/foundation/ADebug.h>
33#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080034#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080035#include <media/stagefright/foundation/hexdump.h>
36#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080037#include <mediadrm/DrmHal.h>
38#include <mediadrm/DrmSessionClientInterface.h>
39#include <mediadrm/DrmSessionManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080040
Jeff Tinker6d998b62017-12-18 14:37:43 -080041using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080042using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080043using drm::V1_0::KeyType;
44using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080045using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080046using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070048using drm::V1_1::HdcpLevel;
49using drm::V1_1::SecureStopRelease;
50using drm::V1_1::SecurityLevel;
51using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070052using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080053using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080054using ::android::hardware::hidl_array;
55using ::android::hardware::hidl_string;
56using ::android::hardware::hidl_vec;
57using ::android::hardware::Return;
58using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080059using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080060using ::android::sp;
61
Jeff Tinkerb8684f32018-12-12 08:41:31 -080062typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
63typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080064typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080065
Adam Stonecea91ce2018-01-22 19:23:28 -080066namespace {
67
68// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
69// in the MediaDrm API.
70constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080071constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080072
Adam Stone32494f52018-02-26 22:53:27 -080073template<typename T>
74std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070075 // Note that the base 64 conversion only works with arrays of single-byte
76 // values. If the source is empty or is not an array of single-byte values,
77 // return empty string.
78 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080079 return "";
80 }
Adam Stone32494f52018-02-26 22:53:27 -080081
82 android::AString outputString;
83 encodeBase64(data, size, &outputString);
84 // Remove trailing equals padding if it exists.
85 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
86 outputString.erase(outputString.size() - 1, 1);
87 }
88
89 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080090}
91
Adam Stone32494f52018-02-26 22:53:27 -080092} // anonymous namespace
93
Jeff Tinkera53d6552017-01-20 00:31:46 -080094namespace android {
95
Jeff Tinker6d998b62017-12-18 14:37:43 -080096#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
97
Jeff Tinkera53d6552017-01-20 00:31:46 -080098static inline int getCallingPid() {
99 return IPCThreadState::self()->getCallingPid();
100}
101
102static bool checkPermission(const char* permissionString) {
103 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
104 bool ok = checkCallingPermission(String16(permissionString));
105 if (!ok) ALOGE("Request requires %s", permissionString);
106 return ok;
107}
108
109static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
110 Vector<uint8_t> vector;
111 vector.appendArray(vec.data(), vec.size());
112 return *const_cast<const Vector<uint8_t> *>(&vector);
113}
114
115static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
116 hidl_vec<uint8_t> vec;
117 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
118 return vec;
119}
120
121static String8 toString8(const hidl_string &string) {
122 return String8(string.c_str());
123}
124
125static hidl_string toHidlString(const String8& string) {
126 return hidl_string(string.string());
127}
128
Jeff Tinker6d998b62017-12-18 14:37:43 -0800129static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
130 switch(level) {
131 case SecurityLevel::SW_SECURE_CRYPTO:
132 return DrmPlugin::kSecurityLevelSwSecureCrypto;
133 case SecurityLevel::SW_SECURE_DECODE:
134 return DrmPlugin::kSecurityLevelSwSecureDecode;
135 case SecurityLevel::HW_SECURE_CRYPTO:
136 return DrmPlugin::kSecurityLevelHwSecureCrypto;
137 case SecurityLevel::HW_SECURE_DECODE:
138 return DrmPlugin::kSecurityLevelHwSecureDecode;
139 case SecurityLevel::HW_SECURE_ALL:
140 return DrmPlugin::kSecurityLevelHwSecureAll;
141 default:
142 return DrmPlugin::kSecurityLevelUnknown;
143 }
144}
145
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800146static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
147 switch(level) {
148 case DrmPlugin::kSecurityLevelSwSecureCrypto:
149 return SecurityLevel::SW_SECURE_CRYPTO;
150 case DrmPlugin::kSecurityLevelSwSecureDecode:
151 return SecurityLevel::SW_SECURE_DECODE;
152 case DrmPlugin::kSecurityLevelHwSecureCrypto:
153 return SecurityLevel::HW_SECURE_CRYPTO;
154 case DrmPlugin::kSecurityLevelHwSecureDecode:
155 return SecurityLevel::HW_SECURE_DECODE;
156 case DrmPlugin::kSecurityLevelHwSecureAll:
157 return SecurityLevel::HW_SECURE_ALL;
158 default:
159 return SecurityLevel::UNKNOWN;
160 }
161}
162
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700163static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
164 OfflineLicenseState licenseState) {
165 switch(licenseState) {
166 case OfflineLicenseState::USABLE:
167 return DrmPlugin::kOfflineLicenseStateUsable;
168 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800169 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700170 default:
171 return DrmPlugin::kOfflineLicenseStateUnknown;
172 }
173}
174
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800175static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800176 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800177 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800178 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800179 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800180 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800181 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800182 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800183 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800184 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800185 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800186 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800187 case HdcpLevel_V1_2::HDCP_V2_3:
188 return DrmPlugin::kHdcpV2_3;
189 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800190 return DrmPlugin::kHdcpNoOutput;
191 default:
192 return DrmPlugin::kHdcpLevelUnknown;
193 }
194}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800195static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
196 keyedVector) {
197 std::vector<KeyValue> stdKeyedVector;
198 for (size_t i = 0; i < keyedVector.size(); i++) {
199 KeyValue keyValue;
200 keyValue.key = toHidlString(keyedVector.keyAt(i));
201 keyValue.value = toHidlString(keyedVector.valueAt(i));
202 stdKeyedVector.push_back(keyValue);
203 }
204 return ::KeyedVector(stdKeyedVector);
205}
206
207static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
208 hKeyedVector) {
209 KeyedVector<String8, String8> keyedVector;
210 for (size_t i = 0; i < hKeyedVector.size(); i++) {
211 keyedVector.add(toString8(hKeyedVector[i].key),
212 toString8(hKeyedVector[i].value));
213 }
214 return keyedVector;
215}
216
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800217static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800218 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800219 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800220 for (size_t i = 0; i < hSecureStops.size(); i++) {
221 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
222 }
223 return secureStops;
224}
225
Jeff Tinker15177d72018-01-25 12:57:55 -0800226static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
227 hSecureStopIds) {
228 List<Vector<uint8_t>> secureStopIds;
229 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
230 secureStopIds.push_back(toVector(hSecureStopIds[i]));
231 }
232 return secureStopIds;
233}
234
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700235static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
236 hKeySetIds) {
237 List<Vector<uint8_t>> keySetIds;
238 for (size_t i = 0; i < hKeySetIds.size(); i++) {
239 keySetIds.push_back(toVector(hKeySetIds[i]));
240 }
241 return keySetIds;
242}
243
Jeff Tinkera53d6552017-01-20 00:31:46 -0800244static status_t toStatusT(Status status) {
245 switch (status) {
246 case Status::OK:
247 return OK;
248 break;
249 case Status::ERROR_DRM_NO_LICENSE:
250 return ERROR_DRM_NO_LICENSE;
251 break;
252 case Status::ERROR_DRM_LICENSE_EXPIRED:
253 return ERROR_DRM_LICENSE_EXPIRED;
254 break;
255 case Status::ERROR_DRM_SESSION_NOT_OPENED:
256 return ERROR_DRM_SESSION_NOT_OPENED;
257 break;
258 case Status::ERROR_DRM_CANNOT_HANDLE:
259 return ERROR_DRM_CANNOT_HANDLE;
260 break;
261 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800262 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800263 break;
264 case Status::BAD_VALUE:
265 return BAD_VALUE;
266 break;
267 case Status::ERROR_DRM_NOT_PROVISIONED:
268 return ERROR_DRM_NOT_PROVISIONED;
269 break;
270 case Status::ERROR_DRM_RESOURCE_BUSY:
271 return ERROR_DRM_RESOURCE_BUSY;
272 break;
273 case Status::ERROR_DRM_DEVICE_REVOKED:
274 return ERROR_DRM_DEVICE_REVOKED;
275 break;
276 case Status::ERROR_DRM_UNKNOWN:
277 default:
278 return ERROR_DRM_UNKNOWN;
279 break;
280 }
281}
282
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800283static status_t toStatusT_1_2(Status_V1_2 status) {
284 switch (status) {
285 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
286 return ERROR_DRM_RESOURCE_CONTENTION;
287 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
288 return ERROR_DRM_FRAME_TOO_LARGE;
289 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
290 return ERROR_DRM_INSUFFICIENT_SECURITY;
291 default:
292 return toStatusT(static_cast<Status>(status));
293 }
294}
295
Jeff Tinkera53d6552017-01-20 00:31:46 -0800296
297Mutex DrmHal::mLock;
298
299struct DrmSessionClient : public DrmSessionClientInterface {
300 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
301
302 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
303 sp<DrmHal> drm = mDrm.promote();
304 if (drm == NULL) {
305 return true;
306 }
307 status_t err = drm->closeSession(sessionId);
308 if (err != OK) {
309 return false;
310 }
311 drm->sendEvent(EventType::SESSION_RECLAIMED,
312 toHidlVec(sessionId), hidl_vec<uint8_t>());
313 return true;
314 }
315
316protected:
317 virtual ~DrmSessionClient() {}
318
319private:
320 wp<DrmHal> mDrm;
321
322 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
323};
324
325DrmHal::DrmHal()
326 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800327 mFactories(makeDrmFactories()),
328 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800329}
330
Jeff Tinker61332812017-05-15 16:53:10 -0700331void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800332 Mutex::Autolock autoLock(mLock);
333 auto openSessions = mOpenSessions;
334 for (size_t i = 0; i < openSessions.size(); i++) {
335 mLock.unlock();
336 closeSession(openSessions[i]);
337 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700338 }
339 mOpenSessions.clear();
340}
341
Jeff Tinkera53d6552017-01-20 00:31:46 -0800342DrmHal::~DrmHal() {
343 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
344}
345
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800346void DrmHal::cleanup() {
347 closeOpenSessions();
348
349 Mutex::Autolock autoLock(mLock);
350 reportPluginMetrics();
351 reportFrameworkMetrics();
352
353 setListener(NULL);
354 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800355 if (mPluginV1_2 != NULL) {
356 if (!mPluginV1_2->setListener(NULL).isOk()) {
357 mInitCheck = DEAD_OBJECT;
358 }
359 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800360 if (!mPlugin->setListener(NULL).isOk()) {
361 mInitCheck = DEAD_OBJECT;
362 }
363 }
364 mPlugin.clear();
365 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700366 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800367}
368
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800369Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
370 Vector<sp<IDrmFactory>> factories;
371
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800372 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800373
374 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800375 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800376 [&factories](const hidl_vec<hidl_string> &registered) {
377 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000378 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800379 if (factory != NULL) {
380 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000381 }
382 }
383 }
384 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800385 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000386 [&factories](const hidl_vec<hidl_string> &registered) {
387 for (const auto &instance : registered) {
388 auto factory = drm::V1_1::IDrmFactory::getService(instance);
389 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000390 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800391 }
392 }
393 }
394 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700395 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700396 [&factories](const hidl_vec<hidl_string> &registered) {
397 for (const auto &instance : registered) {
398 auto factory = drm::V1_2::IDrmFactory::getService(instance);
399 if (factory != NULL) {
400 factories.push_back(factory);
401 }
402 }
403 }
404 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800405 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800406
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800407 if (factories.size() == 0) {
408 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700409 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800410 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000411 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800412 factories.push_back(passthrough);
413 } else {
414 ALOGE("Failed to find any drm factories");
415 }
416 }
417 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800418}
419
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800420sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
421 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800422 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800423 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424
425 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800426 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800427 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800428 if (status != Status::OK) {
429 ALOGE("Failed to make drm plugin");
430 return;
431 }
432 plugin = hPlugin;
433 }
434 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700435
436 if (!hResult.isOk()) {
437 ALOGE("createPlugin remote call failed");
438 }
439
Jeff Tinkera53d6552017-01-20 00:31:46 -0800440 return plugin;
441}
442
443status_t DrmHal::initCheck() const {
444 return mInitCheck;
445}
446
447status_t DrmHal::setListener(const sp<IDrmClient>& listener)
448{
449 Mutex::Autolock lock(mEventLock);
450 if (mListener != NULL){
451 IInterface::asBinder(mListener)->unlinkToDeath(this);
452 }
453 if (listener != NULL) {
454 IInterface::asBinder(listener)->linkToDeath(this);
455 }
456 mListener = listener;
457 return NO_ERROR;
458}
459
460Return<void> DrmHal::sendEvent(EventType hEventType,
461 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800462 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800463
464 mEventLock.lock();
465 sp<IDrmClient> listener = mListener;
466 mEventLock.unlock();
467
468 if (listener != NULL) {
469 Parcel obj;
470 writeByteArray(obj, sessionId);
471 writeByteArray(obj, data);
472
473 Mutex::Autolock lock(mNotifyLock);
474 DrmPlugin::EventType eventType;
475 switch(hEventType) {
476 case EventType::PROVISION_REQUIRED:
477 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
478 break;
479 case EventType::KEY_NEEDED:
480 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
481 break;
482 case EventType::KEY_EXPIRED:
483 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
484 break;
485 case EventType::VENDOR_DEFINED:
486 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
487 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700488 case EventType::SESSION_RECLAIMED:
489 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
490 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800491 default:
492 return Void();
493 }
494 listener->notify(eventType, 0, &obj);
495 }
496 return Void();
497}
498
499Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
500 int64_t expiryTimeInMS) {
501
502 mEventLock.lock();
503 sp<IDrmClient> listener = mListener;
504 mEventLock.unlock();
505
506 if (listener != NULL) {
507 Parcel obj;
508 writeByteArray(obj, sessionId);
509 obj.writeInt64(expiryTimeInMS);
510
511 Mutex::Autolock lock(mNotifyLock);
512 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
513 }
514 return Void();
515}
516
517Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700518 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
519 std::vector<KeyStatus> keyStatusVec;
520 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
521 keyStatusVec.push_back({keyStatus_V1_0.keyId,
522 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
523 }
524 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
525 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
526}
527
528Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Jeff Tinkera53d6552017-01-20 00:31:46 -0800529 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
530
531 mEventLock.lock();
532 sp<IDrmClient> listener = mListener;
533 mEventLock.unlock();
534
535 if (listener != NULL) {
536 Parcel obj;
537 writeByteArray(obj, sessionId);
538
539 size_t nKeys = keyStatusList.size();
540 obj.writeInt32(nKeys);
541 for (size_t i = 0; i < nKeys; ++i) {
542 const KeyStatus &keyStatus = keyStatusList[i];
543 writeByteArray(obj, keyStatus.keyId);
544 uint32_t type;
545 switch(keyStatus.type) {
546 case KeyStatusType::USABLE:
547 type = DrmPlugin::kKeyStatusType_Usable;
548 break;
549 case KeyStatusType::EXPIRED:
550 type = DrmPlugin::kKeyStatusType_Expired;
551 break;
552 case KeyStatusType::OUTPUTNOTALLOWED:
553 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
554 break;
555 case KeyStatusType::STATUSPENDING:
556 type = DrmPlugin::kKeyStatusType_StatusPending;
557 break;
Robert Shiha5033262019-05-06 14:15:12 -0700558 case KeyStatusType::USABLEINFUTURE:
559 type = DrmPlugin::kKeyStatusType_UsableInFuture;
560 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800561 case KeyStatusType::INTERNALERROR:
562 default:
563 type = DrmPlugin::kKeyStatusType_InternalError;
564 break;
565 }
566 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800567 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800568 }
569 obj.writeInt32(hasNewUsableKey);
570
571 Mutex::Autolock lock(mNotifyLock);
572 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800573 } else {
574 // There's no listener. But we still want to count the key change
575 // events.
576 size_t nKeys = keyStatusList.size();
577 for (size_t i = 0; i < nKeys; i++) {
578 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
579 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800580 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800581
Jeff Tinkera53d6552017-01-20 00:31:46 -0800582 return Void();
583}
584
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800585Return<void> DrmHal::sendSessionLostState(
586 const hidl_vec<uint8_t>& sessionId) {
587
588 mEventLock.lock();
589 sp<IDrmClient> listener = mListener;
590 mEventLock.unlock();
591
592 if (listener != NULL) {
593 Parcel obj;
594 writeByteArray(obj, sessionId);
595 Mutex::Autolock lock(mNotifyLock);
596 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
597 }
598 return Void();
599}
600
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800601status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
602 const uint8_t uuid[16],
603 const String8 &mimeType,
604 DrmPlugin::SecurityLevel level,
605 bool *isSupported) {
606 *isSupported = false;
607
608 // handle default value cases
609 if (level == DrmPlugin::kSecurityLevelUnknown) {
610 if (mimeType == "") {
611 // isCryptoSchemeSupported(uuid)
612 *isSupported = true;
613 } else {
614 // isCryptoSchemeSupported(uuid, mimeType)
615 *isSupported = factory->isContentTypeSupported(mimeType.string());
616 }
617 return OK;
618 } else if (mimeType == "") {
619 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800620 }
621
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800622 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
623 if (factoryV1_2 == NULL) {
624 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800625 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800626 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
627 mimeType.string(), toHidlSecurityLevel(level));
628 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800629 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800630}
631
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800632status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
633 const String8 &mimeType,
634 DrmPlugin::SecurityLevel level,
635 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800636 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800637 *isSupported = false;
638 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
639 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
640 return matchMimeTypeAndSecurityLevel(mFactories[i],
641 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800642 }
643 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800644 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800645}
646
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800647status_t DrmHal::createPlugin(const uint8_t uuid[16],
648 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800649 Mutex::Autolock autoLock(mLock);
650
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800651 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800652 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800653 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
654 if (plugin != NULL) {
655 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800656 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700657 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800658 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800659 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800660 }
661 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800662
663 if (mPlugin == NULL) {
664 mInitCheck = ERROR_UNSUPPORTED;
665 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800666 mInitCheck = OK;
667 if (mPluginV1_2 != NULL) {
668 if (!mPluginV1_2->setListener(this).isOk()) {
669 mInitCheck = DEAD_OBJECT;
670 }
671 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700672 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800673 }
674 if (mInitCheck != OK) {
675 mPlugin.clear();
676 mPluginV1_1.clear();
677 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700678 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800679 }
680
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800681
Jeff Tinkera53d6552017-01-20 00:31:46 -0800682 return mInitCheck;
683}
684
685status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800686 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800687 return OK;
688}
689
Jeff Tinker41d279a2018-02-11 19:52:08 +0000690status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
691 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800692 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800693 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800694
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800695 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000696 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000697
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800698 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000699 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800700 } else {
701 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
702 return ERROR_DRM_CANNOT_HANDLE;
703 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000704 }
705
706 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800707 bool retry = true;
708 do {
709 hidl_vec<uint8_t> hSessionId;
710
Jeff Tinker41d279a2018-02-11 19:52:08 +0000711 Return<void> hResult;
712 if (mPluginV1_1 == NULL || !setSecurityLevel) {
713 hResult = mPlugin->openSession(
714 [&](Status status,const hidl_vec<uint8_t>& id) {
715 if (status == Status::OK) {
716 sessionId = toVector(id);
717 }
718 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800719 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000720 );
721 } else {
722 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
723 [&](Status status, const hidl_vec<uint8_t>& id) {
724 if (status == Status::OK) {
725 sessionId = toVector(id);
726 }
727 err = toStatusT(status);
728 }
729 );
730 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800731
732 if (!hResult.isOk()) {
733 err = DEAD_OBJECT;
734 }
735
736 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
737 mLock.unlock();
738 // reclaimSession may call back to closeSession, since mLock is
739 // shared between Drm instances, we should unlock here to avoid
740 // deadlock.
741 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
742 mLock.lock();
743 } else {
744 retry = false;
745 }
746 } while (retry);
747
748 if (err == OK) {
749 DrmSessionManager::Instance()->addSession(getCallingPid(),
750 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700751 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800752 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800753 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800754
Adam Stonef0e618d2018-01-17 19:20:41 -0800755 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800756 return err;
757}
758
759status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
760 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800761 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800762
Jeff Tinker319d5f42017-07-26 15:44:33 -0700763 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
764 if (status.isOk()) {
765 if (status == Status::OK) {
766 DrmSessionManager::Instance()->removeSession(sessionId);
767 for (size_t i = 0; i < mOpenSessions.size(); i++) {
768 if (mOpenSessions[i] == sessionId) {
769 mOpenSessions.removeAt(i);
770 break;
771 }
Jeff Tinker61332812017-05-15 16:53:10 -0700772 }
773 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800774 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800775 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800776 mMetrics.mCloseSessionCounter.Increment(response);
777 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800778 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800779 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700780 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800781}
782
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800783static DrmPlugin::KeyRequestType toKeyRequestType(
784 KeyRequestType keyRequestType) {
785 switch (keyRequestType) {
786 case KeyRequestType::INITIAL:
787 return DrmPlugin::kKeyRequestType_Initial;
788 break;
789 case KeyRequestType::RENEWAL:
790 return DrmPlugin::kKeyRequestType_Renewal;
791 break;
792 case KeyRequestType::RELEASE:
793 return DrmPlugin::kKeyRequestType_Release;
794 break;
795 default:
796 return DrmPlugin::kKeyRequestType_Unknown;
797 break;
798 }
799}
800
801static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
802 KeyRequestType_V1_1 keyRequestType) {
803 switch (keyRequestType) {
804 case KeyRequestType_V1_1::NONE:
805 return DrmPlugin::kKeyRequestType_None;
806 break;
807 case KeyRequestType_V1_1::UPDATE:
808 return DrmPlugin::kKeyRequestType_Update;
809 break;
810 default:
811 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
812 break;
813 }
814}
815
Jeff Tinkera53d6552017-01-20 00:31:46 -0800816status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
817 Vector<uint8_t> const &initData, String8 const &mimeType,
818 DrmPlugin::KeyType keyType, KeyedVector<String8,
819 String8> const &optionalParameters, Vector<uint8_t> &request,
820 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
821 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800822 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800823 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800824
825 DrmSessionManager::Instance()->useSession(sessionId);
826
827 KeyType hKeyType;
828 if (keyType == DrmPlugin::kKeyType_Streaming) {
829 hKeyType = KeyType::STREAMING;
830 } else if (keyType == DrmPlugin::kKeyType_Offline) {
831 hKeyType = KeyType::OFFLINE;
832 } else if (keyType == DrmPlugin::kKeyType_Release) {
833 hKeyType = KeyType::RELEASE;
834 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800835 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800836 return BAD_VALUE;
837 }
838
839 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
840
841 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800842 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800843
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800844 if (mPluginV1_2 != NULL) {
845 hResult = mPluginV1_2->getKeyRequest_1_2(
846 toHidlVec(sessionId), toHidlVec(initData),
847 toHidlString(mimeType), hKeyType, hOptionalParameters,
848 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
849 KeyRequestType_V1_1 hKeyRequestType,
850 const hidl_string& hDefaultUrl) {
851 if (status == Status_V1_2::OK) {
852 request = toVector(hRequest);
853 defaultUrl = toString8(hDefaultUrl);
854 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
855 }
856 err = toStatusT_1_2(status);
857 });
858 } else if (mPluginV1_1 != NULL) {
859 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800860 toHidlVec(sessionId), toHidlVec(initData),
861 toHidlString(mimeType), hKeyType, hOptionalParameters,
862 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800863 KeyRequestType_V1_1 hKeyRequestType,
864 const hidl_string& hDefaultUrl) {
865 if (status == Status::OK) {
866 request = toVector(hRequest);
867 defaultUrl = toString8(hDefaultUrl);
868 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800869 }
870 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800871 });
872 } else {
873 hResult = mPlugin->getKeyRequest(
874 toHidlVec(sessionId), toHidlVec(initData),
875 toHidlString(mimeType), hKeyType, hOptionalParameters,
876 [&](Status status, const hidl_vec<uint8_t>& hRequest,
877 KeyRequestType hKeyRequestType,
878 const hidl_string& hDefaultUrl) {
879 if (status == Status::OK) {
880 request = toVector(hRequest);
881 defaultUrl = toString8(hDefaultUrl);
882 *keyRequestType = toKeyRequestType(hKeyRequestType);
883 }
884 err = toStatusT(status);
885 });
886 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800887
Adam Stonef0e618d2018-01-17 19:20:41 -0800888 err = hResult.isOk() ? err : DEAD_OBJECT;
889 keyRequestTimer.SetAttribute(err);
890 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800891}
892
893status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
894 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
895 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800896 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800897
Jeff Tinker6d998b62017-12-18 14:37:43 -0800898 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899
900 DrmSessionManager::Instance()->useSession(sessionId);
901
902 status_t err = UNKNOWN_ERROR;
903
904 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
905 toHidlVec(response),
906 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
907 if (status == Status::OK) {
908 keySetId = toVector(hKeySetId);
909 }
910 err = toStatusT(status);
911 }
912 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800913 err = hResult.isOk() ? err : DEAD_OBJECT;
914 keyResponseTimer.SetAttribute(err);
915 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800916}
917
918status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
919 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800920 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800921
Jeff Tinker58ad4752018-02-16 16:51:59 -0800922 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
923 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800924}
925
926status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
927 Vector<uint8_t> const &keySetId) {
928 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800929 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800930
931 DrmSessionManager::Instance()->useSession(sessionId);
932
Jeff Tinker58ad4752018-02-16 16:51:59 -0800933 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
934 toHidlVec(keySetId));
935 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800936}
937
938status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
939 KeyedVector<String8, String8> &infoMap) const {
940 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800941 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800942
943 DrmSessionManager::Instance()->useSession(sessionId);
944
945 ::KeyedVector hInfoMap;
946
947 status_t err = UNKNOWN_ERROR;
948
949 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
950 [&](Status status, const hidl_vec<KeyValue>& map) {
951 if (status == Status::OK) {
952 infoMap = toKeyedVector(map);
953 }
954 err = toStatusT(status);
955 }
956 );
957
958 return hResult.isOk() ? err : DEAD_OBJECT;
959}
960
961status_t DrmHal::getProvisionRequest(String8 const &certType,
962 String8 const &certAuthority, Vector<uint8_t> &request,
963 String8 &defaultUrl) {
964 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800965 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800966
967 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800968 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800969
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800970 if (mPluginV1_2 != NULL) {
971 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
972 toHidlString(certType), toHidlString(certAuthority),
973 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
974 const hidl_string& hDefaultUrl) {
975 if (status == Status_V1_2::OK) {
976 request = toVector(hRequest);
977 defaultUrl = toString8(hDefaultUrl);
978 }
979 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800980 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800981 );
982 } else {
983 Return<void> hResult = mPlugin->getProvisionRequest(
984 toHidlString(certType), toHidlString(certAuthority),
985 [&](Status status, const hidl_vec<uint8_t>& hRequest,
986 const hidl_string& hDefaultUrl) {
987 if (status == Status::OK) {
988 request = toVector(hRequest);
989 defaultUrl = toString8(hDefaultUrl);
990 }
991 err = toStatusT(status);
992 }
993 );
994 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800995
Adam Stonecea91ce2018-01-22 19:23:28 -0800996 err = hResult.isOk() ? err : DEAD_OBJECT;
997 mMetrics.mGetProvisionRequestCounter.Increment(err);
998 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800999}
1000
1001status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001002 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001003 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001004 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001005
1006 status_t err = UNKNOWN_ERROR;
1007
1008 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1009 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1010 const hidl_vec<uint8_t>& hWrappedKey) {
1011 if (status == Status::OK) {
1012 certificate = toVector(hCertificate);
1013 wrappedKey = toVector(hWrappedKey);
1014 }
1015 err = toStatusT(status);
1016 }
1017 );
1018
Adam Stonecea91ce2018-01-22 19:23:28 -08001019 err = hResult.isOk() ? err : DEAD_OBJECT;
1020 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1021 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001022}
1023
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001024status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001025 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001026 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001027
1028 status_t err = UNKNOWN_ERROR;
1029
1030 Return<void> hResult = mPlugin->getSecureStops(
1031 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1032 if (status == Status::OK) {
1033 secureStops = toSecureStops(hSecureStops);
1034 }
1035 err = toStatusT(status);
1036 }
1037 );
1038
1039 return hResult.isOk() ? err : DEAD_OBJECT;
1040}
1041
1042
Jeff Tinker15177d72018-01-25 12:57:55 -08001043status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1044 Mutex::Autolock autoLock(mLock);
1045
1046 if (mInitCheck != OK) {
1047 return mInitCheck;
1048 }
1049
1050 if (mPluginV1_1 == NULL) {
1051 return ERROR_DRM_CANNOT_HANDLE;
1052 }
1053
1054 status_t err = UNKNOWN_ERROR;
1055
1056 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1057 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1058 if (status == Status::OK) {
1059 secureStopIds = toSecureStopIds(hSecureStopIds);
1060 }
1061 err = toStatusT(status);
1062 }
1063 );
1064
1065 return hResult.isOk() ? err : DEAD_OBJECT;
1066}
1067
1068
Jeff Tinkera53d6552017-01-20 00:31:46 -08001069status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1070 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001071 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001072
1073 status_t err = UNKNOWN_ERROR;
1074
1075 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1076 [&](Status status, const SecureStop& hSecureStop) {
1077 if (status == Status::OK) {
1078 secureStop = toVector(hSecureStop.opaqueData);
1079 }
1080 err = toStatusT(status);
1081 }
1082 );
1083
1084 return hResult.isOk() ? err : DEAD_OBJECT;
1085}
1086
1087status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1088 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001089 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001090
Jeff Tinker58ad4752018-02-16 16:51:59 -08001091 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001092 if (mPluginV1_1 != NULL) {
1093 SecureStopRelease secureStopRelease;
1094 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001095 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1096 } else {
1097 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001098 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001099 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001100}
1101
Jeff Tinker15177d72018-01-25 12:57:55 -08001102status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1103 Mutex::Autolock autoLock(mLock);
1104
1105 if (mInitCheck != OK) {
1106 return mInitCheck;
1107 }
1108
1109 if (mPluginV1_1 == NULL) {
1110 return ERROR_DRM_CANNOT_HANDLE;
1111 }
1112
Jeff Tinker58ad4752018-02-16 16:51:59 -08001113 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1114 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001115}
1116
1117status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001118 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001119 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001120
Jeff Tinker58ad4752018-02-16 16:51:59 -08001121 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001122 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001123 status = mPluginV1_1->removeAllSecureStops();
1124 } else {
1125 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001126 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001127 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001128}
1129
Jeff Tinker6d998b62017-12-18 14:37:43 -08001130status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1131 DrmPlugin::HdcpLevel *max) const {
1132 Mutex::Autolock autoLock(mLock);
1133 INIT_CHECK();
1134
1135 if (connected == NULL || max == NULL) {
1136 return BAD_VALUE;
1137 }
1138 status_t err = UNKNOWN_ERROR;
1139
Jeff Tinker6d998b62017-12-18 14:37:43 -08001140 *connected = DrmPlugin::kHdcpLevelUnknown;
1141 *max = DrmPlugin::kHdcpLevelUnknown;
1142
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001143 Return<void> hResult;
1144 if (mPluginV1_2 != NULL) {
1145 hResult = mPluginV1_2->getHdcpLevels_1_2(
1146 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1147 if (status == Status_V1_2::OK) {
1148 *connected = toHdcpLevel(hConnected);
1149 *max = toHdcpLevel(hMax);
1150 }
1151 err = toStatusT_1_2(status);
1152 });
1153 } else if (mPluginV1_1 != NULL) {
1154 hResult = mPluginV1_1->getHdcpLevels(
1155 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1156 if (status == Status::OK) {
1157 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1158 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1159 }
1160 err = toStatusT(status);
1161 });
1162 } else {
1163 return ERROR_DRM_CANNOT_HANDLE;
1164 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001165
1166 return hResult.isOk() ? err : DEAD_OBJECT;
1167}
1168
1169status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1170 Mutex::Autolock autoLock(mLock);
1171 INIT_CHECK();
1172
1173 if (open == NULL || max == NULL) {
1174 return BAD_VALUE;
1175 }
1176 status_t err = UNKNOWN_ERROR;
1177
1178 *open = 0;
1179 *max = 0;
1180
1181 if (mPluginV1_1 == NULL) {
1182 return ERROR_DRM_CANNOT_HANDLE;
1183 }
1184
1185 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1186 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1187 if (status == Status::OK) {
1188 *open = hOpen;
1189 *max = hMax;
1190 }
1191 err = toStatusT(status);
1192 }
1193 );
1194
1195 return hResult.isOk() ? err : DEAD_OBJECT;
1196}
1197
1198status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1199 DrmPlugin::SecurityLevel *level) const {
1200 Mutex::Autolock autoLock(mLock);
1201 INIT_CHECK();
1202
1203 if (level == NULL) {
1204 return BAD_VALUE;
1205 }
1206 status_t err = UNKNOWN_ERROR;
1207
1208 if (mPluginV1_1 == NULL) {
1209 return ERROR_DRM_CANNOT_HANDLE;
1210 }
1211
1212 *level = DrmPlugin::kSecurityLevelUnknown;
1213
1214 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1215 [&](Status status, SecurityLevel hLevel) {
1216 if (status == Status::OK) {
1217 *level = toSecurityLevel(hLevel);
1218 }
1219 err = toStatusT(status);
1220 }
1221 );
1222
1223 return hResult.isOk() ? err : DEAD_OBJECT;
1224}
1225
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001226status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1227 Mutex::Autolock autoLock(mLock);
1228
1229 if (mInitCheck != OK) {
1230 return mInitCheck;
1231 }
1232
1233 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001234 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001235 }
1236
1237 status_t err = UNKNOWN_ERROR;
1238
1239 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1240 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1241 if (status == Status::OK) {
1242 keySetIds = toKeySetIds(hKeySetIds);
1243 }
1244 err = toStatusT(status);
1245 }
1246 );
1247
1248 return hResult.isOk() ? err : DEAD_OBJECT;
1249}
1250
1251status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1252 Mutex::Autolock autoLock(mLock);
1253
1254 if (mInitCheck != OK) {
1255 return mInitCheck;
1256 }
1257
1258 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001259 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001260 }
1261
1262 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1263 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1264}
1265
1266status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1267 DrmPlugin::OfflineLicenseState *licenseState) const {
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 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1278
1279 status_t err = UNKNOWN_ERROR;
1280
1281 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1282 [&](Status status, OfflineLicenseState hLicenseState) {
1283 if (status == Status::OK) {
1284 *licenseState = toOfflineLicenseState(hLicenseState);
1285 }
1286 err = toStatusT(status);
1287 }
1288 );
1289
1290 return hResult.isOk() ? err : DEAD_OBJECT;
1291}
1292
Jeff Tinkera53d6552017-01-20 00:31:46 -08001293status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1294 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001295 return getPropertyStringInternal(name, value);
1296}
1297
1298status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1299 // This function is internal to the class and should only be called while
1300 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001301 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001302
1303 status_t err = UNKNOWN_ERROR;
1304
1305 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1306 [&](Status status, const hidl_string& hValue) {
1307 if (status == Status::OK) {
1308 value = toString8(hValue);
1309 }
1310 err = toStatusT(status);
1311 }
1312 );
1313
1314 return hResult.isOk() ? err : DEAD_OBJECT;
1315}
1316
1317status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1318 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001319 return getPropertyByteArrayInternal(name, value);
1320}
1321
1322status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1323 // This function is internal to the class and should only be called while
1324 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001325 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001326
1327 status_t err = UNKNOWN_ERROR;
1328
1329 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1330 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1331 if (status == Status::OK) {
1332 value = toVector(hValue);
1333 }
1334 err = toStatusT(status);
1335 }
1336 );
1337
Adam Stonecea91ce2018-01-22 19:23:28 -08001338 err = hResult.isOk() ? err : DEAD_OBJECT;
1339 if (name == kPropertyDeviceUniqueId) {
1340 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1341 }
1342 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001343}
1344
1345status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1346 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001347 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001348
Jeff Tinker58ad4752018-02-16 16:51:59 -08001349 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001350 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001351 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001352}
1353
1354status_t DrmHal::setPropertyByteArray(String8 const &name,
1355 Vector<uint8_t> const &value ) const {
1356 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001357 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001358
Jeff Tinker58ad4752018-02-16 16:51:59 -08001359 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001360 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001361 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001362}
1363
Adam Stone28f27c32018-02-05 15:07:48 -08001364status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1365 if (metrics == nullptr) {
1366 return UNEXPECTED_NULL;
1367 }
1368 mMetrics.Export(metrics);
1369
1370 // Append vendor metrics if they are supported.
1371 if (mPluginV1_1 != NULL) {
1372 String8 vendor;
1373 String8 description;
1374 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1375 || vendor.isEmpty()) {
1376 ALOGE("Get vendor failed or is empty");
1377 vendor = "NONE";
1378 }
1379 if (getPropertyStringInternal(String8("description"), description) != OK
1380 || description.isEmpty()) {
1381 ALOGE("Get description failed or is empty.");
1382 description = "NONE";
1383 }
1384 vendor += ".";
1385 vendor += description;
1386
1387 hidl_vec<DrmMetricGroup> pluginMetrics;
1388 status_t err = UNKNOWN_ERROR;
1389
1390 Return<void> status = mPluginV1_1->getMetrics(
1391 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1392 if (status != Status::OK) {
1393 ALOGV("Error getting plugin metrics: %d", status);
1394 } else {
1395 PersistableBundle pluginBundle;
1396 if (MediaDrmMetrics::HidlMetricsToBundle(
1397 pluginMetrics, &pluginBundle) == OK) {
1398 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1399 }
1400 }
1401 err = toStatusT(status);
1402 });
1403 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001404 }
1405
Adam Stoneab394d12017-12-22 12:34:20 -08001406 return OK;
1407}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001408
1409status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1410 String8 const &algorithm) {
1411 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001412 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001413
1414 DrmSessionManager::Instance()->useSession(sessionId);
1415
Jeff Tinkere6412942018-04-30 17:35:16 -07001416 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001417 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001418 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001419}
1420
1421status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1422 String8 const &algorithm) {
1423 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001424 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001425
1426 DrmSessionManager::Instance()->useSession(sessionId);
1427
Jeff Tinkere6412942018-04-30 17:35:16 -07001428 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001429 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001430 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001431}
1432
1433status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001434 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1435 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001436 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001437 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001438
1439 DrmSessionManager::Instance()->useSession(sessionId);
1440
1441 status_t err = UNKNOWN_ERROR;
1442
1443 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1444 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1445 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1446 if (status == Status::OK) {
1447 output = toVector(hOutput);
1448 }
1449 err = toStatusT(status);
1450 }
1451 );
1452
1453 return hResult.isOk() ? err : DEAD_OBJECT;
1454}
1455
1456status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001457 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1458 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001459 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001460 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001461
1462 DrmSessionManager::Instance()->useSession(sessionId);
1463
1464 status_t err = UNKNOWN_ERROR;
1465
1466 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1467 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1468 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1469 if (status == Status::OK) {
1470 output = toVector(hOutput);
1471 }
1472 err = toStatusT(status);
1473 }
1474 );
1475
1476 return hResult.isOk() ? err : DEAD_OBJECT;
1477}
1478
1479status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001480 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1481 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001482 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001483 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001484
1485 DrmSessionManager::Instance()->useSession(sessionId);
1486
1487 status_t err = UNKNOWN_ERROR;
1488
1489 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1490 toHidlVec(keyId), toHidlVec(message),
1491 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1492 if (status == Status::OK) {
1493 signature = toVector(hSignature);
1494 }
1495 err = toStatusT(status);
1496 }
1497 );
1498
1499 return hResult.isOk() ? err : DEAD_OBJECT;
1500}
1501
1502status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001503 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1504 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001505 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001506 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001507
1508 DrmSessionManager::Instance()->useSession(sessionId);
1509
1510 status_t err = UNKNOWN_ERROR;
1511
1512 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1513 toHidlVec(message), toHidlVec(signature),
1514 [&](Status status, bool hMatch) {
1515 if (status == Status::OK) {
1516 match = hMatch;
1517 } else {
1518 match = false;
1519 }
1520 err = toStatusT(status);
1521 }
1522 );
1523
1524 return hResult.isOk() ? err : DEAD_OBJECT;
1525}
1526
1527status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001528 String8 const &algorithm, Vector<uint8_t> const &message,
1529 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001530 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001531 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001532
1533 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1534 return -EPERM;
1535 }
1536
1537 DrmSessionManager::Instance()->useSession(sessionId);
1538
1539 status_t err = UNKNOWN_ERROR;
1540
1541 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1542 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1543 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1544 if (status == Status::OK) {
1545 signature = toVector(hSignature);
1546 }
1547 err = toStatusT(status);
1548 }
1549 );
1550
1551 return hResult.isOk() ? err : DEAD_OBJECT;
1552}
1553
1554void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1555{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001556 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001557}
1558
1559void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1560{
1561 if (vec.size()) {
1562 obj.writeInt32(vec.size());
1563 obj.write(vec.data(), vec.size());
1564 } else {
1565 obj.writeInt32(0);
1566 }
1567}
1568
Adam Stonefb679e32018-02-07 10:25:48 -08001569void DrmHal::reportFrameworkMetrics() const
1570{
Ray Essick6a305222019-01-28 20:33:18 -08001571 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1572 item->generateSessionID();
1573 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001574 String8 vendor;
1575 String8 description;
1576 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1577 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001578 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001579 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001580 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001581 }
1582 result = getPropertyStringInternal(String8("description"), description);
1583 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001584 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001585 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001586 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001587 }
Adam Stoneab394d12017-12-22 12:34:20 -08001588
Adam Stonefb679e32018-02-07 10:25:48 -08001589 std::string serializedMetrics;
1590 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1591 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001592 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001593 }
Adam Stone32494f52018-02-26 22:53:27 -08001594 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1595 serializedMetrics.size());
1596 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001597 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001598 }
Ray Essick6a305222019-01-28 20:33:18 -08001599 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001600 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001601 }
1602}
1603
1604void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001605{
Adam Stone32494f52018-02-26 22:53:27 -08001606 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001607 String8 vendor;
1608 String8 description;
1609 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1610 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001611 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1612 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1613 metricsVector.size());
1614 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1615 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001616 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001617 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001618 }
1619 }
1620}
1621
Jeff Tinkera53d6552017-01-20 00:31:46 -08001622} // namespace android