blob: 2d4b3d8e69f33098c1b46c026e52412df698fdce [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>
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080027#include <android/hidl/manager/1.0/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 Tinkerc8baaba2018-10-23 11:32:36 -0700148static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
149 OfflineLicenseState licenseState) {
150 switch(licenseState) {
151 case OfflineLicenseState::USABLE:
152 return DrmPlugin::kOfflineLicenseStateUsable;
153 case OfflineLicenseState::INACTIVE:
154 return DrmPlugin::kOfflineLicenseStateInactive;
155 default:
156 return DrmPlugin::kOfflineLicenseStateUnknown;
157 }
158}
159
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800160static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800161 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800162 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800163 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800164 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800165 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800166 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800167 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800168 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800169 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800170 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800171 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800172 case HdcpLevel_V1_2::HDCP_V2_3:
173 return DrmPlugin::kHdcpV2_3;
174 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800175 return DrmPlugin::kHdcpNoOutput;
176 default:
177 return DrmPlugin::kHdcpLevelUnknown;
178 }
179}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800180static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
181 keyedVector) {
182 std::vector<KeyValue> stdKeyedVector;
183 for (size_t i = 0; i < keyedVector.size(); i++) {
184 KeyValue keyValue;
185 keyValue.key = toHidlString(keyedVector.keyAt(i));
186 keyValue.value = toHidlString(keyedVector.valueAt(i));
187 stdKeyedVector.push_back(keyValue);
188 }
189 return ::KeyedVector(stdKeyedVector);
190}
191
192static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
193 hKeyedVector) {
194 KeyedVector<String8, String8> keyedVector;
195 for (size_t i = 0; i < hKeyedVector.size(); i++) {
196 keyedVector.add(toString8(hKeyedVector[i].key),
197 toString8(hKeyedVector[i].value));
198 }
199 return keyedVector;
200}
201
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800202static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800203 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800204 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800205 for (size_t i = 0; i < hSecureStops.size(); i++) {
206 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
207 }
208 return secureStops;
209}
210
Jeff Tinker15177d72018-01-25 12:57:55 -0800211static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
212 hSecureStopIds) {
213 List<Vector<uint8_t>> secureStopIds;
214 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
215 secureStopIds.push_back(toVector(hSecureStopIds[i]));
216 }
217 return secureStopIds;
218}
219
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700220static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
221 hKeySetIds) {
222 List<Vector<uint8_t>> keySetIds;
223 for (size_t i = 0; i < hKeySetIds.size(); i++) {
224 keySetIds.push_back(toVector(hKeySetIds[i]));
225 }
226 return keySetIds;
227}
228
Jeff Tinkera53d6552017-01-20 00:31:46 -0800229static status_t toStatusT(Status status) {
230 switch (status) {
231 case Status::OK:
232 return OK;
233 break;
234 case Status::ERROR_DRM_NO_LICENSE:
235 return ERROR_DRM_NO_LICENSE;
236 break;
237 case Status::ERROR_DRM_LICENSE_EXPIRED:
238 return ERROR_DRM_LICENSE_EXPIRED;
239 break;
240 case Status::ERROR_DRM_SESSION_NOT_OPENED:
241 return ERROR_DRM_SESSION_NOT_OPENED;
242 break;
243 case Status::ERROR_DRM_CANNOT_HANDLE:
244 return ERROR_DRM_CANNOT_HANDLE;
245 break;
246 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800247 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800248 break;
249 case Status::BAD_VALUE:
250 return BAD_VALUE;
251 break;
252 case Status::ERROR_DRM_NOT_PROVISIONED:
253 return ERROR_DRM_NOT_PROVISIONED;
254 break;
255 case Status::ERROR_DRM_RESOURCE_BUSY:
256 return ERROR_DRM_RESOURCE_BUSY;
257 break;
258 case Status::ERROR_DRM_DEVICE_REVOKED:
259 return ERROR_DRM_DEVICE_REVOKED;
260 break;
261 case Status::ERROR_DRM_UNKNOWN:
262 default:
263 return ERROR_DRM_UNKNOWN;
264 break;
265 }
266}
267
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800268static status_t toStatusT_1_2(Status_V1_2 status) {
269 switch (status) {
270 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
271 return ERROR_DRM_RESOURCE_CONTENTION;
272 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
273 return ERROR_DRM_FRAME_TOO_LARGE;
274 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
275 return ERROR_DRM_INSUFFICIENT_SECURITY;
276 default:
277 return toStatusT(static_cast<Status>(status));
278 }
279}
280
Jeff Tinkera53d6552017-01-20 00:31:46 -0800281
282Mutex DrmHal::mLock;
283
284struct DrmSessionClient : public DrmSessionClientInterface {
285 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
286
287 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
288 sp<DrmHal> drm = mDrm.promote();
289 if (drm == NULL) {
290 return true;
291 }
292 status_t err = drm->closeSession(sessionId);
293 if (err != OK) {
294 return false;
295 }
296 drm->sendEvent(EventType::SESSION_RECLAIMED,
297 toHidlVec(sessionId), hidl_vec<uint8_t>());
298 return true;
299 }
300
301protected:
302 virtual ~DrmSessionClient() {}
303
304private:
305 wp<DrmHal> mDrm;
306
307 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
308};
309
310DrmHal::DrmHal()
311 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800312 mFactories(makeDrmFactories()),
313 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800314}
315
Jeff Tinker61332812017-05-15 16:53:10 -0700316void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800317 Mutex::Autolock autoLock(mLock);
318 auto openSessions = mOpenSessions;
319 for (size_t i = 0; i < openSessions.size(); i++) {
320 mLock.unlock();
321 closeSession(openSessions[i]);
322 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700323 }
324 mOpenSessions.clear();
325}
326
Jeff Tinkera53d6552017-01-20 00:31:46 -0800327DrmHal::~DrmHal() {
328 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
329}
330
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800331void DrmHal::cleanup() {
332 closeOpenSessions();
333
334 Mutex::Autolock autoLock(mLock);
335 reportPluginMetrics();
336 reportFrameworkMetrics();
337
338 setListener(NULL);
339 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800340 if (mPluginV1_2 != NULL) {
341 if (!mPluginV1_2->setListener(NULL).isOk()) {
342 mInitCheck = DEAD_OBJECT;
343 }
344 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800345 if (!mPlugin->setListener(NULL).isOk()) {
346 mInitCheck = DEAD_OBJECT;
347 }
348 }
349 mPlugin.clear();
350 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700351 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800352}
353
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800354Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
355 Vector<sp<IDrmFactory>> factories;
356
Jeff Tinker593111f2017-05-25 16:00:21 -0700357 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800358
359 if (manager != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000360 manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800361 [&factories](const hidl_vec<hidl_string> &registered) {
362 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000363 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800364 if (factory != NULL) {
365 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000366 }
367 }
368 }
369 );
370 manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
371 [&factories](const hidl_vec<hidl_string> &registered) {
372 for (const auto &instance : registered) {
373 auto factory = drm::V1_1::IDrmFactory::getService(instance);
374 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000375 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800376 }
377 }
378 }
379 );
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700380 manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
381 [&factories](const hidl_vec<hidl_string> &registered) {
382 for (const auto &instance : registered) {
383 auto factory = drm::V1_2::IDrmFactory::getService(instance);
384 if (factory != NULL) {
385 factories.push_back(factory);
386 }
387 }
388 }
389 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800390 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800391
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800392 if (factories.size() == 0) {
393 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700394 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800395 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000396 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800397 factories.push_back(passthrough);
398 } else {
399 ALOGE("Failed to find any drm factories");
400 }
401 }
402 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800403}
404
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800405sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
406 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800407 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800408 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800409
410 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800411 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800412 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800413 if (status != Status::OK) {
414 ALOGE("Failed to make drm plugin");
415 return;
416 }
417 plugin = hPlugin;
418 }
419 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700420
421 if (!hResult.isOk()) {
422 ALOGE("createPlugin remote call failed");
423 }
424
Jeff Tinkera53d6552017-01-20 00:31:46 -0800425 return plugin;
426}
427
428status_t DrmHal::initCheck() const {
429 return mInitCheck;
430}
431
432status_t DrmHal::setListener(const sp<IDrmClient>& listener)
433{
434 Mutex::Autolock lock(mEventLock);
435 if (mListener != NULL){
436 IInterface::asBinder(mListener)->unlinkToDeath(this);
437 }
438 if (listener != NULL) {
439 IInterface::asBinder(listener)->linkToDeath(this);
440 }
441 mListener = listener;
442 return NO_ERROR;
443}
444
445Return<void> DrmHal::sendEvent(EventType hEventType,
446 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800447 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800448
449 mEventLock.lock();
450 sp<IDrmClient> listener = mListener;
451 mEventLock.unlock();
452
453 if (listener != NULL) {
454 Parcel obj;
455 writeByteArray(obj, sessionId);
456 writeByteArray(obj, data);
457
458 Mutex::Autolock lock(mNotifyLock);
459 DrmPlugin::EventType eventType;
460 switch(hEventType) {
461 case EventType::PROVISION_REQUIRED:
462 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
463 break;
464 case EventType::KEY_NEEDED:
465 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
466 break;
467 case EventType::KEY_EXPIRED:
468 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
469 break;
470 case EventType::VENDOR_DEFINED:
471 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
472 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700473 case EventType::SESSION_RECLAIMED:
474 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
475 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800476 default:
477 return Void();
478 }
479 listener->notify(eventType, 0, &obj);
480 }
481 return Void();
482}
483
484Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
485 int64_t expiryTimeInMS) {
486
487 mEventLock.lock();
488 sp<IDrmClient> listener = mListener;
489 mEventLock.unlock();
490
491 if (listener != NULL) {
492 Parcel obj;
493 writeByteArray(obj, sessionId);
494 obj.writeInt64(expiryTimeInMS);
495
496 Mutex::Autolock lock(mNotifyLock);
497 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
498 }
499 return Void();
500}
501
502Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
503 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
504
505 mEventLock.lock();
506 sp<IDrmClient> listener = mListener;
507 mEventLock.unlock();
508
509 if (listener != NULL) {
510 Parcel obj;
511 writeByteArray(obj, sessionId);
512
513 size_t nKeys = keyStatusList.size();
514 obj.writeInt32(nKeys);
515 for (size_t i = 0; i < nKeys; ++i) {
516 const KeyStatus &keyStatus = keyStatusList[i];
517 writeByteArray(obj, keyStatus.keyId);
518 uint32_t type;
519 switch(keyStatus.type) {
520 case KeyStatusType::USABLE:
521 type = DrmPlugin::kKeyStatusType_Usable;
522 break;
523 case KeyStatusType::EXPIRED:
524 type = DrmPlugin::kKeyStatusType_Expired;
525 break;
526 case KeyStatusType::OUTPUTNOTALLOWED:
527 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
528 break;
529 case KeyStatusType::STATUSPENDING:
530 type = DrmPlugin::kKeyStatusType_StatusPending;
531 break;
532 case KeyStatusType::INTERNALERROR:
533 default:
534 type = DrmPlugin::kKeyStatusType_InternalError;
535 break;
536 }
537 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800538 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800539 }
540 obj.writeInt32(hasNewUsableKey);
541
542 Mutex::Autolock lock(mNotifyLock);
543 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800544 } else {
545 // There's no listener. But we still want to count the key change
546 // events.
547 size_t nKeys = keyStatusList.size();
548 for (size_t i = 0; i < nKeys; i++) {
549 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
550 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800551 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800552
Jeff Tinkera53d6552017-01-20 00:31:46 -0800553 return Void();
554}
555
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800556Return<void> DrmHal::sendSessionLostState(
557 const hidl_vec<uint8_t>& sessionId) {
558
559 mEventLock.lock();
560 sp<IDrmClient> listener = mListener;
561 mEventLock.unlock();
562
563 if (listener != NULL) {
564 Parcel obj;
565 writeByteArray(obj, sessionId);
566 Mutex::Autolock lock(mNotifyLock);
567 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
568 }
569 return Void();
570}
571
Jeff Tinkera53d6552017-01-20 00:31:46 -0800572bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
573 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800574
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800575 for (size_t i = 0; i < mFactories.size(); i++) {
576 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
577 if (mimeType != "") {
578 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
579 return true;
580 }
581 } else {
582 return true;
583 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800584 }
585 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800586 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800587}
588
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800589status_t DrmHal::createPlugin(const uint8_t uuid[16],
590 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800591 Mutex::Autolock autoLock(mLock);
592
Peter Kalauskas7676a402018-12-27 11:04:16 -0800593 for (size_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800594 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800595 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
596 if (plugin != NULL) {
597 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800598 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700599 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800600 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800601 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800602 }
603 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800604
605 if (mPlugin == NULL) {
606 mInitCheck = ERROR_UNSUPPORTED;
607 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800608 mInitCheck = OK;
609 if (mPluginV1_2 != NULL) {
610 if (!mPluginV1_2->setListener(this).isOk()) {
611 mInitCheck = DEAD_OBJECT;
612 }
613 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700614 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800615 }
616 if (mInitCheck != OK) {
617 mPlugin.clear();
618 mPluginV1_1.clear();
619 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700620 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800621 }
622
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800623
Jeff Tinkera53d6552017-01-20 00:31:46 -0800624 return mInitCheck;
625}
626
627status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800628 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800629 return OK;
630}
631
Jeff Tinker41d279a2018-02-11 19:52:08 +0000632status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
633 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800634 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800635 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800636
Jeff Tinker41d279a2018-02-11 19:52:08 +0000637 SecurityLevel hSecurityLevel;
638 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000639
Jeff Tinker41d279a2018-02-11 19:52:08 +0000640 switch(level) {
641 case DrmPlugin::kSecurityLevelSwSecureCrypto:
642 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
643 break;
644 case DrmPlugin::kSecurityLevelSwSecureDecode:
645 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
646 break;
647 case DrmPlugin::kSecurityLevelHwSecureCrypto:
648 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
649 break;
650 case DrmPlugin::kSecurityLevelHwSecureDecode:
651 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
652 break;
653 case DrmPlugin::kSecurityLevelHwSecureAll:
654 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
655 break;
656 case DrmPlugin::kSecurityLevelMax:
657 setSecurityLevel = false;
658 break;
659 default:
660 return ERROR_DRM_CANNOT_HANDLE;
661 }
662
663 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664 bool retry = true;
665 do {
666 hidl_vec<uint8_t> hSessionId;
667
Jeff Tinker41d279a2018-02-11 19:52:08 +0000668 Return<void> hResult;
669 if (mPluginV1_1 == NULL || !setSecurityLevel) {
670 hResult = mPlugin->openSession(
671 [&](Status status,const hidl_vec<uint8_t>& id) {
672 if (status == Status::OK) {
673 sessionId = toVector(id);
674 }
675 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800676 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000677 );
678 } else {
679 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
680 [&](Status status, const hidl_vec<uint8_t>& id) {
681 if (status == Status::OK) {
682 sessionId = toVector(id);
683 }
684 err = toStatusT(status);
685 }
686 );
687 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800688
689 if (!hResult.isOk()) {
690 err = DEAD_OBJECT;
691 }
692
693 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
694 mLock.unlock();
695 // reclaimSession may call back to closeSession, since mLock is
696 // shared between Drm instances, we should unlock here to avoid
697 // deadlock.
698 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
699 mLock.lock();
700 } else {
701 retry = false;
702 }
703 } while (retry);
704
705 if (err == OK) {
706 DrmSessionManager::Instance()->addSession(getCallingPid(),
707 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700708 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800709 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800710 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800711
Adam Stonef0e618d2018-01-17 19:20:41 -0800712 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800713 return err;
714}
715
716status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
717 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800718 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800719
Jeff Tinker319d5f42017-07-26 15:44:33 -0700720 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
721 if (status.isOk()) {
722 if (status == Status::OK) {
723 DrmSessionManager::Instance()->removeSession(sessionId);
724 for (size_t i = 0; i < mOpenSessions.size(); i++) {
725 if (mOpenSessions[i] == sessionId) {
726 mOpenSessions.removeAt(i);
727 break;
728 }
Jeff Tinker61332812017-05-15 16:53:10 -0700729 }
730 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800731 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800732 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800733 mMetrics.mCloseSessionCounter.Increment(response);
734 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800735 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800736 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700737 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800738}
739
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800740static DrmPlugin::KeyRequestType toKeyRequestType(
741 KeyRequestType keyRequestType) {
742 switch (keyRequestType) {
743 case KeyRequestType::INITIAL:
744 return DrmPlugin::kKeyRequestType_Initial;
745 break;
746 case KeyRequestType::RENEWAL:
747 return DrmPlugin::kKeyRequestType_Renewal;
748 break;
749 case KeyRequestType::RELEASE:
750 return DrmPlugin::kKeyRequestType_Release;
751 break;
752 default:
753 return DrmPlugin::kKeyRequestType_Unknown;
754 break;
755 }
756}
757
758static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
759 KeyRequestType_V1_1 keyRequestType) {
760 switch (keyRequestType) {
761 case KeyRequestType_V1_1::NONE:
762 return DrmPlugin::kKeyRequestType_None;
763 break;
764 case KeyRequestType_V1_1::UPDATE:
765 return DrmPlugin::kKeyRequestType_Update;
766 break;
767 default:
768 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
769 break;
770 }
771}
772
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
774 Vector<uint8_t> const &initData, String8 const &mimeType,
775 DrmPlugin::KeyType keyType, KeyedVector<String8,
776 String8> const &optionalParameters, Vector<uint8_t> &request,
777 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
778 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800779 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800780 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800781
782 DrmSessionManager::Instance()->useSession(sessionId);
783
784 KeyType hKeyType;
785 if (keyType == DrmPlugin::kKeyType_Streaming) {
786 hKeyType = KeyType::STREAMING;
787 } else if (keyType == DrmPlugin::kKeyType_Offline) {
788 hKeyType = KeyType::OFFLINE;
789 } else if (keyType == DrmPlugin::kKeyType_Release) {
790 hKeyType = KeyType::RELEASE;
791 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800792 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800793 return BAD_VALUE;
794 }
795
796 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
797
798 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800799 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800800
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800801 if (mPluginV1_2 != NULL) {
802 hResult = mPluginV1_2->getKeyRequest_1_2(
803 toHidlVec(sessionId), toHidlVec(initData),
804 toHidlString(mimeType), hKeyType, hOptionalParameters,
805 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
806 KeyRequestType_V1_1 hKeyRequestType,
807 const hidl_string& hDefaultUrl) {
808 if (status == Status_V1_2::OK) {
809 request = toVector(hRequest);
810 defaultUrl = toString8(hDefaultUrl);
811 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
812 }
813 err = toStatusT_1_2(status);
814 });
815 } else if (mPluginV1_1 != NULL) {
816 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800817 toHidlVec(sessionId), toHidlVec(initData),
818 toHidlString(mimeType), hKeyType, hOptionalParameters,
819 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800820 KeyRequestType_V1_1 hKeyRequestType,
821 const hidl_string& hDefaultUrl) {
822 if (status == Status::OK) {
823 request = toVector(hRequest);
824 defaultUrl = toString8(hDefaultUrl);
825 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800826 }
827 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800828 });
829 } else {
830 hResult = mPlugin->getKeyRequest(
831 toHidlVec(sessionId), toHidlVec(initData),
832 toHidlString(mimeType), hKeyType, hOptionalParameters,
833 [&](Status status, const hidl_vec<uint8_t>& hRequest,
834 KeyRequestType hKeyRequestType,
835 const hidl_string& hDefaultUrl) {
836 if (status == Status::OK) {
837 request = toVector(hRequest);
838 defaultUrl = toString8(hDefaultUrl);
839 *keyRequestType = toKeyRequestType(hKeyRequestType);
840 }
841 err = toStatusT(status);
842 });
843 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800844
Adam Stonef0e618d2018-01-17 19:20:41 -0800845 err = hResult.isOk() ? err : DEAD_OBJECT;
846 keyRequestTimer.SetAttribute(err);
847 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800848}
849
850status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
851 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
852 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800853 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800854
Jeff Tinker6d998b62017-12-18 14:37:43 -0800855 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800856
857 DrmSessionManager::Instance()->useSession(sessionId);
858
859 status_t err = UNKNOWN_ERROR;
860
861 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
862 toHidlVec(response),
863 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
864 if (status == Status::OK) {
865 keySetId = toVector(hKeySetId);
866 }
867 err = toStatusT(status);
868 }
869 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800870 err = hResult.isOk() ? err : DEAD_OBJECT;
871 keyResponseTimer.SetAttribute(err);
872 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800873}
874
875status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
876 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800877 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800878
Jeff Tinker58ad4752018-02-16 16:51:59 -0800879 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
880 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800881}
882
883status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
884 Vector<uint8_t> const &keySetId) {
885 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800886 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800887
888 DrmSessionManager::Instance()->useSession(sessionId);
889
Jeff Tinker58ad4752018-02-16 16:51:59 -0800890 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
891 toHidlVec(keySetId));
892 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800893}
894
895status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
896 KeyedVector<String8, String8> &infoMap) const {
897 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800898 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899
900 DrmSessionManager::Instance()->useSession(sessionId);
901
902 ::KeyedVector hInfoMap;
903
904 status_t err = UNKNOWN_ERROR;
905
906 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
907 [&](Status status, const hidl_vec<KeyValue>& map) {
908 if (status == Status::OK) {
909 infoMap = toKeyedVector(map);
910 }
911 err = toStatusT(status);
912 }
913 );
914
915 return hResult.isOk() ? err : DEAD_OBJECT;
916}
917
918status_t DrmHal::getProvisionRequest(String8 const &certType,
919 String8 const &certAuthority, Vector<uint8_t> &request,
920 String8 &defaultUrl) {
921 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800922 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800923
924 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800925 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800926
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800927 if (mPluginV1_2 != NULL) {
928 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
929 toHidlString(certType), toHidlString(certAuthority),
930 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
931 const hidl_string& hDefaultUrl) {
932 if (status == Status_V1_2::OK) {
933 request = toVector(hRequest);
934 defaultUrl = toString8(hDefaultUrl);
935 }
936 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800938 );
939 } else {
940 Return<void> hResult = mPlugin->getProvisionRequest(
941 toHidlString(certType), toHidlString(certAuthority),
942 [&](Status status, const hidl_vec<uint8_t>& hRequest,
943 const hidl_string& hDefaultUrl) {
944 if (status == Status::OK) {
945 request = toVector(hRequest);
946 defaultUrl = toString8(hDefaultUrl);
947 }
948 err = toStatusT(status);
949 }
950 );
951 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800952
Adam Stonecea91ce2018-01-22 19:23:28 -0800953 err = hResult.isOk() ? err : DEAD_OBJECT;
954 mMetrics.mGetProvisionRequestCounter.Increment(err);
955 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800956}
957
958status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800959 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800960 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800961 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800962
963 status_t err = UNKNOWN_ERROR;
964
965 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
966 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
967 const hidl_vec<uint8_t>& hWrappedKey) {
968 if (status == Status::OK) {
969 certificate = toVector(hCertificate);
970 wrappedKey = toVector(hWrappedKey);
971 }
972 err = toStatusT(status);
973 }
974 );
975
Adam Stonecea91ce2018-01-22 19:23:28 -0800976 err = hResult.isOk() ? err : DEAD_OBJECT;
977 mMetrics.mProvideProvisionResponseCounter.Increment(err);
978 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800979}
980
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800981status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800982 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800983 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800984
985 status_t err = UNKNOWN_ERROR;
986
987 Return<void> hResult = mPlugin->getSecureStops(
988 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
989 if (status == Status::OK) {
990 secureStops = toSecureStops(hSecureStops);
991 }
992 err = toStatusT(status);
993 }
994 );
995
996 return hResult.isOk() ? err : DEAD_OBJECT;
997}
998
999
Jeff Tinker15177d72018-01-25 12:57:55 -08001000status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1001 Mutex::Autolock autoLock(mLock);
1002
1003 if (mInitCheck != OK) {
1004 return mInitCheck;
1005 }
1006
1007 if (mPluginV1_1 == NULL) {
1008 return ERROR_DRM_CANNOT_HANDLE;
1009 }
1010
1011 status_t err = UNKNOWN_ERROR;
1012
1013 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1014 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1015 if (status == Status::OK) {
1016 secureStopIds = toSecureStopIds(hSecureStopIds);
1017 }
1018 err = toStatusT(status);
1019 }
1020 );
1021
1022 return hResult.isOk() ? err : DEAD_OBJECT;
1023}
1024
1025
Jeff Tinkera53d6552017-01-20 00:31:46 -08001026status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1027 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001028 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001029
1030 status_t err = UNKNOWN_ERROR;
1031
1032 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1033 [&](Status status, const SecureStop& hSecureStop) {
1034 if (status == Status::OK) {
1035 secureStop = toVector(hSecureStop.opaqueData);
1036 }
1037 err = toStatusT(status);
1038 }
1039 );
1040
1041 return hResult.isOk() ? err : DEAD_OBJECT;
1042}
1043
1044status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1045 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001046 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001047
Jeff Tinker58ad4752018-02-16 16:51:59 -08001048 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001049 if (mPluginV1_1 != NULL) {
1050 SecureStopRelease secureStopRelease;
1051 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001052 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1053 } else {
1054 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001055 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001056 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001057}
1058
Jeff Tinker15177d72018-01-25 12:57:55 -08001059status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1060 Mutex::Autolock autoLock(mLock);
1061
1062 if (mInitCheck != OK) {
1063 return mInitCheck;
1064 }
1065
1066 if (mPluginV1_1 == NULL) {
1067 return ERROR_DRM_CANNOT_HANDLE;
1068 }
1069
Jeff Tinker58ad4752018-02-16 16:51:59 -08001070 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1071 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001072}
1073
1074status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001075 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001076 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001077
Jeff Tinker58ad4752018-02-16 16:51:59 -08001078 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001079 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001080 status = mPluginV1_1->removeAllSecureStops();
1081 } else {
1082 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001083 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001084 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001085}
1086
Jeff Tinker6d998b62017-12-18 14:37:43 -08001087status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1088 DrmPlugin::HdcpLevel *max) const {
1089 Mutex::Autolock autoLock(mLock);
1090 INIT_CHECK();
1091
1092 if (connected == NULL || max == NULL) {
1093 return BAD_VALUE;
1094 }
1095 status_t err = UNKNOWN_ERROR;
1096
Jeff Tinker6d998b62017-12-18 14:37:43 -08001097 *connected = DrmPlugin::kHdcpLevelUnknown;
1098 *max = DrmPlugin::kHdcpLevelUnknown;
1099
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001100 Return<void> hResult;
1101 if (mPluginV1_2 != NULL) {
1102 hResult = mPluginV1_2->getHdcpLevels_1_2(
1103 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1104 if (status == Status_V1_2::OK) {
1105 *connected = toHdcpLevel(hConnected);
1106 *max = toHdcpLevel(hMax);
1107 }
1108 err = toStatusT_1_2(status);
1109 });
1110 } else if (mPluginV1_1 != NULL) {
1111 hResult = mPluginV1_1->getHdcpLevels(
1112 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1113 if (status == Status::OK) {
1114 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1115 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1116 }
1117 err = toStatusT(status);
1118 });
1119 } else {
1120 return ERROR_DRM_CANNOT_HANDLE;
1121 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001122
1123 return hResult.isOk() ? err : DEAD_OBJECT;
1124}
1125
1126status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1127 Mutex::Autolock autoLock(mLock);
1128 INIT_CHECK();
1129
1130 if (open == NULL || max == NULL) {
1131 return BAD_VALUE;
1132 }
1133 status_t err = UNKNOWN_ERROR;
1134
1135 *open = 0;
1136 *max = 0;
1137
1138 if (mPluginV1_1 == NULL) {
1139 return ERROR_DRM_CANNOT_HANDLE;
1140 }
1141
1142 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1143 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1144 if (status == Status::OK) {
1145 *open = hOpen;
1146 *max = hMax;
1147 }
1148 err = toStatusT(status);
1149 }
1150 );
1151
1152 return hResult.isOk() ? err : DEAD_OBJECT;
1153}
1154
1155status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1156 DrmPlugin::SecurityLevel *level) const {
1157 Mutex::Autolock autoLock(mLock);
1158 INIT_CHECK();
1159
1160 if (level == NULL) {
1161 return BAD_VALUE;
1162 }
1163 status_t err = UNKNOWN_ERROR;
1164
1165 if (mPluginV1_1 == NULL) {
1166 return ERROR_DRM_CANNOT_HANDLE;
1167 }
1168
1169 *level = DrmPlugin::kSecurityLevelUnknown;
1170
1171 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1172 [&](Status status, SecurityLevel hLevel) {
1173 if (status == Status::OK) {
1174 *level = toSecurityLevel(hLevel);
1175 }
1176 err = toStatusT(status);
1177 }
1178 );
1179
1180 return hResult.isOk() ? err : DEAD_OBJECT;
1181}
1182
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001183status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1184 Mutex::Autolock autoLock(mLock);
1185
1186 if (mInitCheck != OK) {
1187 return mInitCheck;
1188 }
1189
1190 if (mPluginV1_2 == NULL) {
1191 return ERROR_DRM_CANNOT_HANDLE;
1192 }
1193
1194 status_t err = UNKNOWN_ERROR;
1195
1196 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1197 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1198 if (status == Status::OK) {
1199 keySetIds = toKeySetIds(hKeySetIds);
1200 }
1201 err = toStatusT(status);
1202 }
1203 );
1204
1205 return hResult.isOk() ? err : DEAD_OBJECT;
1206}
1207
1208status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
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 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1220 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1221}
1222
1223status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1224 DrmPlugin::OfflineLicenseState *licenseState) const {
1225 Mutex::Autolock autoLock(mLock);
1226
1227 if (mInitCheck != OK) {
1228 return mInitCheck;
1229 }
1230
1231 if (mPluginV1_2 == NULL) {
1232 return ERROR_DRM_CANNOT_HANDLE;
1233 }
1234 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1235
1236 status_t err = UNKNOWN_ERROR;
1237
1238 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1239 [&](Status status, OfflineLicenseState hLicenseState) {
1240 if (status == Status::OK) {
1241 *licenseState = toOfflineLicenseState(hLicenseState);
1242 }
1243 err = toStatusT(status);
1244 }
1245 );
1246
1247 return hResult.isOk() ? err : DEAD_OBJECT;
1248}
1249
Jeff Tinkera53d6552017-01-20 00:31:46 -08001250status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1251 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001252 return getPropertyStringInternal(name, value);
1253}
1254
1255status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1256 // This function is internal to the class and should only be called while
1257 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001258 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001259
1260 status_t err = UNKNOWN_ERROR;
1261
1262 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1263 [&](Status status, const hidl_string& hValue) {
1264 if (status == Status::OK) {
1265 value = toString8(hValue);
1266 }
1267 err = toStatusT(status);
1268 }
1269 );
1270
1271 return hResult.isOk() ? err : DEAD_OBJECT;
1272}
1273
1274status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1275 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001276 return getPropertyByteArrayInternal(name, value);
1277}
1278
1279status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1280 // This function is internal to the class and should only be called while
1281 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001282 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001283
1284 status_t err = UNKNOWN_ERROR;
1285
1286 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1287 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1288 if (status == Status::OK) {
1289 value = toVector(hValue);
1290 }
1291 err = toStatusT(status);
1292 }
1293 );
1294
Adam Stonecea91ce2018-01-22 19:23:28 -08001295 err = hResult.isOk() ? err : DEAD_OBJECT;
1296 if (name == kPropertyDeviceUniqueId) {
1297 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1298 }
1299 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001300}
1301
1302status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1303 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001304 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001305
Jeff Tinker58ad4752018-02-16 16:51:59 -08001306 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001307 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001308 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001309}
1310
1311status_t DrmHal::setPropertyByteArray(String8 const &name,
1312 Vector<uint8_t> const &value ) const {
1313 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001314 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001315
Jeff Tinker58ad4752018-02-16 16:51:59 -08001316 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001317 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001318 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001319}
1320
Adam Stone28f27c32018-02-05 15:07:48 -08001321status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1322 if (metrics == nullptr) {
1323 return UNEXPECTED_NULL;
1324 }
1325 mMetrics.Export(metrics);
1326
1327 // Append vendor metrics if they are supported.
1328 if (mPluginV1_1 != NULL) {
1329 String8 vendor;
1330 String8 description;
1331 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1332 || vendor.isEmpty()) {
1333 ALOGE("Get vendor failed or is empty");
1334 vendor = "NONE";
1335 }
1336 if (getPropertyStringInternal(String8("description"), description) != OK
1337 || description.isEmpty()) {
1338 ALOGE("Get description failed or is empty.");
1339 description = "NONE";
1340 }
1341 vendor += ".";
1342 vendor += description;
1343
1344 hidl_vec<DrmMetricGroup> pluginMetrics;
1345 status_t err = UNKNOWN_ERROR;
1346
1347 Return<void> status = mPluginV1_1->getMetrics(
1348 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1349 if (status != Status::OK) {
1350 ALOGV("Error getting plugin metrics: %d", status);
1351 } else {
1352 PersistableBundle pluginBundle;
1353 if (MediaDrmMetrics::HidlMetricsToBundle(
1354 pluginMetrics, &pluginBundle) == OK) {
1355 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1356 }
1357 }
1358 err = toStatusT(status);
1359 });
1360 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001361 }
1362
Adam Stoneab394d12017-12-22 12:34:20 -08001363 return OK;
1364}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001365
1366status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1367 String8 const &algorithm) {
1368 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001369 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001370
1371 DrmSessionManager::Instance()->useSession(sessionId);
1372
Jeff Tinkere6412942018-04-30 17:35:16 -07001373 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001374 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001375 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001376}
1377
1378status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1379 String8 const &algorithm) {
1380 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001381 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001382
1383 DrmSessionManager::Instance()->useSession(sessionId);
1384
Jeff Tinkere6412942018-04-30 17:35:16 -07001385 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001386 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001387 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001388}
1389
1390status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001391 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1392 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001393 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
1398 status_t err = UNKNOWN_ERROR;
1399
1400 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1401 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1402 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1403 if (status == Status::OK) {
1404 output = toVector(hOutput);
1405 }
1406 err = toStatusT(status);
1407 }
1408 );
1409
1410 return hResult.isOk() ? err : DEAD_OBJECT;
1411}
1412
1413status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001414 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1415 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001416 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001417 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001418
1419 DrmSessionManager::Instance()->useSession(sessionId);
1420
1421 status_t err = UNKNOWN_ERROR;
1422
1423 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1424 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1425 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1426 if (status == Status::OK) {
1427 output = toVector(hOutput);
1428 }
1429 err = toStatusT(status);
1430 }
1431 );
1432
1433 return hResult.isOk() ? err : DEAD_OBJECT;
1434}
1435
1436status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001437 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1438 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001439 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001440 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001441
1442 DrmSessionManager::Instance()->useSession(sessionId);
1443
1444 status_t err = UNKNOWN_ERROR;
1445
1446 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1447 toHidlVec(keyId), toHidlVec(message),
1448 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1449 if (status == Status::OK) {
1450 signature = toVector(hSignature);
1451 }
1452 err = toStatusT(status);
1453 }
1454 );
1455
1456 return hResult.isOk() ? err : DEAD_OBJECT;
1457}
1458
1459status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001460 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1461 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001462 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001463 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001464
1465 DrmSessionManager::Instance()->useSession(sessionId);
1466
1467 status_t err = UNKNOWN_ERROR;
1468
1469 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1470 toHidlVec(message), toHidlVec(signature),
1471 [&](Status status, bool hMatch) {
1472 if (status == Status::OK) {
1473 match = hMatch;
1474 } else {
1475 match = false;
1476 }
1477 err = toStatusT(status);
1478 }
1479 );
1480
1481 return hResult.isOk() ? err : DEAD_OBJECT;
1482}
1483
1484status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001485 String8 const &algorithm, Vector<uint8_t> const &message,
1486 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
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 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1491 return -EPERM;
1492 }
1493
1494 DrmSessionManager::Instance()->useSession(sessionId);
1495
1496 status_t err = UNKNOWN_ERROR;
1497
1498 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1499 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1500 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1501 if (status == Status::OK) {
1502 signature = toVector(hSignature);
1503 }
1504 err = toStatusT(status);
1505 }
1506 );
1507
1508 return hResult.isOk() ? err : DEAD_OBJECT;
1509}
1510
1511void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1512{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001513 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001514}
1515
1516void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1517{
1518 if (vec.size()) {
1519 obj.writeInt32(vec.size());
1520 obj.write(vec.data(), vec.size());
1521 } else {
1522 obj.writeInt32(0);
1523 }
1524}
1525
Adam Stonefb679e32018-02-07 10:25:48 -08001526void DrmHal::reportFrameworkMetrics() const
1527{
1528 MediaAnalyticsItem item("mediadrm");
1529 item.generateSessionID();
1530 item.setPkgName(mMetrics.GetAppPackageName().c_str());
1531 String8 vendor;
1532 String8 description;
1533 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1534 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001535 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001536 } else {
1537 item.setCString("vendor", vendor.c_str());
1538 }
1539 result = getPropertyStringInternal(String8("description"), description);
1540 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001541 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001542 } else {
1543 item.setCString("description", description.c_str());
1544 }
Adam Stoneab394d12017-12-22 12:34:20 -08001545
Adam Stonefb679e32018-02-07 10:25:48 -08001546 std::string serializedMetrics;
1547 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1548 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001549 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001550 }
Adam Stone32494f52018-02-26 22:53:27 -08001551 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1552 serializedMetrics.size());
1553 if (!b64EncodedMetrics.empty()) {
1554 item.setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001555 }
1556 if (!item.selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001557 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001558 }
1559}
1560
1561void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001562{
Adam Stone32494f52018-02-26 22:53:27 -08001563 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001564 String8 vendor;
1565 String8 description;
1566 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1567 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001568 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1569 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1570 metricsVector.size());
1571 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1572 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001573 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001574 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001575 }
1576 }
1577}
1578
Jeff Tinkera53d6552017-01-20 00:31:46 -08001579} // namespace android