blob: 480c7cda0a8b66a85572a615fe66b6a9e7e1ad18 [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 Tinker6d998b62017-12-18 14:37:43 -080043using drm::V1_0::KeyStatusType;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080044using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080045using drm::V1_0::KeyType;
46using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080048using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080049using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070050using drm::V1_1::HdcpLevel;
51using drm::V1_1::SecureStopRelease;
52using drm::V1_1::SecurityLevel;
53using drm::V1_2::KeySetId;
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:
171 return DrmPlugin::kOfflineLicenseStateInactive;
172 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,
520 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
521
522 mEventLock.lock();
523 sp<IDrmClient> listener = mListener;
524 mEventLock.unlock();
525
526 if (listener != NULL) {
527 Parcel obj;
528 writeByteArray(obj, sessionId);
529
530 size_t nKeys = keyStatusList.size();
531 obj.writeInt32(nKeys);
532 for (size_t i = 0; i < nKeys; ++i) {
533 const KeyStatus &keyStatus = keyStatusList[i];
534 writeByteArray(obj, keyStatus.keyId);
535 uint32_t type;
536 switch(keyStatus.type) {
537 case KeyStatusType::USABLE:
538 type = DrmPlugin::kKeyStatusType_Usable;
539 break;
540 case KeyStatusType::EXPIRED:
541 type = DrmPlugin::kKeyStatusType_Expired;
542 break;
543 case KeyStatusType::OUTPUTNOTALLOWED:
544 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
545 break;
546 case KeyStatusType::STATUSPENDING:
547 type = DrmPlugin::kKeyStatusType_StatusPending;
548 break;
549 case KeyStatusType::INTERNALERROR:
550 default:
551 type = DrmPlugin::kKeyStatusType_InternalError;
552 break;
553 }
554 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800555 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800556 }
557 obj.writeInt32(hasNewUsableKey);
558
559 Mutex::Autolock lock(mNotifyLock);
560 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800561 } else {
562 // There's no listener. But we still want to count the key change
563 // events.
564 size_t nKeys = keyStatusList.size();
565 for (size_t i = 0; i < nKeys; i++) {
566 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
567 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800568 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800569
Jeff Tinkera53d6552017-01-20 00:31:46 -0800570 return Void();
571}
572
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800573Return<void> DrmHal::sendSessionLostState(
574 const hidl_vec<uint8_t>& sessionId) {
575
576 mEventLock.lock();
577 sp<IDrmClient> listener = mListener;
578 mEventLock.unlock();
579
580 if (listener != NULL) {
581 Parcel obj;
582 writeByteArray(obj, sessionId);
583 Mutex::Autolock lock(mNotifyLock);
584 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
585 }
586 return Void();
587}
588
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800589bool DrmHal::matchMimeTypeAndSecurityLevel(sp<IDrmFactory> &factory,
590 const uint8_t uuid[16],
591 const String8 &mimeType,
592 DrmPlugin::SecurityLevel level) {
593 if (mimeType == "") {
594 return true;
595 } else if (!factory->isContentTypeSupported(mimeType.string())) {
596 return false;
597 }
598
599 if (level == DrmPlugin::kSecurityLevelUnknown) {
600 return true;
601 } else {
602 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
603 if (factoryV1_2 == NULL) {
604 return true;
605 } else if (factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
606 mimeType.string(), toHidlSecurityLevel(level))) {
607 return true;
608 }
609 }
610 return false;
611}
612
613bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
614 const String8 &mimeType,
615 DrmPlugin::SecurityLevel level) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800616 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800617
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800618 for (size_t i = 0; i < mFactories.size(); i++) {
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800619 sp<IDrmFactory> factory = mFactories[i];
620 if (factory->isCryptoSchemeSupported(uuid)) {
621 if (matchMimeTypeAndSecurityLevel(factory, uuid, mimeType, level)) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800622 return true;
623 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800624 }
625 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800626 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800627}
628
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800629status_t DrmHal::createPlugin(const uint8_t uuid[16],
630 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800631 Mutex::Autolock autoLock(mLock);
632
Peter Kalauskas7676a402018-12-27 11:04:16 -0800633 for (size_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800634 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800635 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
636 if (plugin != NULL) {
637 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800638 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700639 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800640 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800641 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800642 }
643 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800644
645 if (mPlugin == NULL) {
646 mInitCheck = ERROR_UNSUPPORTED;
647 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800648 mInitCheck = OK;
649 if (mPluginV1_2 != NULL) {
650 if (!mPluginV1_2->setListener(this).isOk()) {
651 mInitCheck = DEAD_OBJECT;
652 }
653 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700654 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800655 }
656 if (mInitCheck != OK) {
657 mPlugin.clear();
658 mPluginV1_1.clear();
659 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700660 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800661 }
662
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800663
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664 return mInitCheck;
665}
666
667status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800668 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800669 return OK;
670}
671
Jeff Tinker41d279a2018-02-11 19:52:08 +0000672status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
673 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800674 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800675 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800676
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800677 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000678 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000679
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800680 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000681 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800682 } else {
683 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
684 return ERROR_DRM_CANNOT_HANDLE;
685 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000686 }
687
688 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800689 bool retry = true;
690 do {
691 hidl_vec<uint8_t> hSessionId;
692
Jeff Tinker41d279a2018-02-11 19:52:08 +0000693 Return<void> hResult;
694 if (mPluginV1_1 == NULL || !setSecurityLevel) {
695 hResult = mPlugin->openSession(
696 [&](Status status,const hidl_vec<uint8_t>& id) {
697 if (status == Status::OK) {
698 sessionId = toVector(id);
699 }
700 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800701 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000702 );
703 } else {
704 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
705 [&](Status status, const hidl_vec<uint8_t>& id) {
706 if (status == Status::OK) {
707 sessionId = toVector(id);
708 }
709 err = toStatusT(status);
710 }
711 );
712 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800713
714 if (!hResult.isOk()) {
715 err = DEAD_OBJECT;
716 }
717
718 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
719 mLock.unlock();
720 // reclaimSession may call back to closeSession, since mLock is
721 // shared between Drm instances, we should unlock here to avoid
722 // deadlock.
723 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
724 mLock.lock();
725 } else {
726 retry = false;
727 }
728 } while (retry);
729
730 if (err == OK) {
731 DrmSessionManager::Instance()->addSession(getCallingPid(),
732 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700733 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800734 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800735 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800736
Adam Stonef0e618d2018-01-17 19:20:41 -0800737 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800738 return err;
739}
740
741status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
742 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800743 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800744
Jeff Tinker319d5f42017-07-26 15:44:33 -0700745 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
746 if (status.isOk()) {
747 if (status == Status::OK) {
748 DrmSessionManager::Instance()->removeSession(sessionId);
749 for (size_t i = 0; i < mOpenSessions.size(); i++) {
750 if (mOpenSessions[i] == sessionId) {
751 mOpenSessions.removeAt(i);
752 break;
753 }
Jeff Tinker61332812017-05-15 16:53:10 -0700754 }
755 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800756 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800757 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800758 mMetrics.mCloseSessionCounter.Increment(response);
759 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800760 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800761 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700762 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800763}
764
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800765static DrmPlugin::KeyRequestType toKeyRequestType(
766 KeyRequestType keyRequestType) {
767 switch (keyRequestType) {
768 case KeyRequestType::INITIAL:
769 return DrmPlugin::kKeyRequestType_Initial;
770 break;
771 case KeyRequestType::RENEWAL:
772 return DrmPlugin::kKeyRequestType_Renewal;
773 break;
774 case KeyRequestType::RELEASE:
775 return DrmPlugin::kKeyRequestType_Release;
776 break;
777 default:
778 return DrmPlugin::kKeyRequestType_Unknown;
779 break;
780 }
781}
782
783static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
784 KeyRequestType_V1_1 keyRequestType) {
785 switch (keyRequestType) {
786 case KeyRequestType_V1_1::NONE:
787 return DrmPlugin::kKeyRequestType_None;
788 break;
789 case KeyRequestType_V1_1::UPDATE:
790 return DrmPlugin::kKeyRequestType_Update;
791 break;
792 default:
793 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
794 break;
795 }
796}
797
Jeff Tinkera53d6552017-01-20 00:31:46 -0800798status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
799 Vector<uint8_t> const &initData, String8 const &mimeType,
800 DrmPlugin::KeyType keyType, KeyedVector<String8,
801 String8> const &optionalParameters, Vector<uint8_t> &request,
802 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
803 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800804 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800805 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800806
807 DrmSessionManager::Instance()->useSession(sessionId);
808
809 KeyType hKeyType;
810 if (keyType == DrmPlugin::kKeyType_Streaming) {
811 hKeyType = KeyType::STREAMING;
812 } else if (keyType == DrmPlugin::kKeyType_Offline) {
813 hKeyType = KeyType::OFFLINE;
814 } else if (keyType == DrmPlugin::kKeyType_Release) {
815 hKeyType = KeyType::RELEASE;
816 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800817 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800818 return BAD_VALUE;
819 }
820
821 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
822
823 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800824 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800825
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800826 if (mPluginV1_2 != NULL) {
827 hResult = mPluginV1_2->getKeyRequest_1_2(
828 toHidlVec(sessionId), toHidlVec(initData),
829 toHidlString(mimeType), hKeyType, hOptionalParameters,
830 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
831 KeyRequestType_V1_1 hKeyRequestType,
832 const hidl_string& hDefaultUrl) {
833 if (status == Status_V1_2::OK) {
834 request = toVector(hRequest);
835 defaultUrl = toString8(hDefaultUrl);
836 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
837 }
838 err = toStatusT_1_2(status);
839 });
840 } else if (mPluginV1_1 != NULL) {
841 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800842 toHidlVec(sessionId), toHidlVec(initData),
843 toHidlString(mimeType), hKeyType, hOptionalParameters,
844 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800845 KeyRequestType_V1_1 hKeyRequestType,
846 const hidl_string& hDefaultUrl) {
847 if (status == Status::OK) {
848 request = toVector(hRequest);
849 defaultUrl = toString8(hDefaultUrl);
850 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800851 }
852 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800853 });
854 } else {
855 hResult = mPlugin->getKeyRequest(
856 toHidlVec(sessionId), toHidlVec(initData),
857 toHidlString(mimeType), hKeyType, hOptionalParameters,
858 [&](Status status, const hidl_vec<uint8_t>& hRequest,
859 KeyRequestType hKeyRequestType,
860 const hidl_string& hDefaultUrl) {
861 if (status == Status::OK) {
862 request = toVector(hRequest);
863 defaultUrl = toString8(hDefaultUrl);
864 *keyRequestType = toKeyRequestType(hKeyRequestType);
865 }
866 err = toStatusT(status);
867 });
868 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800869
Adam Stonef0e618d2018-01-17 19:20:41 -0800870 err = hResult.isOk() ? err : DEAD_OBJECT;
871 keyRequestTimer.SetAttribute(err);
872 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800873}
874
875status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
876 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
877 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800878 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800879
Jeff Tinker6d998b62017-12-18 14:37:43 -0800880 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800881
882 DrmSessionManager::Instance()->useSession(sessionId);
883
884 status_t err = UNKNOWN_ERROR;
885
886 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
887 toHidlVec(response),
888 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
889 if (status == Status::OK) {
890 keySetId = toVector(hKeySetId);
891 }
892 err = toStatusT(status);
893 }
894 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800895 err = hResult.isOk() ? err : DEAD_OBJECT;
896 keyResponseTimer.SetAttribute(err);
897 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800898}
899
900status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
901 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800902 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800903
Jeff Tinker58ad4752018-02-16 16:51:59 -0800904 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
905 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800906}
907
908status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
909 Vector<uint8_t> const &keySetId) {
910 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800911 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800912
913 DrmSessionManager::Instance()->useSession(sessionId);
914
Jeff Tinker58ad4752018-02-16 16:51:59 -0800915 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
916 toHidlVec(keySetId));
917 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800918}
919
920status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
921 KeyedVector<String8, String8> &infoMap) const {
922 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800923 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800924
925 DrmSessionManager::Instance()->useSession(sessionId);
926
927 ::KeyedVector hInfoMap;
928
929 status_t err = UNKNOWN_ERROR;
930
931 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
932 [&](Status status, const hidl_vec<KeyValue>& map) {
933 if (status == Status::OK) {
934 infoMap = toKeyedVector(map);
935 }
936 err = toStatusT(status);
937 }
938 );
939
940 return hResult.isOk() ? err : DEAD_OBJECT;
941}
942
943status_t DrmHal::getProvisionRequest(String8 const &certType,
944 String8 const &certAuthority, Vector<uint8_t> &request,
945 String8 &defaultUrl) {
946 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800947 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800948
949 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800950 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800951
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800952 if (mPluginV1_2 != NULL) {
953 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
954 toHidlString(certType), toHidlString(certAuthority),
955 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
956 const hidl_string& hDefaultUrl) {
957 if (status == Status_V1_2::OK) {
958 request = toVector(hRequest);
959 defaultUrl = toString8(hDefaultUrl);
960 }
961 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800962 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800963 );
964 } else {
965 Return<void> hResult = mPlugin->getProvisionRequest(
966 toHidlString(certType), toHidlString(certAuthority),
967 [&](Status status, const hidl_vec<uint8_t>& hRequest,
968 const hidl_string& hDefaultUrl) {
969 if (status == Status::OK) {
970 request = toVector(hRequest);
971 defaultUrl = toString8(hDefaultUrl);
972 }
973 err = toStatusT(status);
974 }
975 );
976 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800977
Adam Stonecea91ce2018-01-22 19:23:28 -0800978 err = hResult.isOk() ? err : DEAD_OBJECT;
979 mMetrics.mGetProvisionRequestCounter.Increment(err);
980 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800981}
982
983status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800984 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800985 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800986 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800987
988 status_t err = UNKNOWN_ERROR;
989
990 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
991 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
992 const hidl_vec<uint8_t>& hWrappedKey) {
993 if (status == Status::OK) {
994 certificate = toVector(hCertificate);
995 wrappedKey = toVector(hWrappedKey);
996 }
997 err = toStatusT(status);
998 }
999 );
1000
Adam Stonecea91ce2018-01-22 19:23:28 -08001001 err = hResult.isOk() ? err : DEAD_OBJECT;
1002 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1003 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001004}
1005
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001006status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001007 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001008 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001009
1010 status_t err = UNKNOWN_ERROR;
1011
1012 Return<void> hResult = mPlugin->getSecureStops(
1013 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1014 if (status == Status::OK) {
1015 secureStops = toSecureStops(hSecureStops);
1016 }
1017 err = toStatusT(status);
1018 }
1019 );
1020
1021 return hResult.isOk() ? err : DEAD_OBJECT;
1022}
1023
1024
Jeff Tinker15177d72018-01-25 12:57:55 -08001025status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1026 Mutex::Autolock autoLock(mLock);
1027
1028 if (mInitCheck != OK) {
1029 return mInitCheck;
1030 }
1031
1032 if (mPluginV1_1 == NULL) {
1033 return ERROR_DRM_CANNOT_HANDLE;
1034 }
1035
1036 status_t err = UNKNOWN_ERROR;
1037
1038 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1039 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1040 if (status == Status::OK) {
1041 secureStopIds = toSecureStopIds(hSecureStopIds);
1042 }
1043 err = toStatusT(status);
1044 }
1045 );
1046
1047 return hResult.isOk() ? err : DEAD_OBJECT;
1048}
1049
1050
Jeff Tinkera53d6552017-01-20 00:31:46 -08001051status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1052 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001053 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001054
1055 status_t err = UNKNOWN_ERROR;
1056
1057 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1058 [&](Status status, const SecureStop& hSecureStop) {
1059 if (status == Status::OK) {
1060 secureStop = toVector(hSecureStop.opaqueData);
1061 }
1062 err = toStatusT(status);
1063 }
1064 );
1065
1066 return hResult.isOk() ? err : DEAD_OBJECT;
1067}
1068
1069status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1070 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001071 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001072
Jeff Tinker58ad4752018-02-16 16:51:59 -08001073 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001074 if (mPluginV1_1 != NULL) {
1075 SecureStopRelease secureStopRelease;
1076 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001077 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1078 } else {
1079 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001080 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001081 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001082}
1083
Jeff Tinker15177d72018-01-25 12:57:55 -08001084status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1085 Mutex::Autolock autoLock(mLock);
1086
1087 if (mInitCheck != OK) {
1088 return mInitCheck;
1089 }
1090
1091 if (mPluginV1_1 == NULL) {
1092 return ERROR_DRM_CANNOT_HANDLE;
1093 }
1094
Jeff Tinker58ad4752018-02-16 16:51:59 -08001095 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1096 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001097}
1098
1099status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001100 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001101 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001102
Jeff Tinker58ad4752018-02-16 16:51:59 -08001103 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001104 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001105 status = mPluginV1_1->removeAllSecureStops();
1106 } else {
1107 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001108 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001109 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001110}
1111
Jeff Tinker6d998b62017-12-18 14:37:43 -08001112status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1113 DrmPlugin::HdcpLevel *max) const {
1114 Mutex::Autolock autoLock(mLock);
1115 INIT_CHECK();
1116
1117 if (connected == NULL || max == NULL) {
1118 return BAD_VALUE;
1119 }
1120 status_t err = UNKNOWN_ERROR;
1121
Jeff Tinker6d998b62017-12-18 14:37:43 -08001122 *connected = DrmPlugin::kHdcpLevelUnknown;
1123 *max = DrmPlugin::kHdcpLevelUnknown;
1124
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001125 Return<void> hResult;
1126 if (mPluginV1_2 != NULL) {
1127 hResult = mPluginV1_2->getHdcpLevels_1_2(
1128 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1129 if (status == Status_V1_2::OK) {
1130 *connected = toHdcpLevel(hConnected);
1131 *max = toHdcpLevel(hMax);
1132 }
1133 err = toStatusT_1_2(status);
1134 });
1135 } else if (mPluginV1_1 != NULL) {
1136 hResult = mPluginV1_1->getHdcpLevels(
1137 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1138 if (status == Status::OK) {
1139 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1140 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1141 }
1142 err = toStatusT(status);
1143 });
1144 } else {
1145 return ERROR_DRM_CANNOT_HANDLE;
1146 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001147
1148 return hResult.isOk() ? err : DEAD_OBJECT;
1149}
1150
1151status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1152 Mutex::Autolock autoLock(mLock);
1153 INIT_CHECK();
1154
1155 if (open == NULL || max == NULL) {
1156 return BAD_VALUE;
1157 }
1158 status_t err = UNKNOWN_ERROR;
1159
1160 *open = 0;
1161 *max = 0;
1162
1163 if (mPluginV1_1 == NULL) {
1164 return ERROR_DRM_CANNOT_HANDLE;
1165 }
1166
1167 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1168 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1169 if (status == Status::OK) {
1170 *open = hOpen;
1171 *max = hMax;
1172 }
1173 err = toStatusT(status);
1174 }
1175 );
1176
1177 return hResult.isOk() ? err : DEAD_OBJECT;
1178}
1179
1180status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1181 DrmPlugin::SecurityLevel *level) const {
1182 Mutex::Autolock autoLock(mLock);
1183 INIT_CHECK();
1184
1185 if (level == NULL) {
1186 return BAD_VALUE;
1187 }
1188 status_t err = UNKNOWN_ERROR;
1189
1190 if (mPluginV1_1 == NULL) {
1191 return ERROR_DRM_CANNOT_HANDLE;
1192 }
1193
1194 *level = DrmPlugin::kSecurityLevelUnknown;
1195
1196 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1197 [&](Status status, SecurityLevel hLevel) {
1198 if (status == Status::OK) {
1199 *level = toSecurityLevel(hLevel);
1200 }
1201 err = toStatusT(status);
1202 }
1203 );
1204
1205 return hResult.isOk() ? err : DEAD_OBJECT;
1206}
1207
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001208status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1209 Mutex::Autolock autoLock(mLock);
1210
1211 if (mInitCheck != OK) {
1212 return mInitCheck;
1213 }
1214
1215 if (mPluginV1_2 == NULL) {
1216 return ERROR_DRM_CANNOT_HANDLE;
1217 }
1218
1219 status_t err = UNKNOWN_ERROR;
1220
1221 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1222 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1223 if (status == Status::OK) {
1224 keySetIds = toKeySetIds(hKeySetIds);
1225 }
1226 err = toStatusT(status);
1227 }
1228 );
1229
1230 return hResult.isOk() ? err : DEAD_OBJECT;
1231}
1232
1233status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1234 Mutex::Autolock autoLock(mLock);
1235
1236 if (mInitCheck != OK) {
1237 return mInitCheck;
1238 }
1239
1240 if (mPluginV1_2 == NULL) {
1241 return ERROR_DRM_CANNOT_HANDLE;
1242 }
1243
1244 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1245 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1246}
1247
1248status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1249 DrmPlugin::OfflineLicenseState *licenseState) const {
1250 Mutex::Autolock autoLock(mLock);
1251
1252 if (mInitCheck != OK) {
1253 return mInitCheck;
1254 }
1255
1256 if (mPluginV1_2 == NULL) {
1257 return ERROR_DRM_CANNOT_HANDLE;
1258 }
1259 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1260
1261 status_t err = UNKNOWN_ERROR;
1262
1263 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1264 [&](Status status, OfflineLicenseState hLicenseState) {
1265 if (status == Status::OK) {
1266 *licenseState = toOfflineLicenseState(hLicenseState);
1267 }
1268 err = toStatusT(status);
1269 }
1270 );
1271
1272 return hResult.isOk() ? err : DEAD_OBJECT;
1273}
1274
Jeff Tinkera53d6552017-01-20 00:31:46 -08001275status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1276 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001277 return getPropertyStringInternal(name, value);
1278}
1279
1280status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1281 // This function is internal to the class and should only be called while
1282 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001283 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001284
1285 status_t err = UNKNOWN_ERROR;
1286
1287 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1288 [&](Status status, const hidl_string& hValue) {
1289 if (status == Status::OK) {
1290 value = toString8(hValue);
1291 }
1292 err = toStatusT(status);
1293 }
1294 );
1295
1296 return hResult.isOk() ? err : DEAD_OBJECT;
1297}
1298
1299status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1300 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001301 return getPropertyByteArrayInternal(name, value);
1302}
1303
1304status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1305 // This function is internal to the class and should only be called while
1306 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001307 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001308
1309 status_t err = UNKNOWN_ERROR;
1310
1311 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1312 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1313 if (status == Status::OK) {
1314 value = toVector(hValue);
1315 }
1316 err = toStatusT(status);
1317 }
1318 );
1319
Adam Stonecea91ce2018-01-22 19:23:28 -08001320 err = hResult.isOk() ? err : DEAD_OBJECT;
1321 if (name == kPropertyDeviceUniqueId) {
1322 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1323 }
1324 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001325}
1326
1327status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1328 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001329 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001330
Jeff Tinker58ad4752018-02-16 16:51:59 -08001331 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001332 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001333 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001334}
1335
1336status_t DrmHal::setPropertyByteArray(String8 const &name,
1337 Vector<uint8_t> const &value ) const {
1338 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001339 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001340
Jeff Tinker58ad4752018-02-16 16:51:59 -08001341 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001342 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001343 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001344}
1345
Adam Stone28f27c32018-02-05 15:07:48 -08001346status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1347 if (metrics == nullptr) {
1348 return UNEXPECTED_NULL;
1349 }
1350 mMetrics.Export(metrics);
1351
1352 // Append vendor metrics if they are supported.
1353 if (mPluginV1_1 != NULL) {
1354 String8 vendor;
1355 String8 description;
1356 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1357 || vendor.isEmpty()) {
1358 ALOGE("Get vendor failed or is empty");
1359 vendor = "NONE";
1360 }
1361 if (getPropertyStringInternal(String8("description"), description) != OK
1362 || description.isEmpty()) {
1363 ALOGE("Get description failed or is empty.");
1364 description = "NONE";
1365 }
1366 vendor += ".";
1367 vendor += description;
1368
1369 hidl_vec<DrmMetricGroup> pluginMetrics;
1370 status_t err = UNKNOWN_ERROR;
1371
1372 Return<void> status = mPluginV1_1->getMetrics(
1373 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1374 if (status != Status::OK) {
1375 ALOGV("Error getting plugin metrics: %d", status);
1376 } else {
1377 PersistableBundle pluginBundle;
1378 if (MediaDrmMetrics::HidlMetricsToBundle(
1379 pluginMetrics, &pluginBundle) == OK) {
1380 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1381 }
1382 }
1383 err = toStatusT(status);
1384 });
1385 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001386 }
1387
Adam Stoneab394d12017-12-22 12:34:20 -08001388 return OK;
1389}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001390
1391status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1392 String8 const &algorithm) {
1393 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001394 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001395
1396 DrmSessionManager::Instance()->useSession(sessionId);
1397
Jeff Tinkere6412942018-04-30 17:35:16 -07001398 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001399 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001400 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001401}
1402
1403status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1404 String8 const &algorithm) {
1405 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001406 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001407
1408 DrmSessionManager::Instance()->useSession(sessionId);
1409
Jeff Tinkere6412942018-04-30 17:35:16 -07001410 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001411 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001412 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001413}
1414
1415status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001416 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1417 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001418 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001419 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001420
1421 DrmSessionManager::Instance()->useSession(sessionId);
1422
1423 status_t err = UNKNOWN_ERROR;
1424
1425 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1426 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1427 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1428 if (status == Status::OK) {
1429 output = toVector(hOutput);
1430 }
1431 err = toStatusT(status);
1432 }
1433 );
1434
1435 return hResult.isOk() ? err : DEAD_OBJECT;
1436}
1437
1438status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001439 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1440 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001441 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001442 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001443
1444 DrmSessionManager::Instance()->useSession(sessionId);
1445
1446 status_t err = UNKNOWN_ERROR;
1447
1448 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1449 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1450 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1451 if (status == Status::OK) {
1452 output = toVector(hOutput);
1453 }
1454 err = toStatusT(status);
1455 }
1456 );
1457
1458 return hResult.isOk() ? err : DEAD_OBJECT;
1459}
1460
1461status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001462 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1463 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001464 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001465 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001466
1467 DrmSessionManager::Instance()->useSession(sessionId);
1468
1469 status_t err = UNKNOWN_ERROR;
1470
1471 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1472 toHidlVec(keyId), toHidlVec(message),
1473 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1474 if (status == Status::OK) {
1475 signature = toVector(hSignature);
1476 }
1477 err = toStatusT(status);
1478 }
1479 );
1480
1481 return hResult.isOk() ? err : DEAD_OBJECT;
1482}
1483
1484status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001485 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1486 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001487 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001488 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001489
1490 DrmSessionManager::Instance()->useSession(sessionId);
1491
1492 status_t err = UNKNOWN_ERROR;
1493
1494 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1495 toHidlVec(message), toHidlVec(signature),
1496 [&](Status status, bool hMatch) {
1497 if (status == Status::OK) {
1498 match = hMatch;
1499 } else {
1500 match = false;
1501 }
1502 err = toStatusT(status);
1503 }
1504 );
1505
1506 return hResult.isOk() ? err : DEAD_OBJECT;
1507}
1508
1509status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001510 String8 const &algorithm, Vector<uint8_t> const &message,
1511 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001512 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001513 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001514
1515 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1516 return -EPERM;
1517 }
1518
1519 DrmSessionManager::Instance()->useSession(sessionId);
1520
1521 status_t err = UNKNOWN_ERROR;
1522
1523 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1524 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1525 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1526 if (status == Status::OK) {
1527 signature = toVector(hSignature);
1528 }
1529 err = toStatusT(status);
1530 }
1531 );
1532
1533 return hResult.isOk() ? err : DEAD_OBJECT;
1534}
1535
1536void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1537{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001538 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001539}
1540
1541void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1542{
1543 if (vec.size()) {
1544 obj.writeInt32(vec.size());
1545 obj.write(vec.data(), vec.size());
1546 } else {
1547 obj.writeInt32(0);
1548 }
1549}
1550
Adam Stonefb679e32018-02-07 10:25:48 -08001551void DrmHal::reportFrameworkMetrics() const
1552{
1553 MediaAnalyticsItem item("mediadrm");
1554 item.generateSessionID();
1555 item.setPkgName(mMetrics.GetAppPackageName().c_str());
1556 String8 vendor;
1557 String8 description;
1558 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1559 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001560 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001561 } else {
1562 item.setCString("vendor", vendor.c_str());
1563 }
1564 result = getPropertyStringInternal(String8("description"), description);
1565 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001566 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001567 } else {
1568 item.setCString("description", description.c_str());
1569 }
Adam Stoneab394d12017-12-22 12:34:20 -08001570
Adam Stonefb679e32018-02-07 10:25:48 -08001571 std::string serializedMetrics;
1572 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1573 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001574 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001575 }
Adam Stone32494f52018-02-26 22:53:27 -08001576 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1577 serializedMetrics.size());
1578 if (!b64EncodedMetrics.empty()) {
1579 item.setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001580 }
1581 if (!item.selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001582 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001583 }
1584}
1585
1586void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001587{
Adam Stone32494f52018-02-26 22:53:27 -08001588 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001589 String8 vendor;
1590 String8 description;
1591 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1592 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001593 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1594 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1595 metricsVector.size());
1596 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1597 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001598 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001599 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001600 }
1601 }
1602}
1603
Jeff Tinkera53d6552017-01-20 00:31:46 -08001604} // namespace android