blob: e79fd4bf5ef0958bbef7b8a15c22a4771fe22366 [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>
Jeff Tinkera53d6552017-01-20 00:31:46 -080029
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
Jeff Tinker6d998b62017-12-18 14:37:43 -080042using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080043using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080044using drm::V1_0::KeyType;
45using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080047using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070049using drm::V1_1::HdcpLevel;
50using drm::V1_1::SecureStopRelease;
51using drm::V1_1::SecurityLevel;
52using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070053using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080054using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080055using ::android::hardware::hidl_array;
56using ::android::hardware::hidl_string;
57using ::android::hardware::hidl_vec;
58using ::android::hardware::Return;
59using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080060using ::android::hidl::manager::V1_0::IServiceManager;
Adam Stone637b7852018-01-30 12:09:36 -080061using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080062using ::android::sp;
63
Jeff Tinkerb8684f32018-12-12 08:41:31 -080064typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
65typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080066typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080067
Adam Stonecea91ce2018-01-22 19:23:28 -080068namespace {
69
70// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
71// in the MediaDrm API.
72constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080073constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080074
Adam Stone32494f52018-02-26 22:53:27 -080075template<typename T>
76std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070077 // Note that the base 64 conversion only works with arrays of single-byte
78 // values. If the source is empty or is not an array of single-byte values,
79 // return empty string.
80 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080081 return "";
82 }
Adam Stone32494f52018-02-26 22:53:27 -080083
84 android::AString outputString;
85 encodeBase64(data, size, &outputString);
86 // Remove trailing equals padding if it exists.
87 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
88 outputString.erase(outputString.size() - 1, 1);
89 }
90
91 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080092}
93
Adam Stone32494f52018-02-26 22:53:27 -080094} // anonymous namespace
95
Jeff Tinkera53d6552017-01-20 00:31:46 -080096namespace android {
97
Jeff Tinker6d998b62017-12-18 14:37:43 -080098#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
99
Jeff Tinkera53d6552017-01-20 00:31:46 -0800100static inline int getCallingPid() {
101 return IPCThreadState::self()->getCallingPid();
102}
103
104static bool checkPermission(const char* permissionString) {
105 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
106 bool ok = checkCallingPermission(String16(permissionString));
107 if (!ok) ALOGE("Request requires %s", permissionString);
108 return ok;
109}
110
111static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
112 Vector<uint8_t> vector;
113 vector.appendArray(vec.data(), vec.size());
114 return *const_cast<const Vector<uint8_t> *>(&vector);
115}
116
117static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
118 hidl_vec<uint8_t> vec;
119 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
120 return vec;
121}
122
123static String8 toString8(const hidl_string &string) {
124 return String8(string.c_str());
125}
126
127static hidl_string toHidlString(const String8& string) {
128 return hidl_string(string.string());
129}
130
Jeff Tinker6d998b62017-12-18 14:37:43 -0800131static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
132 switch(level) {
133 case SecurityLevel::SW_SECURE_CRYPTO:
134 return DrmPlugin::kSecurityLevelSwSecureCrypto;
135 case SecurityLevel::SW_SECURE_DECODE:
136 return DrmPlugin::kSecurityLevelSwSecureDecode;
137 case SecurityLevel::HW_SECURE_CRYPTO:
138 return DrmPlugin::kSecurityLevelHwSecureCrypto;
139 case SecurityLevel::HW_SECURE_DECODE:
140 return DrmPlugin::kSecurityLevelHwSecureDecode;
141 case SecurityLevel::HW_SECURE_ALL:
142 return DrmPlugin::kSecurityLevelHwSecureAll;
143 default:
144 return DrmPlugin::kSecurityLevelUnknown;
145 }
146}
147
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800148static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
149 switch(level) {
150 case DrmPlugin::kSecurityLevelSwSecureCrypto:
151 return SecurityLevel::SW_SECURE_CRYPTO;
152 case DrmPlugin::kSecurityLevelSwSecureDecode:
153 return SecurityLevel::SW_SECURE_DECODE;
154 case DrmPlugin::kSecurityLevelHwSecureCrypto:
155 return SecurityLevel::HW_SECURE_CRYPTO;
156 case DrmPlugin::kSecurityLevelHwSecureDecode:
157 return SecurityLevel::HW_SECURE_DECODE;
158 case DrmPlugin::kSecurityLevelHwSecureAll:
159 return SecurityLevel::HW_SECURE_ALL;
160 default:
161 return SecurityLevel::UNKNOWN;
162 }
163}
164
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700165static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
166 OfflineLicenseState licenseState) {
167 switch(licenseState) {
168 case OfflineLicenseState::USABLE:
169 return DrmPlugin::kOfflineLicenseStateUsable;
170 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800171 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700172 default:
173 return DrmPlugin::kOfflineLicenseStateUnknown;
174 }
175}
176
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800177static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800178 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800179 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800180 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800181 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800182 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800183 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800184 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800185 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800186 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800187 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800188 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800189 case HdcpLevel_V1_2::HDCP_V2_3:
190 return DrmPlugin::kHdcpV2_3;
191 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800192 return DrmPlugin::kHdcpNoOutput;
193 default:
194 return DrmPlugin::kHdcpLevelUnknown;
195 }
196}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800197static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
198 keyedVector) {
199 std::vector<KeyValue> stdKeyedVector;
200 for (size_t i = 0; i < keyedVector.size(); i++) {
201 KeyValue keyValue;
202 keyValue.key = toHidlString(keyedVector.keyAt(i));
203 keyValue.value = toHidlString(keyedVector.valueAt(i));
204 stdKeyedVector.push_back(keyValue);
205 }
206 return ::KeyedVector(stdKeyedVector);
207}
208
209static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
210 hKeyedVector) {
211 KeyedVector<String8, String8> keyedVector;
212 for (size_t i = 0; i < hKeyedVector.size(); i++) {
213 keyedVector.add(toString8(hKeyedVector[i].key),
214 toString8(hKeyedVector[i].value));
215 }
216 return keyedVector;
217}
218
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800219static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800220 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800221 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800222 for (size_t i = 0; i < hSecureStops.size(); i++) {
223 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
224 }
225 return secureStops;
226}
227
Jeff Tinker15177d72018-01-25 12:57:55 -0800228static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
229 hSecureStopIds) {
230 List<Vector<uint8_t>> secureStopIds;
231 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
232 secureStopIds.push_back(toVector(hSecureStopIds[i]));
233 }
234 return secureStopIds;
235}
236
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700237static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
238 hKeySetIds) {
239 List<Vector<uint8_t>> keySetIds;
240 for (size_t i = 0; i < hKeySetIds.size(); i++) {
241 keySetIds.push_back(toVector(hKeySetIds[i]));
242 }
243 return keySetIds;
244}
245
Jeff Tinkera53d6552017-01-20 00:31:46 -0800246static status_t toStatusT(Status status) {
247 switch (status) {
248 case Status::OK:
249 return OK;
250 break;
251 case Status::ERROR_DRM_NO_LICENSE:
252 return ERROR_DRM_NO_LICENSE;
253 break;
254 case Status::ERROR_DRM_LICENSE_EXPIRED:
255 return ERROR_DRM_LICENSE_EXPIRED;
256 break;
257 case Status::ERROR_DRM_SESSION_NOT_OPENED:
258 return ERROR_DRM_SESSION_NOT_OPENED;
259 break;
260 case Status::ERROR_DRM_CANNOT_HANDLE:
261 return ERROR_DRM_CANNOT_HANDLE;
262 break;
263 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800264 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800265 break;
266 case Status::BAD_VALUE:
267 return BAD_VALUE;
268 break;
269 case Status::ERROR_DRM_NOT_PROVISIONED:
270 return ERROR_DRM_NOT_PROVISIONED;
271 break;
272 case Status::ERROR_DRM_RESOURCE_BUSY:
273 return ERROR_DRM_RESOURCE_BUSY;
274 break;
275 case Status::ERROR_DRM_DEVICE_REVOKED:
276 return ERROR_DRM_DEVICE_REVOKED;
277 break;
278 case Status::ERROR_DRM_UNKNOWN:
279 default:
280 return ERROR_DRM_UNKNOWN;
281 break;
282 }
283}
284
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800285static status_t toStatusT_1_2(Status_V1_2 status) {
286 switch (status) {
287 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
288 return ERROR_DRM_RESOURCE_CONTENTION;
289 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
290 return ERROR_DRM_FRAME_TOO_LARGE;
291 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
292 return ERROR_DRM_INSUFFICIENT_SECURITY;
293 default:
294 return toStatusT(static_cast<Status>(status));
295 }
296}
297
Jeff Tinkera53d6552017-01-20 00:31:46 -0800298
299Mutex DrmHal::mLock;
300
301struct DrmSessionClient : public DrmSessionClientInterface {
302 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
303
304 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
305 sp<DrmHal> drm = mDrm.promote();
306 if (drm == NULL) {
307 return true;
308 }
309 status_t err = drm->closeSession(sessionId);
310 if (err != OK) {
311 return false;
312 }
313 drm->sendEvent(EventType::SESSION_RECLAIMED,
314 toHidlVec(sessionId), hidl_vec<uint8_t>());
315 return true;
316 }
317
318protected:
319 virtual ~DrmSessionClient() {}
320
321private:
322 wp<DrmHal> mDrm;
323
324 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
325};
326
327DrmHal::DrmHal()
328 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800329 mFactories(makeDrmFactories()),
330 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800331}
332
Jeff Tinker61332812017-05-15 16:53:10 -0700333void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800334 Mutex::Autolock autoLock(mLock);
335 auto openSessions = mOpenSessions;
336 for (size_t i = 0; i < openSessions.size(); i++) {
337 mLock.unlock();
338 closeSession(openSessions[i]);
339 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700340 }
341 mOpenSessions.clear();
342}
343
Jeff Tinkera53d6552017-01-20 00:31:46 -0800344DrmHal::~DrmHal() {
345 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
346}
347
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800348void DrmHal::cleanup() {
349 closeOpenSessions();
350
351 Mutex::Autolock autoLock(mLock);
352 reportPluginMetrics();
353 reportFrameworkMetrics();
354
355 setListener(NULL);
356 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800357 if (mPluginV1_2 != NULL) {
358 if (!mPluginV1_2->setListener(NULL).isOk()) {
359 mInitCheck = DEAD_OBJECT;
360 }
361 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800362 if (!mPlugin->setListener(NULL).isOk()) {
363 mInitCheck = DEAD_OBJECT;
364 }
365 }
366 mPlugin.clear();
367 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700368 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800369}
370
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800371Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
372 Vector<sp<IDrmFactory>> factories;
373
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800374 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800375
376 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800377 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800378 [&factories](const hidl_vec<hidl_string> &registered) {
379 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000380 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800381 if (factory != NULL) {
382 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000383 }
384 }
385 }
386 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800387 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000388 [&factories](const hidl_vec<hidl_string> &registered) {
389 for (const auto &instance : registered) {
390 auto factory = drm::V1_1::IDrmFactory::getService(instance);
391 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000392 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800393 }
394 }
395 }
396 );
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700397 manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
398 [&factories](const hidl_vec<hidl_string> &registered) {
399 for (const auto &instance : registered) {
400 auto factory = drm::V1_2::IDrmFactory::getService(instance);
401 if (factory != NULL) {
402 factories.push_back(factory);
403 }
404 }
405 }
406 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800407 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800408
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800409 if (factories.size() == 0) {
410 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700411 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800412 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000413 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800414 factories.push_back(passthrough);
415 } else {
416 ALOGE("Failed to find any drm factories");
417 }
418 }
419 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800420}
421
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800422sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
423 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800424 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800425 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800426
427 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800428 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800429 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800430 if (status != Status::OK) {
431 ALOGE("Failed to make drm plugin");
432 return;
433 }
434 plugin = hPlugin;
435 }
436 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700437
438 if (!hResult.isOk()) {
439 ALOGE("createPlugin remote call failed");
440 }
441
Jeff Tinkera53d6552017-01-20 00:31:46 -0800442 return plugin;
443}
444
445status_t DrmHal::initCheck() const {
446 return mInitCheck;
447}
448
449status_t DrmHal::setListener(const sp<IDrmClient>& listener)
450{
451 Mutex::Autolock lock(mEventLock);
452 if (mListener != NULL){
453 IInterface::asBinder(mListener)->unlinkToDeath(this);
454 }
455 if (listener != NULL) {
456 IInterface::asBinder(listener)->linkToDeath(this);
457 }
458 mListener = listener;
459 return NO_ERROR;
460}
461
462Return<void> DrmHal::sendEvent(EventType hEventType,
463 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800464 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800465
466 mEventLock.lock();
467 sp<IDrmClient> listener = mListener;
468 mEventLock.unlock();
469
470 if (listener != NULL) {
471 Parcel obj;
472 writeByteArray(obj, sessionId);
473 writeByteArray(obj, data);
474
475 Mutex::Autolock lock(mNotifyLock);
476 DrmPlugin::EventType eventType;
477 switch(hEventType) {
478 case EventType::PROVISION_REQUIRED:
479 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
480 break;
481 case EventType::KEY_NEEDED:
482 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
483 break;
484 case EventType::KEY_EXPIRED:
485 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
486 break;
487 case EventType::VENDOR_DEFINED:
488 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
489 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700490 case EventType::SESSION_RECLAIMED:
491 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
492 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800493 default:
494 return Void();
495 }
496 listener->notify(eventType, 0, &obj);
497 }
498 return Void();
499}
500
501Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
502 int64_t expiryTimeInMS) {
503
504 mEventLock.lock();
505 sp<IDrmClient> listener = mListener;
506 mEventLock.unlock();
507
508 if (listener != NULL) {
509 Parcel obj;
510 writeByteArray(obj, sessionId);
511 obj.writeInt64(expiryTimeInMS);
512
513 Mutex::Autolock lock(mNotifyLock);
514 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
515 }
516 return Void();
517}
518
519Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700520 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
521 std::vector<KeyStatus> keyStatusVec;
522 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
523 keyStatusVec.push_back({keyStatus_V1_0.keyId,
524 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
525 }
526 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
527 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
528}
529
530Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Jeff Tinkera53d6552017-01-20 00:31:46 -0800531 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
532
533 mEventLock.lock();
534 sp<IDrmClient> listener = mListener;
535 mEventLock.unlock();
536
537 if (listener != NULL) {
538 Parcel obj;
539 writeByteArray(obj, sessionId);
540
541 size_t nKeys = keyStatusList.size();
542 obj.writeInt32(nKeys);
543 for (size_t i = 0; i < nKeys; ++i) {
544 const KeyStatus &keyStatus = keyStatusList[i];
545 writeByteArray(obj, keyStatus.keyId);
546 uint32_t type;
547 switch(keyStatus.type) {
548 case KeyStatusType::USABLE:
549 type = DrmPlugin::kKeyStatusType_Usable;
550 break;
551 case KeyStatusType::EXPIRED:
552 type = DrmPlugin::kKeyStatusType_Expired;
553 break;
554 case KeyStatusType::OUTPUTNOTALLOWED:
555 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
556 break;
557 case KeyStatusType::STATUSPENDING:
558 type = DrmPlugin::kKeyStatusType_StatusPending;
559 break;
Robert Shiha5033262019-05-06 14:15:12 -0700560 case KeyStatusType::USABLEINFUTURE:
561 type = DrmPlugin::kKeyStatusType_UsableInFuture;
562 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800563 case KeyStatusType::INTERNALERROR:
564 default:
565 type = DrmPlugin::kKeyStatusType_InternalError;
566 break;
567 }
568 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800569 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800570 }
571 obj.writeInt32(hasNewUsableKey);
572
573 Mutex::Autolock lock(mNotifyLock);
574 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800575 } else {
576 // There's no listener. But we still want to count the key change
577 // events.
578 size_t nKeys = keyStatusList.size();
579 for (size_t i = 0; i < nKeys; i++) {
580 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
581 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800582 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800583
Jeff Tinkera53d6552017-01-20 00:31:46 -0800584 return Void();
585}
586
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800587Return<void> DrmHal::sendSessionLostState(
588 const hidl_vec<uint8_t>& sessionId) {
589
590 mEventLock.lock();
591 sp<IDrmClient> listener = mListener;
592 mEventLock.unlock();
593
594 if (listener != NULL) {
595 Parcel obj;
596 writeByteArray(obj, sessionId);
597 Mutex::Autolock lock(mNotifyLock);
598 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
599 }
600 return Void();
601}
602
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800603status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
604 const uint8_t uuid[16],
605 const String8 &mimeType,
606 DrmPlugin::SecurityLevel level,
607 bool *isSupported) {
608 *isSupported = false;
609
610 // handle default value cases
611 if (level == DrmPlugin::kSecurityLevelUnknown) {
612 if (mimeType == "") {
613 // isCryptoSchemeSupported(uuid)
614 *isSupported = true;
615 } else {
616 // isCryptoSchemeSupported(uuid, mimeType)
617 *isSupported = factory->isContentTypeSupported(mimeType.string());
618 }
619 return OK;
620 } else if (mimeType == "") {
621 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800622 }
623
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800624 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
625 if (factoryV1_2 == NULL) {
626 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800627 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800628 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
629 mimeType.string(), toHidlSecurityLevel(level));
630 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800631 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800632}
633
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800634status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
635 const String8 &mimeType,
636 DrmPlugin::SecurityLevel level,
637 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800638 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800639 *isSupported = false;
640 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
641 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
642 return matchMimeTypeAndSecurityLevel(mFactories[i],
643 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800644 }
645 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800646 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800647}
648
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800649status_t DrmHal::createPlugin(const uint8_t uuid[16],
650 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800651 Mutex::Autolock autoLock(mLock);
652
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800653 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800654 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800655 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
656 if (plugin != NULL) {
657 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800658 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700659 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800660 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800661 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800662 }
663 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664
665 if (mPlugin == NULL) {
666 mInitCheck = ERROR_UNSUPPORTED;
667 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800668 mInitCheck = OK;
669 if (mPluginV1_2 != NULL) {
670 if (!mPluginV1_2->setListener(this).isOk()) {
671 mInitCheck = DEAD_OBJECT;
672 }
673 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700674 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800675 }
676 if (mInitCheck != OK) {
677 mPlugin.clear();
678 mPluginV1_1.clear();
679 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700680 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800681 }
682
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800683
Jeff Tinkera53d6552017-01-20 00:31:46 -0800684 return mInitCheck;
685}
686
687status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800688 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800689 return OK;
690}
691
Jeff Tinker41d279a2018-02-11 19:52:08 +0000692status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
693 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800694 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800695 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800696
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800697 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000698 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000699
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800700 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000701 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800702 } else {
703 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
704 return ERROR_DRM_CANNOT_HANDLE;
705 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000706 }
707
708 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800709 bool retry = true;
710 do {
711 hidl_vec<uint8_t> hSessionId;
712
Jeff Tinker41d279a2018-02-11 19:52:08 +0000713 Return<void> hResult;
714 if (mPluginV1_1 == NULL || !setSecurityLevel) {
715 hResult = mPlugin->openSession(
716 [&](Status status,const hidl_vec<uint8_t>& id) {
717 if (status == Status::OK) {
718 sessionId = toVector(id);
719 }
720 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800721 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000722 );
723 } else {
724 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
725 [&](Status status, const hidl_vec<uint8_t>& id) {
726 if (status == Status::OK) {
727 sessionId = toVector(id);
728 }
729 err = toStatusT(status);
730 }
731 );
732 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800733
734 if (!hResult.isOk()) {
735 err = DEAD_OBJECT;
736 }
737
738 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
739 mLock.unlock();
740 // reclaimSession may call back to closeSession, since mLock is
741 // shared between Drm instances, we should unlock here to avoid
742 // deadlock.
743 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
744 mLock.lock();
745 } else {
746 retry = false;
747 }
748 } while (retry);
749
750 if (err == OK) {
751 DrmSessionManager::Instance()->addSession(getCallingPid(),
752 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700753 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800754 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800755 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800756
Adam Stonef0e618d2018-01-17 19:20:41 -0800757 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800758 return err;
759}
760
761status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
762 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800763 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800764
Jeff Tinker319d5f42017-07-26 15:44:33 -0700765 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
766 if (status.isOk()) {
767 if (status == Status::OK) {
768 DrmSessionManager::Instance()->removeSession(sessionId);
769 for (size_t i = 0; i < mOpenSessions.size(); i++) {
770 if (mOpenSessions[i] == sessionId) {
771 mOpenSessions.removeAt(i);
772 break;
773 }
Jeff Tinker61332812017-05-15 16:53:10 -0700774 }
775 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800776 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800777 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800778 mMetrics.mCloseSessionCounter.Increment(response);
779 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800780 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800781 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700782 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800783}
784
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800785static DrmPlugin::KeyRequestType toKeyRequestType(
786 KeyRequestType keyRequestType) {
787 switch (keyRequestType) {
788 case KeyRequestType::INITIAL:
789 return DrmPlugin::kKeyRequestType_Initial;
790 break;
791 case KeyRequestType::RENEWAL:
792 return DrmPlugin::kKeyRequestType_Renewal;
793 break;
794 case KeyRequestType::RELEASE:
795 return DrmPlugin::kKeyRequestType_Release;
796 break;
797 default:
798 return DrmPlugin::kKeyRequestType_Unknown;
799 break;
800 }
801}
802
803static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
804 KeyRequestType_V1_1 keyRequestType) {
805 switch (keyRequestType) {
806 case KeyRequestType_V1_1::NONE:
807 return DrmPlugin::kKeyRequestType_None;
808 break;
809 case KeyRequestType_V1_1::UPDATE:
810 return DrmPlugin::kKeyRequestType_Update;
811 break;
812 default:
813 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
814 break;
815 }
816}
817
Jeff Tinkera53d6552017-01-20 00:31:46 -0800818status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
819 Vector<uint8_t> const &initData, String8 const &mimeType,
820 DrmPlugin::KeyType keyType, KeyedVector<String8,
821 String8> const &optionalParameters, Vector<uint8_t> &request,
822 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
823 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800824 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800825 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800826
827 DrmSessionManager::Instance()->useSession(sessionId);
828
829 KeyType hKeyType;
830 if (keyType == DrmPlugin::kKeyType_Streaming) {
831 hKeyType = KeyType::STREAMING;
832 } else if (keyType == DrmPlugin::kKeyType_Offline) {
833 hKeyType = KeyType::OFFLINE;
834 } else if (keyType == DrmPlugin::kKeyType_Release) {
835 hKeyType = KeyType::RELEASE;
836 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800837 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800838 return BAD_VALUE;
839 }
840
841 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
842
843 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800844 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800845
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800846 if (mPluginV1_2 != NULL) {
847 hResult = mPluginV1_2->getKeyRequest_1_2(
848 toHidlVec(sessionId), toHidlVec(initData),
849 toHidlString(mimeType), hKeyType, hOptionalParameters,
850 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
851 KeyRequestType_V1_1 hKeyRequestType,
852 const hidl_string& hDefaultUrl) {
853 if (status == Status_V1_2::OK) {
854 request = toVector(hRequest);
855 defaultUrl = toString8(hDefaultUrl);
856 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
857 }
858 err = toStatusT_1_2(status);
859 });
860 } else if (mPluginV1_1 != NULL) {
861 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800862 toHidlVec(sessionId), toHidlVec(initData),
863 toHidlString(mimeType), hKeyType, hOptionalParameters,
864 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800865 KeyRequestType_V1_1 hKeyRequestType,
866 const hidl_string& hDefaultUrl) {
867 if (status == Status::OK) {
868 request = toVector(hRequest);
869 defaultUrl = toString8(hDefaultUrl);
870 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800871 }
872 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800873 });
874 } else {
875 hResult = mPlugin->getKeyRequest(
876 toHidlVec(sessionId), toHidlVec(initData),
877 toHidlString(mimeType), hKeyType, hOptionalParameters,
878 [&](Status status, const hidl_vec<uint8_t>& hRequest,
879 KeyRequestType hKeyRequestType,
880 const hidl_string& hDefaultUrl) {
881 if (status == Status::OK) {
882 request = toVector(hRequest);
883 defaultUrl = toString8(hDefaultUrl);
884 *keyRequestType = toKeyRequestType(hKeyRequestType);
885 }
886 err = toStatusT(status);
887 });
888 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800889
Adam Stonef0e618d2018-01-17 19:20:41 -0800890 err = hResult.isOk() ? err : DEAD_OBJECT;
891 keyRequestTimer.SetAttribute(err);
892 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800893}
894
895status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
896 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
897 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800898 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700899 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800900
901 DrmSessionManager::Instance()->useSession(sessionId);
902
903 status_t err = UNKNOWN_ERROR;
904
905 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
906 toHidlVec(response),
907 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
908 if (status == Status::OK) {
909 keySetId = toVector(hKeySetId);
910 }
911 err = toStatusT(status);
912 }
913 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800914 err = hResult.isOk() ? err : DEAD_OBJECT;
915 keyResponseTimer.SetAttribute(err);
916 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800917}
918
919status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
920 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800921 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800922
Jeff Tinker58ad4752018-02-16 16:51:59 -0800923 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
924 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800925}
926
927status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
928 Vector<uint8_t> const &keySetId) {
929 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800930 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800931
932 DrmSessionManager::Instance()->useSession(sessionId);
933
Jeff Tinker58ad4752018-02-16 16:51:59 -0800934 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
935 toHidlVec(keySetId));
936 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937}
938
939status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
940 KeyedVector<String8, String8> &infoMap) const {
941 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800942 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800943
944 DrmSessionManager::Instance()->useSession(sessionId);
945
946 ::KeyedVector hInfoMap;
947
948 status_t err = UNKNOWN_ERROR;
949
950 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
951 [&](Status status, const hidl_vec<KeyValue>& map) {
952 if (status == Status::OK) {
953 infoMap = toKeyedVector(map);
954 }
955 err = toStatusT(status);
956 }
957 );
958
959 return hResult.isOk() ? err : DEAD_OBJECT;
960}
961
962status_t DrmHal::getProvisionRequest(String8 const &certType,
963 String8 const &certAuthority, Vector<uint8_t> &request,
964 String8 &defaultUrl) {
965 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800966 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800967
968 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800969 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800970
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800971 if (mPluginV1_2 != NULL) {
972 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
973 toHidlString(certType), toHidlString(certAuthority),
974 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
975 const hidl_string& hDefaultUrl) {
976 if (status == Status_V1_2::OK) {
977 request = toVector(hRequest);
978 defaultUrl = toString8(hDefaultUrl);
979 }
980 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800981 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800982 );
983 } else {
984 Return<void> hResult = mPlugin->getProvisionRequest(
985 toHidlString(certType), toHidlString(certAuthority),
986 [&](Status status, const hidl_vec<uint8_t>& hRequest,
987 const hidl_string& hDefaultUrl) {
988 if (status == Status::OK) {
989 request = toVector(hRequest);
990 defaultUrl = toString8(hDefaultUrl);
991 }
992 err = toStatusT(status);
993 }
994 );
995 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800996
Adam Stonecea91ce2018-01-22 19:23:28 -0800997 err = hResult.isOk() ? err : DEAD_OBJECT;
998 mMetrics.mGetProvisionRequestCounter.Increment(err);
999 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001000}
1001
1002status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001003 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001004 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001005 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001006
1007 status_t err = UNKNOWN_ERROR;
1008
1009 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1010 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1011 const hidl_vec<uint8_t>& hWrappedKey) {
1012 if (status == Status::OK) {
1013 certificate = toVector(hCertificate);
1014 wrappedKey = toVector(hWrappedKey);
1015 }
1016 err = toStatusT(status);
1017 }
1018 );
1019
Adam Stonecea91ce2018-01-22 19:23:28 -08001020 err = hResult.isOk() ? err : DEAD_OBJECT;
1021 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1022 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001023}
1024
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001025status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001026 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001027 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001028
1029 status_t err = UNKNOWN_ERROR;
1030
1031 Return<void> hResult = mPlugin->getSecureStops(
1032 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1033 if (status == Status::OK) {
1034 secureStops = toSecureStops(hSecureStops);
1035 }
1036 err = toStatusT(status);
1037 }
1038 );
1039
1040 return hResult.isOk() ? err : DEAD_OBJECT;
1041}
1042
1043
Jeff Tinker15177d72018-01-25 12:57:55 -08001044status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1045 Mutex::Autolock autoLock(mLock);
1046
1047 if (mInitCheck != OK) {
1048 return mInitCheck;
1049 }
1050
1051 if (mPluginV1_1 == NULL) {
1052 return ERROR_DRM_CANNOT_HANDLE;
1053 }
1054
1055 status_t err = UNKNOWN_ERROR;
1056
1057 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1058 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1059 if (status == Status::OK) {
1060 secureStopIds = toSecureStopIds(hSecureStopIds);
1061 }
1062 err = toStatusT(status);
1063 }
1064 );
1065
1066 return hResult.isOk() ? err : DEAD_OBJECT;
1067}
1068
1069
Jeff Tinkera53d6552017-01-20 00:31:46 -08001070status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1071 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001072 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001073
1074 status_t err = UNKNOWN_ERROR;
1075
1076 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1077 [&](Status status, const SecureStop& hSecureStop) {
1078 if (status == Status::OK) {
1079 secureStop = toVector(hSecureStop.opaqueData);
1080 }
1081 err = toStatusT(status);
1082 }
1083 );
1084
1085 return hResult.isOk() ? err : DEAD_OBJECT;
1086}
1087
1088status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1089 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001090 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001091
Jeff Tinker58ad4752018-02-16 16:51:59 -08001092 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001093 if (mPluginV1_1 != NULL) {
1094 SecureStopRelease secureStopRelease;
1095 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001096 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1097 } else {
1098 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001099 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001100 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001101}
1102
Jeff Tinker15177d72018-01-25 12:57:55 -08001103status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1104 Mutex::Autolock autoLock(mLock);
1105
1106 if (mInitCheck != OK) {
1107 return mInitCheck;
1108 }
1109
1110 if (mPluginV1_1 == NULL) {
1111 return ERROR_DRM_CANNOT_HANDLE;
1112 }
1113
Jeff Tinker58ad4752018-02-16 16:51:59 -08001114 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1115 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001116}
1117
1118status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001119 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001120 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001121
Jeff Tinker58ad4752018-02-16 16:51:59 -08001122 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001123 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001124 status = mPluginV1_1->removeAllSecureStops();
1125 } else {
1126 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001127 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001128 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001129}
1130
Jeff Tinker6d998b62017-12-18 14:37:43 -08001131status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1132 DrmPlugin::HdcpLevel *max) const {
1133 Mutex::Autolock autoLock(mLock);
1134 INIT_CHECK();
1135
1136 if (connected == NULL || max == NULL) {
1137 return BAD_VALUE;
1138 }
1139 status_t err = UNKNOWN_ERROR;
1140
Jeff Tinker6d998b62017-12-18 14:37:43 -08001141 *connected = DrmPlugin::kHdcpLevelUnknown;
1142 *max = DrmPlugin::kHdcpLevelUnknown;
1143
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001144 Return<void> hResult;
1145 if (mPluginV1_2 != NULL) {
1146 hResult = mPluginV1_2->getHdcpLevels_1_2(
1147 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1148 if (status == Status_V1_2::OK) {
1149 *connected = toHdcpLevel(hConnected);
1150 *max = toHdcpLevel(hMax);
1151 }
1152 err = toStatusT_1_2(status);
1153 });
1154 } else if (mPluginV1_1 != NULL) {
1155 hResult = mPluginV1_1->getHdcpLevels(
1156 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1157 if (status == Status::OK) {
1158 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1159 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1160 }
1161 err = toStatusT(status);
1162 });
1163 } else {
1164 return ERROR_DRM_CANNOT_HANDLE;
1165 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001166
1167 return hResult.isOk() ? err : DEAD_OBJECT;
1168}
1169
1170status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1171 Mutex::Autolock autoLock(mLock);
1172 INIT_CHECK();
1173
1174 if (open == NULL || max == NULL) {
1175 return BAD_VALUE;
1176 }
1177 status_t err = UNKNOWN_ERROR;
1178
1179 *open = 0;
1180 *max = 0;
1181
1182 if (mPluginV1_1 == NULL) {
1183 return ERROR_DRM_CANNOT_HANDLE;
1184 }
1185
1186 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1187 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1188 if (status == Status::OK) {
1189 *open = hOpen;
1190 *max = hMax;
1191 }
1192 err = toStatusT(status);
1193 }
1194 );
1195
1196 return hResult.isOk() ? err : DEAD_OBJECT;
1197}
1198
1199status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1200 DrmPlugin::SecurityLevel *level) const {
1201 Mutex::Autolock autoLock(mLock);
1202 INIT_CHECK();
1203
1204 if (level == NULL) {
1205 return BAD_VALUE;
1206 }
1207 status_t err = UNKNOWN_ERROR;
1208
1209 if (mPluginV1_1 == NULL) {
1210 return ERROR_DRM_CANNOT_HANDLE;
1211 }
1212
1213 *level = DrmPlugin::kSecurityLevelUnknown;
1214
1215 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1216 [&](Status status, SecurityLevel hLevel) {
1217 if (status == Status::OK) {
1218 *level = toSecurityLevel(hLevel);
1219 }
1220 err = toStatusT(status);
1221 }
1222 );
1223
1224 return hResult.isOk() ? err : DEAD_OBJECT;
1225}
1226
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001227status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1228 Mutex::Autolock autoLock(mLock);
1229
1230 if (mInitCheck != OK) {
1231 return mInitCheck;
1232 }
1233
1234 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001235 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001236 }
1237
1238 status_t err = UNKNOWN_ERROR;
1239
1240 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1241 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1242 if (status == Status::OK) {
1243 keySetIds = toKeySetIds(hKeySetIds);
1244 }
1245 err = toStatusT(status);
1246 }
1247 );
1248
1249 return hResult.isOk() ? err : DEAD_OBJECT;
1250}
1251
1252status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1253 Mutex::Autolock autoLock(mLock);
1254
1255 if (mInitCheck != OK) {
1256 return mInitCheck;
1257 }
1258
1259 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001260 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001261 }
1262
1263 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1264 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1265}
1266
1267status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1268 DrmPlugin::OfflineLicenseState *licenseState) const {
1269 Mutex::Autolock autoLock(mLock);
1270
1271 if (mInitCheck != OK) {
1272 return mInitCheck;
1273 }
1274
1275 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001276 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001277 }
1278 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1279
1280 status_t err = UNKNOWN_ERROR;
1281
1282 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1283 [&](Status status, OfflineLicenseState hLicenseState) {
1284 if (status == Status::OK) {
1285 *licenseState = toOfflineLicenseState(hLicenseState);
1286 }
1287 err = toStatusT(status);
1288 }
1289 );
1290
1291 return hResult.isOk() ? err : DEAD_OBJECT;
1292}
1293
Jeff Tinkera53d6552017-01-20 00:31:46 -08001294status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1295 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001296 return getPropertyStringInternal(name, value);
1297}
1298
1299status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1300 // This function is internal to the class and should only be called while
1301 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001302 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001303
1304 status_t err = UNKNOWN_ERROR;
1305
1306 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1307 [&](Status status, const hidl_string& hValue) {
1308 if (status == Status::OK) {
1309 value = toString8(hValue);
1310 }
1311 err = toStatusT(status);
1312 }
1313 );
1314
1315 return hResult.isOk() ? err : DEAD_OBJECT;
1316}
1317
1318status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1319 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001320 return getPropertyByteArrayInternal(name, value);
1321}
1322
1323status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1324 // This function is internal to the class and should only be called while
1325 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001326 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001327
1328 status_t err = UNKNOWN_ERROR;
1329
1330 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1331 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1332 if (status == Status::OK) {
1333 value = toVector(hValue);
1334 }
1335 err = toStatusT(status);
1336 }
1337 );
1338
Adam Stonecea91ce2018-01-22 19:23:28 -08001339 err = hResult.isOk() ? err : DEAD_OBJECT;
1340 if (name == kPropertyDeviceUniqueId) {
1341 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1342 }
1343 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001344}
1345
1346status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1347 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001348 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001349
Jeff Tinker58ad4752018-02-16 16:51:59 -08001350 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001351 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001352 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001353}
1354
1355status_t DrmHal::setPropertyByteArray(String8 const &name,
1356 Vector<uint8_t> const &value ) const {
1357 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001358 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001359
Jeff Tinker58ad4752018-02-16 16:51:59 -08001360 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001361 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001362 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001363}
1364
Adam Stone28f27c32018-02-05 15:07:48 -08001365status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1366 if (metrics == nullptr) {
1367 return UNEXPECTED_NULL;
1368 }
1369 mMetrics.Export(metrics);
1370
1371 // Append vendor metrics if they are supported.
1372 if (mPluginV1_1 != NULL) {
1373 String8 vendor;
1374 String8 description;
1375 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1376 || vendor.isEmpty()) {
1377 ALOGE("Get vendor failed or is empty");
1378 vendor = "NONE";
1379 }
1380 if (getPropertyStringInternal(String8("description"), description) != OK
1381 || description.isEmpty()) {
1382 ALOGE("Get description failed or is empty.");
1383 description = "NONE";
1384 }
1385 vendor += ".";
1386 vendor += description;
1387
1388 hidl_vec<DrmMetricGroup> pluginMetrics;
1389 status_t err = UNKNOWN_ERROR;
1390
1391 Return<void> status = mPluginV1_1->getMetrics(
1392 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1393 if (status != Status::OK) {
1394 ALOGV("Error getting plugin metrics: %d", status);
1395 } else {
1396 PersistableBundle pluginBundle;
1397 if (MediaDrmMetrics::HidlMetricsToBundle(
1398 pluginMetrics, &pluginBundle) == OK) {
1399 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1400 }
1401 }
1402 err = toStatusT(status);
1403 });
1404 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001405 }
1406
Adam Stoneab394d12017-12-22 12:34:20 -08001407 return OK;
1408}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001409
1410status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1411 String8 const &algorithm) {
1412 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001413 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001414
1415 DrmSessionManager::Instance()->useSession(sessionId);
1416
Jeff Tinkere6412942018-04-30 17:35:16 -07001417 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001418 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001419 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001420}
1421
1422status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1423 String8 const &algorithm) {
1424 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001425 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001426
1427 DrmSessionManager::Instance()->useSession(sessionId);
1428
Jeff Tinkere6412942018-04-30 17:35:16 -07001429 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001430 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001431 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001432}
1433
1434status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001435 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1436 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001437 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001438 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001439
1440 DrmSessionManager::Instance()->useSession(sessionId);
1441
1442 status_t err = UNKNOWN_ERROR;
1443
1444 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1445 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1446 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1447 if (status == Status::OK) {
1448 output = toVector(hOutput);
1449 }
1450 err = toStatusT(status);
1451 }
1452 );
1453
1454 return hResult.isOk() ? err : DEAD_OBJECT;
1455}
1456
1457status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001458 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1459 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001460 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001461 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001462
1463 DrmSessionManager::Instance()->useSession(sessionId);
1464
1465 status_t err = UNKNOWN_ERROR;
1466
1467 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1468 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1469 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1470 if (status == Status::OK) {
1471 output = toVector(hOutput);
1472 }
1473 err = toStatusT(status);
1474 }
1475 );
1476
1477 return hResult.isOk() ? err : DEAD_OBJECT;
1478}
1479
1480status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001481 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1482 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001483 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001484 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001485
1486 DrmSessionManager::Instance()->useSession(sessionId);
1487
1488 status_t err = UNKNOWN_ERROR;
1489
1490 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1491 toHidlVec(keyId), toHidlVec(message),
1492 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1493 if (status == Status::OK) {
1494 signature = toVector(hSignature);
1495 }
1496 err = toStatusT(status);
1497 }
1498 );
1499
1500 return hResult.isOk() ? err : DEAD_OBJECT;
1501}
1502
1503status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001504 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1505 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001506 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001507 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001508
1509 DrmSessionManager::Instance()->useSession(sessionId);
1510
1511 status_t err = UNKNOWN_ERROR;
1512
1513 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1514 toHidlVec(message), toHidlVec(signature),
1515 [&](Status status, bool hMatch) {
1516 if (status == Status::OK) {
1517 match = hMatch;
1518 } else {
1519 match = false;
1520 }
1521 err = toStatusT(status);
1522 }
1523 );
1524
1525 return hResult.isOk() ? err : DEAD_OBJECT;
1526}
1527
1528status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001529 String8 const &algorithm, Vector<uint8_t> const &message,
1530 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001531 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001532 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001533
1534 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1535 return -EPERM;
1536 }
1537
1538 DrmSessionManager::Instance()->useSession(sessionId);
1539
1540 status_t err = UNKNOWN_ERROR;
1541
1542 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1543 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1544 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1545 if (status == Status::OK) {
1546 signature = toVector(hSignature);
1547 }
1548 err = toStatusT(status);
1549 }
1550 );
1551
1552 return hResult.isOk() ? err : DEAD_OBJECT;
1553}
1554
1555void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1556{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001557 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001558}
1559
1560void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1561{
1562 if (vec.size()) {
1563 obj.writeInt32(vec.size());
1564 obj.write(vec.data(), vec.size());
1565 } else {
1566 obj.writeInt32(0);
1567 }
1568}
1569
Adam Stonefb679e32018-02-07 10:25:48 -08001570void DrmHal::reportFrameworkMetrics() const
1571{
Ray Essick6a305222019-01-28 20:33:18 -08001572 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1573 item->generateSessionID();
1574 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001575 String8 vendor;
1576 String8 description;
1577 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1578 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001579 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001580 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001581 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001582 }
1583 result = getPropertyStringInternal(String8("description"), description);
1584 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001585 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001586 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001587 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001588 }
Adam Stoneab394d12017-12-22 12:34:20 -08001589
Adam Stonefb679e32018-02-07 10:25:48 -08001590 std::string serializedMetrics;
1591 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1592 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001593 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001594 }
Adam Stone32494f52018-02-26 22:53:27 -08001595 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1596 serializedMetrics.size());
1597 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001598 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001599 }
Ray Essick6a305222019-01-28 20:33:18 -08001600 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001601 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001602 }
1603}
1604
1605void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001606{
Adam Stone32494f52018-02-26 22:53:27 -08001607 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001608 String8 vendor;
1609 String8 description;
1610 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1611 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001612 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1613 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1614 metricsVector.size());
1615 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1616 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001617 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001618 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001619 }
1620 }
1621}
1622
Jeff Tinkera53d6552017-01-20 00:31:46 -08001623} // namespace android