blob: fc847ff72f243553f20941ca47206e35074b52be [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;
66
Adam Stonecea91ce2018-01-22 19:23:28 -080067namespace {
68
69// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
70// in the MediaDrm API.
71constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080072constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080073
Adam Stone32494f52018-02-26 22:53:27 -080074template<typename T>
75std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070076 // Note that the base 64 conversion only works with arrays of single-byte
77 // values. If the source is empty or is not an array of single-byte values,
78 // return empty string.
79 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080080 return "";
81 }
Adam Stone32494f52018-02-26 22:53:27 -080082
83 android::AString outputString;
84 encodeBase64(data, size, &outputString);
85 // Remove trailing equals padding if it exists.
86 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
87 outputString.erase(outputString.size() - 1, 1);
88 }
89
90 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080091}
92
Adam Stone32494f52018-02-26 22:53:27 -080093} // anonymous namespace
94
Jeff Tinkera53d6552017-01-20 00:31:46 -080095namespace android {
96
Jeff Tinker6d998b62017-12-18 14:37:43 -080097#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
98
Jeff Tinkera53d6552017-01-20 00:31:46 -080099static inline int getCallingPid() {
100 return IPCThreadState::self()->getCallingPid();
101}
102
103static bool checkPermission(const char* permissionString) {
104 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
105 bool ok = checkCallingPermission(String16(permissionString));
106 if (!ok) ALOGE("Request requires %s", permissionString);
107 return ok;
108}
109
110static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
111 Vector<uint8_t> vector;
112 vector.appendArray(vec.data(), vec.size());
113 return *const_cast<const Vector<uint8_t> *>(&vector);
114}
115
116static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
117 hidl_vec<uint8_t> vec;
118 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
119 return vec;
120}
121
122static String8 toString8(const hidl_string &string) {
123 return String8(string.c_str());
124}
125
126static hidl_string toHidlString(const String8& string) {
127 return hidl_string(string.string());
128}
129
Jeff Tinker6d998b62017-12-18 14:37:43 -0800130static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
131 switch(level) {
132 case SecurityLevel::SW_SECURE_CRYPTO:
133 return DrmPlugin::kSecurityLevelSwSecureCrypto;
134 case SecurityLevel::SW_SECURE_DECODE:
135 return DrmPlugin::kSecurityLevelSwSecureDecode;
136 case SecurityLevel::HW_SECURE_CRYPTO:
137 return DrmPlugin::kSecurityLevelHwSecureCrypto;
138 case SecurityLevel::HW_SECURE_DECODE:
139 return DrmPlugin::kSecurityLevelHwSecureDecode;
140 case SecurityLevel::HW_SECURE_ALL:
141 return DrmPlugin::kSecurityLevelHwSecureAll;
142 default:
143 return DrmPlugin::kSecurityLevelUnknown;
144 }
145}
146
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700147static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
148 OfflineLicenseState licenseState) {
149 switch(licenseState) {
150 case OfflineLicenseState::USABLE:
151 return DrmPlugin::kOfflineLicenseStateUsable;
152 case OfflineLicenseState::INACTIVE:
153 return DrmPlugin::kOfflineLicenseStateInactive;
154 default:
155 return DrmPlugin::kOfflineLicenseStateUnknown;
156 }
157}
158
Jeff Tinker6d998b62017-12-18 14:37:43 -0800159static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
160 switch(level) {
161 case HdcpLevel::HDCP_NONE:
162 return DrmPlugin::kHdcpNone;
163 case HdcpLevel::HDCP_V1:
164 return DrmPlugin::kHdcpV1;
165 case HdcpLevel::HDCP_V2:
166 return DrmPlugin::kHdcpV2;
167 case HdcpLevel::HDCP_V2_1:
168 return DrmPlugin::kHdcpV2_1;
169 case HdcpLevel::HDCP_V2_2:
170 return DrmPlugin::kHdcpV2_2;
171 case HdcpLevel::HDCP_NO_OUTPUT:
172 return DrmPlugin::kHdcpNoOutput;
173 default:
174 return DrmPlugin::kHdcpLevelUnknown;
175 }
176}
177
Jeff Tinkera53d6552017-01-20 00:31:46 -0800178
179static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
180 keyedVector) {
181 std::vector<KeyValue> stdKeyedVector;
182 for (size_t i = 0; i < keyedVector.size(); i++) {
183 KeyValue keyValue;
184 keyValue.key = toHidlString(keyedVector.keyAt(i));
185 keyValue.value = toHidlString(keyedVector.valueAt(i));
186 stdKeyedVector.push_back(keyValue);
187 }
188 return ::KeyedVector(stdKeyedVector);
189}
190
191static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
192 hKeyedVector) {
193 KeyedVector<String8, String8> keyedVector;
194 for (size_t i = 0; i < hKeyedVector.size(); i++) {
195 keyedVector.add(toString8(hKeyedVector[i].key),
196 toString8(hKeyedVector[i].value));
197 }
198 return keyedVector;
199}
200
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800201static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800202 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800203 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800204 for (size_t i = 0; i < hSecureStops.size(); i++) {
205 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
206 }
207 return secureStops;
208}
209
Jeff Tinker15177d72018-01-25 12:57:55 -0800210static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
211 hSecureStopIds) {
212 List<Vector<uint8_t>> secureStopIds;
213 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
214 secureStopIds.push_back(toVector(hSecureStopIds[i]));
215 }
216 return secureStopIds;
217}
218
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700219static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
220 hKeySetIds) {
221 List<Vector<uint8_t>> keySetIds;
222 for (size_t i = 0; i < hKeySetIds.size(); i++) {
223 keySetIds.push_back(toVector(hKeySetIds[i]));
224 }
225 return keySetIds;
226}
227
Jeff Tinkera53d6552017-01-20 00:31:46 -0800228static status_t toStatusT(Status status) {
229 switch (status) {
230 case Status::OK:
231 return OK;
232 break;
233 case Status::ERROR_DRM_NO_LICENSE:
234 return ERROR_DRM_NO_LICENSE;
235 break;
236 case Status::ERROR_DRM_LICENSE_EXPIRED:
237 return ERROR_DRM_LICENSE_EXPIRED;
238 break;
239 case Status::ERROR_DRM_SESSION_NOT_OPENED:
240 return ERROR_DRM_SESSION_NOT_OPENED;
241 break;
242 case Status::ERROR_DRM_CANNOT_HANDLE:
243 return ERROR_DRM_CANNOT_HANDLE;
244 break;
245 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800246 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800247 break;
248 case Status::BAD_VALUE:
249 return BAD_VALUE;
250 break;
251 case Status::ERROR_DRM_NOT_PROVISIONED:
252 return ERROR_DRM_NOT_PROVISIONED;
253 break;
254 case Status::ERROR_DRM_RESOURCE_BUSY:
255 return ERROR_DRM_RESOURCE_BUSY;
256 break;
257 case Status::ERROR_DRM_DEVICE_REVOKED:
258 return ERROR_DRM_DEVICE_REVOKED;
259 break;
260 case Status::ERROR_DRM_UNKNOWN:
261 default:
262 return ERROR_DRM_UNKNOWN;
263 break;
264 }
265}
266
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800267static status_t toStatusT_1_2(Status_V1_2 status) {
268 switch (status) {
269 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
270 return ERROR_DRM_RESOURCE_CONTENTION;
271 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
272 return ERROR_DRM_FRAME_TOO_LARGE;
273 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
274 return ERROR_DRM_INSUFFICIENT_SECURITY;
275 default:
276 return toStatusT(static_cast<Status>(status));
277 }
278}
279
Jeff Tinkera53d6552017-01-20 00:31:46 -0800280
281Mutex DrmHal::mLock;
282
283struct DrmSessionClient : public DrmSessionClientInterface {
284 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
285
286 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
287 sp<DrmHal> drm = mDrm.promote();
288 if (drm == NULL) {
289 return true;
290 }
291 status_t err = drm->closeSession(sessionId);
292 if (err != OK) {
293 return false;
294 }
295 drm->sendEvent(EventType::SESSION_RECLAIMED,
296 toHidlVec(sessionId), hidl_vec<uint8_t>());
297 return true;
298 }
299
300protected:
301 virtual ~DrmSessionClient() {}
302
303private:
304 wp<DrmHal> mDrm;
305
306 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
307};
308
309DrmHal::DrmHal()
310 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800311 mFactories(makeDrmFactories()),
312 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800313}
314
Jeff Tinker61332812017-05-15 16:53:10 -0700315void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800316 Mutex::Autolock autoLock(mLock);
317 auto openSessions = mOpenSessions;
318 for (size_t i = 0; i < openSessions.size(); i++) {
319 mLock.unlock();
320 closeSession(openSessions[i]);
321 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700322 }
323 mOpenSessions.clear();
324}
325
Jeff Tinkera53d6552017-01-20 00:31:46 -0800326DrmHal::~DrmHal() {
327 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
328}
329
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800330void DrmHal::cleanup() {
331 closeOpenSessions();
332
333 Mutex::Autolock autoLock(mLock);
334 reportPluginMetrics();
335 reportFrameworkMetrics();
336
337 setListener(NULL);
338 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800339 if (mPluginV1_2 != NULL) {
340 if (!mPluginV1_2->setListener(NULL).isOk()) {
341 mInitCheck = DEAD_OBJECT;
342 }
343 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800344 if (!mPlugin->setListener(NULL).isOk()) {
345 mInitCheck = DEAD_OBJECT;
346 }
347 }
348 mPlugin.clear();
349 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700350 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800351}
352
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800353Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
354 Vector<sp<IDrmFactory>> factories;
355
Jeff Tinker593111f2017-05-25 16:00:21 -0700356 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800357
358 if (manager != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000359 manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800360 [&factories](const hidl_vec<hidl_string> &registered) {
361 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000362 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800363 if (factory != NULL) {
364 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000365 }
366 }
367 }
368 );
369 manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
370 [&factories](const hidl_vec<hidl_string> &registered) {
371 for (const auto &instance : registered) {
372 auto factory = drm::V1_1::IDrmFactory::getService(instance);
373 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000374 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800375 }
376 }
377 }
378 );
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700379 manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
380 [&factories](const hidl_vec<hidl_string> &registered) {
381 for (const auto &instance : registered) {
382 auto factory = drm::V1_2::IDrmFactory::getService(instance);
383 if (factory != NULL) {
384 factories.push_back(factory);
385 }
386 }
387 }
388 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800389 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800390
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800391 if (factories.size() == 0) {
392 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700393 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800394 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000395 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800396 factories.push_back(passthrough);
397 } else {
398 ALOGE("Failed to find any drm factories");
399 }
400 }
401 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800402}
403
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800404sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
405 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800406 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800407 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800408
409 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800410 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800411 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800412 if (status != Status::OK) {
413 ALOGE("Failed to make drm plugin");
414 return;
415 }
416 plugin = hPlugin;
417 }
418 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700419
420 if (!hResult.isOk()) {
421 ALOGE("createPlugin remote call failed");
422 }
423
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424 return plugin;
425}
426
427status_t DrmHal::initCheck() const {
428 return mInitCheck;
429}
430
431status_t DrmHal::setListener(const sp<IDrmClient>& listener)
432{
433 Mutex::Autolock lock(mEventLock);
434 if (mListener != NULL){
435 IInterface::asBinder(mListener)->unlinkToDeath(this);
436 }
437 if (listener != NULL) {
438 IInterface::asBinder(listener)->linkToDeath(this);
439 }
440 mListener = listener;
441 return NO_ERROR;
442}
443
444Return<void> DrmHal::sendEvent(EventType hEventType,
445 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800446 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800447
448 mEventLock.lock();
449 sp<IDrmClient> listener = mListener;
450 mEventLock.unlock();
451
452 if (listener != NULL) {
453 Parcel obj;
454 writeByteArray(obj, sessionId);
455 writeByteArray(obj, data);
456
457 Mutex::Autolock lock(mNotifyLock);
458 DrmPlugin::EventType eventType;
459 switch(hEventType) {
460 case EventType::PROVISION_REQUIRED:
461 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
462 break;
463 case EventType::KEY_NEEDED:
464 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
465 break;
466 case EventType::KEY_EXPIRED:
467 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
468 break;
469 case EventType::VENDOR_DEFINED:
470 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
471 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700472 case EventType::SESSION_RECLAIMED:
473 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
474 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800475 default:
476 return Void();
477 }
478 listener->notify(eventType, 0, &obj);
479 }
480 return Void();
481}
482
483Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
484 int64_t expiryTimeInMS) {
485
486 mEventLock.lock();
487 sp<IDrmClient> listener = mListener;
488 mEventLock.unlock();
489
490 if (listener != NULL) {
491 Parcel obj;
492 writeByteArray(obj, sessionId);
493 obj.writeInt64(expiryTimeInMS);
494
495 Mutex::Autolock lock(mNotifyLock);
496 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
497 }
498 return Void();
499}
500
501Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
502 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
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
512 size_t nKeys = keyStatusList.size();
513 obj.writeInt32(nKeys);
514 for (size_t i = 0; i < nKeys; ++i) {
515 const KeyStatus &keyStatus = keyStatusList[i];
516 writeByteArray(obj, keyStatus.keyId);
517 uint32_t type;
518 switch(keyStatus.type) {
519 case KeyStatusType::USABLE:
520 type = DrmPlugin::kKeyStatusType_Usable;
521 break;
522 case KeyStatusType::EXPIRED:
523 type = DrmPlugin::kKeyStatusType_Expired;
524 break;
525 case KeyStatusType::OUTPUTNOTALLOWED:
526 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
527 break;
528 case KeyStatusType::STATUSPENDING:
529 type = DrmPlugin::kKeyStatusType_StatusPending;
530 break;
531 case KeyStatusType::INTERNALERROR:
532 default:
533 type = DrmPlugin::kKeyStatusType_InternalError;
534 break;
535 }
536 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800537 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800538 }
539 obj.writeInt32(hasNewUsableKey);
540
541 Mutex::Autolock lock(mNotifyLock);
542 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800543 } else {
544 // There's no listener. But we still want to count the key change
545 // events.
546 size_t nKeys = keyStatusList.size();
547 for (size_t i = 0; i < nKeys; i++) {
548 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
549 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800550 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800551
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552 return Void();
553}
554
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800555Return<void> DrmHal::sendSessionLostState(
556 const hidl_vec<uint8_t>& sessionId) {
557
558 mEventLock.lock();
559 sp<IDrmClient> listener = mListener;
560 mEventLock.unlock();
561
562 if (listener != NULL) {
563 Parcel obj;
564 writeByteArray(obj, sessionId);
565 Mutex::Autolock lock(mNotifyLock);
566 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
567 }
568 return Void();
569}
570
Jeff Tinkera53d6552017-01-20 00:31:46 -0800571bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
572 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800573
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800574 for (size_t i = 0; i < mFactories.size(); i++) {
575 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
576 if (mimeType != "") {
577 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
578 return true;
579 }
580 } else {
581 return true;
582 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583 }
584 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800585 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800586}
587
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800588status_t DrmHal::createPlugin(const uint8_t uuid[16],
589 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800590 Mutex::Autolock autoLock(mLock);
591
Peter Kalauskas7676a402018-12-27 11:04:16 -0800592 for (size_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800593 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800594 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
595 if (plugin != NULL) {
596 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800597 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700598 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800599 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800600 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800601 }
602 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800603
604 if (mPlugin == NULL) {
605 mInitCheck = ERROR_UNSUPPORTED;
606 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800607 mInitCheck = OK;
608 if (mPluginV1_2 != NULL) {
609 if (!mPluginV1_2->setListener(this).isOk()) {
610 mInitCheck = DEAD_OBJECT;
611 }
612 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700613 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800614 }
615 if (mInitCheck != OK) {
616 mPlugin.clear();
617 mPluginV1_1.clear();
618 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700619 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800620 }
621
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800622
Jeff Tinkera53d6552017-01-20 00:31:46 -0800623 return mInitCheck;
624}
625
626status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800627 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800628 return OK;
629}
630
Jeff Tinker41d279a2018-02-11 19:52:08 +0000631status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
632 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800633 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800634 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800635
Jeff Tinker41d279a2018-02-11 19:52:08 +0000636 SecurityLevel hSecurityLevel;
637 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000638
Jeff Tinker41d279a2018-02-11 19:52:08 +0000639 switch(level) {
640 case DrmPlugin::kSecurityLevelSwSecureCrypto:
641 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
642 break;
643 case DrmPlugin::kSecurityLevelSwSecureDecode:
644 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
645 break;
646 case DrmPlugin::kSecurityLevelHwSecureCrypto:
647 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
648 break;
649 case DrmPlugin::kSecurityLevelHwSecureDecode:
650 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
651 break;
652 case DrmPlugin::kSecurityLevelHwSecureAll:
653 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
654 break;
655 case DrmPlugin::kSecurityLevelMax:
656 setSecurityLevel = false;
657 break;
658 default:
659 return ERROR_DRM_CANNOT_HANDLE;
660 }
661
662 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800663 bool retry = true;
664 do {
665 hidl_vec<uint8_t> hSessionId;
666
Jeff Tinker41d279a2018-02-11 19:52:08 +0000667 Return<void> hResult;
668 if (mPluginV1_1 == NULL || !setSecurityLevel) {
669 hResult = mPlugin->openSession(
670 [&](Status status,const hidl_vec<uint8_t>& id) {
671 if (status == Status::OK) {
672 sessionId = toVector(id);
673 }
674 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800675 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000676 );
677 } else {
678 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
679 [&](Status status, const hidl_vec<uint8_t>& id) {
680 if (status == Status::OK) {
681 sessionId = toVector(id);
682 }
683 err = toStatusT(status);
684 }
685 );
686 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800687
688 if (!hResult.isOk()) {
689 err = DEAD_OBJECT;
690 }
691
692 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
693 mLock.unlock();
694 // reclaimSession may call back to closeSession, since mLock is
695 // shared between Drm instances, we should unlock here to avoid
696 // deadlock.
697 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
698 mLock.lock();
699 } else {
700 retry = false;
701 }
702 } while (retry);
703
704 if (err == OK) {
705 DrmSessionManager::Instance()->addSession(getCallingPid(),
706 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700707 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800708 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800709 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800710
Adam Stonef0e618d2018-01-17 19:20:41 -0800711 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800712 return err;
713}
714
715status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
716 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800717 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800718
Jeff Tinker319d5f42017-07-26 15:44:33 -0700719 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
720 if (status.isOk()) {
721 if (status == Status::OK) {
722 DrmSessionManager::Instance()->removeSession(sessionId);
723 for (size_t i = 0; i < mOpenSessions.size(); i++) {
724 if (mOpenSessions[i] == sessionId) {
725 mOpenSessions.removeAt(i);
726 break;
727 }
Jeff Tinker61332812017-05-15 16:53:10 -0700728 }
729 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800730 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800731 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800732 mMetrics.mCloseSessionCounter.Increment(response);
733 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800734 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800735 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700736 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800737}
738
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800739static DrmPlugin::KeyRequestType toKeyRequestType(
740 KeyRequestType keyRequestType) {
741 switch (keyRequestType) {
742 case KeyRequestType::INITIAL:
743 return DrmPlugin::kKeyRequestType_Initial;
744 break;
745 case KeyRequestType::RENEWAL:
746 return DrmPlugin::kKeyRequestType_Renewal;
747 break;
748 case KeyRequestType::RELEASE:
749 return DrmPlugin::kKeyRequestType_Release;
750 break;
751 default:
752 return DrmPlugin::kKeyRequestType_Unknown;
753 break;
754 }
755}
756
757static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
758 KeyRequestType_V1_1 keyRequestType) {
759 switch (keyRequestType) {
760 case KeyRequestType_V1_1::NONE:
761 return DrmPlugin::kKeyRequestType_None;
762 break;
763 case KeyRequestType_V1_1::UPDATE:
764 return DrmPlugin::kKeyRequestType_Update;
765 break;
766 default:
767 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
768 break;
769 }
770}
771
Jeff Tinkera53d6552017-01-20 00:31:46 -0800772status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
773 Vector<uint8_t> const &initData, String8 const &mimeType,
774 DrmPlugin::KeyType keyType, KeyedVector<String8,
775 String8> const &optionalParameters, Vector<uint8_t> &request,
776 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
777 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800778 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800779 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800780
781 DrmSessionManager::Instance()->useSession(sessionId);
782
783 KeyType hKeyType;
784 if (keyType == DrmPlugin::kKeyType_Streaming) {
785 hKeyType = KeyType::STREAMING;
786 } else if (keyType == DrmPlugin::kKeyType_Offline) {
787 hKeyType = KeyType::OFFLINE;
788 } else if (keyType == DrmPlugin::kKeyType_Release) {
789 hKeyType = KeyType::RELEASE;
790 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800791 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800792 return BAD_VALUE;
793 }
794
795 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
796
797 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800798 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800799
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800800 if (mPluginV1_2 != NULL) {
801 hResult = mPluginV1_2->getKeyRequest_1_2(
802 toHidlVec(sessionId), toHidlVec(initData),
803 toHidlString(mimeType), hKeyType, hOptionalParameters,
804 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
805 KeyRequestType_V1_1 hKeyRequestType,
806 const hidl_string& hDefaultUrl) {
807 if (status == Status_V1_2::OK) {
808 request = toVector(hRequest);
809 defaultUrl = toString8(hDefaultUrl);
810 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
811 }
812 err = toStatusT_1_2(status);
813 });
814 } else if (mPluginV1_1 != NULL) {
815 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800816 toHidlVec(sessionId), toHidlVec(initData),
817 toHidlString(mimeType), hKeyType, hOptionalParameters,
818 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800819 KeyRequestType_V1_1 hKeyRequestType,
820 const hidl_string& hDefaultUrl) {
821 if (status == Status::OK) {
822 request = toVector(hRequest);
823 defaultUrl = toString8(hDefaultUrl);
824 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800825 }
826 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800827 });
828 } else {
829 hResult = mPlugin->getKeyRequest(
830 toHidlVec(sessionId), toHidlVec(initData),
831 toHidlString(mimeType), hKeyType, hOptionalParameters,
832 [&](Status status, const hidl_vec<uint8_t>& hRequest,
833 KeyRequestType hKeyRequestType,
834 const hidl_string& hDefaultUrl) {
835 if (status == Status::OK) {
836 request = toVector(hRequest);
837 defaultUrl = toString8(hDefaultUrl);
838 *keyRequestType = toKeyRequestType(hKeyRequestType);
839 }
840 err = toStatusT(status);
841 });
842 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800843
Adam Stonef0e618d2018-01-17 19:20:41 -0800844 err = hResult.isOk() ? err : DEAD_OBJECT;
845 keyRequestTimer.SetAttribute(err);
846 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800847}
848
849status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
850 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
851 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800852 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800853
Jeff Tinker6d998b62017-12-18 14:37:43 -0800854 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800855
856 DrmSessionManager::Instance()->useSession(sessionId);
857
858 status_t err = UNKNOWN_ERROR;
859
860 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
861 toHidlVec(response),
862 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
863 if (status == Status::OK) {
864 keySetId = toVector(hKeySetId);
865 }
866 err = toStatusT(status);
867 }
868 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800869 err = hResult.isOk() ? err : DEAD_OBJECT;
870 keyResponseTimer.SetAttribute(err);
871 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800872}
873
874status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
875 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800876 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800877
Jeff Tinker58ad4752018-02-16 16:51:59 -0800878 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
879 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800880}
881
882status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
883 Vector<uint8_t> const &keySetId) {
884 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800885 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800886
887 DrmSessionManager::Instance()->useSession(sessionId);
888
Jeff Tinker58ad4752018-02-16 16:51:59 -0800889 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
890 toHidlVec(keySetId));
891 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800892}
893
894status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
895 KeyedVector<String8, String8> &infoMap) const {
896 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800897 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800898
899 DrmSessionManager::Instance()->useSession(sessionId);
900
901 ::KeyedVector hInfoMap;
902
903 status_t err = UNKNOWN_ERROR;
904
905 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
906 [&](Status status, const hidl_vec<KeyValue>& map) {
907 if (status == Status::OK) {
908 infoMap = toKeyedVector(map);
909 }
910 err = toStatusT(status);
911 }
912 );
913
914 return hResult.isOk() ? err : DEAD_OBJECT;
915}
916
917status_t DrmHal::getProvisionRequest(String8 const &certType,
918 String8 const &certAuthority, Vector<uint8_t> &request,
919 String8 &defaultUrl) {
920 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800921 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800922
923 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800924 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800925
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800926 if (mPluginV1_2 != NULL) {
927 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
928 toHidlString(certType), toHidlString(certAuthority),
929 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
930 const hidl_string& hDefaultUrl) {
931 if (status == Status_V1_2::OK) {
932 request = toVector(hRequest);
933 defaultUrl = toString8(hDefaultUrl);
934 }
935 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800936 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800937 );
938 } else {
939 Return<void> hResult = mPlugin->getProvisionRequest(
940 toHidlString(certType), toHidlString(certAuthority),
941 [&](Status status, const hidl_vec<uint8_t>& hRequest,
942 const hidl_string& hDefaultUrl) {
943 if (status == Status::OK) {
944 request = toVector(hRequest);
945 defaultUrl = toString8(hDefaultUrl);
946 }
947 err = toStatusT(status);
948 }
949 );
950 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800951
Adam Stonecea91ce2018-01-22 19:23:28 -0800952 err = hResult.isOk() ? err : DEAD_OBJECT;
953 mMetrics.mGetProvisionRequestCounter.Increment(err);
954 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800955}
956
957status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800958 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800959 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800960 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800961
962 status_t err = UNKNOWN_ERROR;
963
964 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
965 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
966 const hidl_vec<uint8_t>& hWrappedKey) {
967 if (status == Status::OK) {
968 certificate = toVector(hCertificate);
969 wrappedKey = toVector(hWrappedKey);
970 }
971 err = toStatusT(status);
972 }
973 );
974
Adam Stonecea91ce2018-01-22 19:23:28 -0800975 err = hResult.isOk() ? err : DEAD_OBJECT;
976 mMetrics.mProvideProvisionResponseCounter.Increment(err);
977 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800978}
979
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800980status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800981 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800982 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800983
984 status_t err = UNKNOWN_ERROR;
985
986 Return<void> hResult = mPlugin->getSecureStops(
987 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
988 if (status == Status::OK) {
989 secureStops = toSecureStops(hSecureStops);
990 }
991 err = toStatusT(status);
992 }
993 );
994
995 return hResult.isOk() ? err : DEAD_OBJECT;
996}
997
998
Jeff Tinker15177d72018-01-25 12:57:55 -0800999status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1000 Mutex::Autolock autoLock(mLock);
1001
1002 if (mInitCheck != OK) {
1003 return mInitCheck;
1004 }
1005
1006 if (mPluginV1_1 == NULL) {
1007 return ERROR_DRM_CANNOT_HANDLE;
1008 }
1009
1010 status_t err = UNKNOWN_ERROR;
1011
1012 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1013 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1014 if (status == Status::OK) {
1015 secureStopIds = toSecureStopIds(hSecureStopIds);
1016 }
1017 err = toStatusT(status);
1018 }
1019 );
1020
1021 return hResult.isOk() ? err : DEAD_OBJECT;
1022}
1023
1024
Jeff Tinkera53d6552017-01-20 00:31:46 -08001025status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1026 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001027 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001028
1029 status_t err = UNKNOWN_ERROR;
1030
1031 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1032 [&](Status status, const SecureStop& hSecureStop) {
1033 if (status == Status::OK) {
1034 secureStop = toVector(hSecureStop.opaqueData);
1035 }
1036 err = toStatusT(status);
1037 }
1038 );
1039
1040 return hResult.isOk() ? err : DEAD_OBJECT;
1041}
1042
1043status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1044 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001045 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001046
Jeff Tinker58ad4752018-02-16 16:51:59 -08001047 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001048 if (mPluginV1_1 != NULL) {
1049 SecureStopRelease secureStopRelease;
1050 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001051 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1052 } else {
1053 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001054 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001055 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001056}
1057
Jeff Tinker15177d72018-01-25 12:57:55 -08001058status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1059 Mutex::Autolock autoLock(mLock);
1060
1061 if (mInitCheck != OK) {
1062 return mInitCheck;
1063 }
1064
1065 if (mPluginV1_1 == NULL) {
1066 return ERROR_DRM_CANNOT_HANDLE;
1067 }
1068
Jeff Tinker58ad4752018-02-16 16:51:59 -08001069 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1070 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001071}
1072
1073status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001074 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001075 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001076
Jeff Tinker58ad4752018-02-16 16:51:59 -08001077 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001078 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001079 status = mPluginV1_1->removeAllSecureStops();
1080 } else {
1081 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001082 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001083 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001084}
1085
Jeff Tinker6d998b62017-12-18 14:37:43 -08001086status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1087 DrmPlugin::HdcpLevel *max) const {
1088 Mutex::Autolock autoLock(mLock);
1089 INIT_CHECK();
1090
1091 if (connected == NULL || max == NULL) {
1092 return BAD_VALUE;
1093 }
1094 status_t err = UNKNOWN_ERROR;
1095
1096 if (mPluginV1_1 == NULL) {
1097 return ERROR_DRM_CANNOT_HANDLE;
1098 }
1099
1100 *connected = DrmPlugin::kHdcpLevelUnknown;
1101 *max = DrmPlugin::kHdcpLevelUnknown;
1102
1103 Return<void> hResult = mPluginV1_1->getHdcpLevels(
1104 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1105 if (status == Status::OK) {
1106 *connected = toHdcpLevel(hConnected);
1107 *max = toHdcpLevel(hMax);
1108 }
1109 err = toStatusT(status);
1110 }
1111 );
1112
1113 return hResult.isOk() ? err : DEAD_OBJECT;
1114}
1115
1116status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1117 Mutex::Autolock autoLock(mLock);
1118 INIT_CHECK();
1119
1120 if (open == NULL || max == NULL) {
1121 return BAD_VALUE;
1122 }
1123 status_t err = UNKNOWN_ERROR;
1124
1125 *open = 0;
1126 *max = 0;
1127
1128 if (mPluginV1_1 == NULL) {
1129 return ERROR_DRM_CANNOT_HANDLE;
1130 }
1131
1132 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1133 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1134 if (status == Status::OK) {
1135 *open = hOpen;
1136 *max = hMax;
1137 }
1138 err = toStatusT(status);
1139 }
1140 );
1141
1142 return hResult.isOk() ? err : DEAD_OBJECT;
1143}
1144
1145status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1146 DrmPlugin::SecurityLevel *level) const {
1147 Mutex::Autolock autoLock(mLock);
1148 INIT_CHECK();
1149
1150 if (level == NULL) {
1151 return BAD_VALUE;
1152 }
1153 status_t err = UNKNOWN_ERROR;
1154
1155 if (mPluginV1_1 == NULL) {
1156 return ERROR_DRM_CANNOT_HANDLE;
1157 }
1158
1159 *level = DrmPlugin::kSecurityLevelUnknown;
1160
1161 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1162 [&](Status status, SecurityLevel hLevel) {
1163 if (status == Status::OK) {
1164 *level = toSecurityLevel(hLevel);
1165 }
1166 err = toStatusT(status);
1167 }
1168 );
1169
1170 return hResult.isOk() ? err : DEAD_OBJECT;
1171}
1172
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001173status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1174 Mutex::Autolock autoLock(mLock);
1175
1176 if (mInitCheck != OK) {
1177 return mInitCheck;
1178 }
1179
1180 if (mPluginV1_2 == NULL) {
1181 return ERROR_DRM_CANNOT_HANDLE;
1182 }
1183
1184 status_t err = UNKNOWN_ERROR;
1185
1186 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1187 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1188 if (status == Status::OK) {
1189 keySetIds = toKeySetIds(hKeySetIds);
1190 }
1191 err = toStatusT(status);
1192 }
1193 );
1194
1195 return hResult.isOk() ? err : DEAD_OBJECT;
1196}
1197
1198status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1199 Mutex::Autolock autoLock(mLock);
1200
1201 if (mInitCheck != OK) {
1202 return mInitCheck;
1203 }
1204
1205 if (mPluginV1_2 == NULL) {
1206 return ERROR_DRM_CANNOT_HANDLE;
1207 }
1208
1209 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1210 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1211}
1212
1213status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1214 DrmPlugin::OfflineLicenseState *licenseState) const {
1215 Mutex::Autolock autoLock(mLock);
1216
1217 if (mInitCheck != OK) {
1218 return mInitCheck;
1219 }
1220
1221 if (mPluginV1_2 == NULL) {
1222 return ERROR_DRM_CANNOT_HANDLE;
1223 }
1224 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1225
1226 status_t err = UNKNOWN_ERROR;
1227
1228 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1229 [&](Status status, OfflineLicenseState hLicenseState) {
1230 if (status == Status::OK) {
1231 *licenseState = toOfflineLicenseState(hLicenseState);
1232 }
1233 err = toStatusT(status);
1234 }
1235 );
1236
1237 return hResult.isOk() ? err : DEAD_OBJECT;
1238}
1239
Jeff Tinkera53d6552017-01-20 00:31:46 -08001240status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1241 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001242 return getPropertyStringInternal(name, value);
1243}
1244
1245status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1246 // This function is internal to the class and should only be called while
1247 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001248 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001249
1250 status_t err = UNKNOWN_ERROR;
1251
1252 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1253 [&](Status status, const hidl_string& hValue) {
1254 if (status == Status::OK) {
1255 value = toString8(hValue);
1256 }
1257 err = toStatusT(status);
1258 }
1259 );
1260
1261 return hResult.isOk() ? err : DEAD_OBJECT;
1262}
1263
1264status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1265 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001266 return getPropertyByteArrayInternal(name, value);
1267}
1268
1269status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1270 // This function is internal to the class and should only be called while
1271 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001272 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001273
1274 status_t err = UNKNOWN_ERROR;
1275
1276 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1277 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1278 if (status == Status::OK) {
1279 value = toVector(hValue);
1280 }
1281 err = toStatusT(status);
1282 }
1283 );
1284
Adam Stonecea91ce2018-01-22 19:23:28 -08001285 err = hResult.isOk() ? err : DEAD_OBJECT;
1286 if (name == kPropertyDeviceUniqueId) {
1287 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1288 }
1289 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001290}
1291
1292status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1293 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001294 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001295
Jeff Tinker58ad4752018-02-16 16:51:59 -08001296 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001297 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001298 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001299}
1300
1301status_t DrmHal::setPropertyByteArray(String8 const &name,
1302 Vector<uint8_t> 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->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001307 toHidlVec(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
Adam Stone28f27c32018-02-05 15:07:48 -08001311status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1312 if (metrics == nullptr) {
1313 return UNEXPECTED_NULL;
1314 }
1315 mMetrics.Export(metrics);
1316
1317 // Append vendor metrics if they are supported.
1318 if (mPluginV1_1 != NULL) {
1319 String8 vendor;
1320 String8 description;
1321 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1322 || vendor.isEmpty()) {
1323 ALOGE("Get vendor failed or is empty");
1324 vendor = "NONE";
1325 }
1326 if (getPropertyStringInternal(String8("description"), description) != OK
1327 || description.isEmpty()) {
1328 ALOGE("Get description failed or is empty.");
1329 description = "NONE";
1330 }
1331 vendor += ".";
1332 vendor += description;
1333
1334 hidl_vec<DrmMetricGroup> pluginMetrics;
1335 status_t err = UNKNOWN_ERROR;
1336
1337 Return<void> status = mPluginV1_1->getMetrics(
1338 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1339 if (status != Status::OK) {
1340 ALOGV("Error getting plugin metrics: %d", status);
1341 } else {
1342 PersistableBundle pluginBundle;
1343 if (MediaDrmMetrics::HidlMetricsToBundle(
1344 pluginMetrics, &pluginBundle) == OK) {
1345 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1346 }
1347 }
1348 err = toStatusT(status);
1349 });
1350 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001351 }
1352
Adam Stoneab394d12017-12-22 12:34:20 -08001353 return OK;
1354}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001355
1356status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1357 String8 const &algorithm) {
1358 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001359 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001360
1361 DrmSessionManager::Instance()->useSession(sessionId);
1362
Jeff Tinkere6412942018-04-30 17:35:16 -07001363 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001364 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001365 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001366}
1367
1368status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1369 String8 const &algorithm) {
1370 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001371 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001372
1373 DrmSessionManager::Instance()->useSession(sessionId);
1374
Jeff Tinkere6412942018-04-30 17:35:16 -07001375 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001376 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001377 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001378}
1379
1380status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001381 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1382 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001383 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001384 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001385
1386 DrmSessionManager::Instance()->useSession(sessionId);
1387
1388 status_t err = UNKNOWN_ERROR;
1389
1390 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1391 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1392 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1393 if (status == Status::OK) {
1394 output = toVector(hOutput);
1395 }
1396 err = toStatusT(status);
1397 }
1398 );
1399
1400 return hResult.isOk() ? err : DEAD_OBJECT;
1401}
1402
1403status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001404 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1405 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001406 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001407 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001408
1409 DrmSessionManager::Instance()->useSession(sessionId);
1410
1411 status_t err = UNKNOWN_ERROR;
1412
1413 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1414 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1415 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1416 if (status == Status::OK) {
1417 output = toVector(hOutput);
1418 }
1419 err = toStatusT(status);
1420 }
1421 );
1422
1423 return hResult.isOk() ? err : DEAD_OBJECT;
1424}
1425
1426status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001427 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1428 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001429 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001430 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001431
1432 DrmSessionManager::Instance()->useSession(sessionId);
1433
1434 status_t err = UNKNOWN_ERROR;
1435
1436 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1437 toHidlVec(keyId), toHidlVec(message),
1438 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1439 if (status == Status::OK) {
1440 signature = toVector(hSignature);
1441 }
1442 err = toStatusT(status);
1443 }
1444 );
1445
1446 return hResult.isOk() ? err : DEAD_OBJECT;
1447}
1448
1449status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001450 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1451 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001452 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001453 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001454
1455 DrmSessionManager::Instance()->useSession(sessionId);
1456
1457 status_t err = UNKNOWN_ERROR;
1458
1459 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1460 toHidlVec(message), toHidlVec(signature),
1461 [&](Status status, bool hMatch) {
1462 if (status == Status::OK) {
1463 match = hMatch;
1464 } else {
1465 match = false;
1466 }
1467 err = toStatusT(status);
1468 }
1469 );
1470
1471 return hResult.isOk() ? err : DEAD_OBJECT;
1472}
1473
1474status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001475 String8 const &algorithm, Vector<uint8_t> const &message,
1476 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001477 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001478 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001479
1480 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1481 return -EPERM;
1482 }
1483
1484 DrmSessionManager::Instance()->useSession(sessionId);
1485
1486 status_t err = UNKNOWN_ERROR;
1487
1488 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1489 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1490 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1491 if (status == Status::OK) {
1492 signature = toVector(hSignature);
1493 }
1494 err = toStatusT(status);
1495 }
1496 );
1497
1498 return hResult.isOk() ? err : DEAD_OBJECT;
1499}
1500
1501void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1502{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001503 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001504}
1505
1506void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1507{
1508 if (vec.size()) {
1509 obj.writeInt32(vec.size());
1510 obj.write(vec.data(), vec.size());
1511 } else {
1512 obj.writeInt32(0);
1513 }
1514}
1515
Adam Stonefb679e32018-02-07 10:25:48 -08001516void DrmHal::reportFrameworkMetrics() const
1517{
1518 MediaAnalyticsItem item("mediadrm");
1519 item.generateSessionID();
1520 item.setPkgName(mMetrics.GetAppPackageName().c_str());
1521 String8 vendor;
1522 String8 description;
1523 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1524 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001525 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001526 } else {
1527 item.setCString("vendor", vendor.c_str());
1528 }
1529 result = getPropertyStringInternal(String8("description"), description);
1530 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001531 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001532 } else {
1533 item.setCString("description", description.c_str());
1534 }
Adam Stoneab394d12017-12-22 12:34:20 -08001535
Adam Stonefb679e32018-02-07 10:25:48 -08001536 std::string serializedMetrics;
1537 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1538 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001539 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001540 }
Adam Stone32494f52018-02-26 22:53:27 -08001541 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1542 serializedMetrics.size());
1543 if (!b64EncodedMetrics.empty()) {
1544 item.setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001545 }
1546 if (!item.selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001547 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001548 }
1549}
1550
1551void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001552{
Adam Stone32494f52018-02-26 22:53:27 -08001553 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001554 String8 vendor;
1555 String8 description;
1556 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1557 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001558 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1559 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1560 metricsVector.size());
1561 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1562 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001563 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001564 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001565 }
1566 }
1567}
1568
Jeff Tinkera53d6552017-01-20 00:31:46 -08001569} // namespace android