blob: 982b117a348b12bc78ba5ba2bf14421f3df266c0 [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"
19#include <utils/Log.h>
20
21#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080023
24#include <android/hardware/drm/1.0/IDrmFactory.h>
25#include <android/hardware/drm/1.0/IDrmPlugin.h>
26#include <android/hardware/drm/1.0/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
30#include <media/DrmHal.h>
31#include <media/DrmSessionClientInterface.h>
32#include <media/DrmSessionManager.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070033#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080034#include <media/drm/DrmAPI.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AString.h>
37#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/MediaErrors.h>
39
Jeff Tinker6d998b62017-12-18 14:37:43 -080040using drm::V1_0::KeyedVector;
Jeff Tinker6d998b62017-12-18 14:37:43 -080041using drm::V1_0::KeyStatusType;
42using drm::V1_0::KeyType;
43using drm::V1_0::KeyValue;
44using drm::V1_1::HdcpLevel;;
45using drm::V1_0::SecureStop;
46using drm::V1_1::SecurityLevel;
47using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080048using ::android::hardware::hidl_array;
49using ::android::hardware::hidl_string;
50using ::android::hardware::hidl_vec;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080053using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080054using ::android::sp;
55
56namespace android {
57
Jeff Tinker6d998b62017-12-18 14:37:43 -080058#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
59
Jeff Tinkera53d6552017-01-20 00:31:46 -080060static inline int getCallingPid() {
61 return IPCThreadState::self()->getCallingPid();
62}
63
64static bool checkPermission(const char* permissionString) {
65 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
66 bool ok = checkCallingPermission(String16(permissionString));
67 if (!ok) ALOGE("Request requires %s", permissionString);
68 return ok;
69}
70
71static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
72 Vector<uint8_t> vector;
73 vector.appendArray(vec.data(), vec.size());
74 return *const_cast<const Vector<uint8_t> *>(&vector);
75}
76
77static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
78 hidl_vec<uint8_t> vec;
79 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
80 return vec;
81}
82
83static String8 toString8(const hidl_string &string) {
84 return String8(string.c_str());
85}
86
87static hidl_string toHidlString(const String8& string) {
88 return hidl_string(string.string());
89}
90
Jeff Tinker6d998b62017-12-18 14:37:43 -080091static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
92 switch(level) {
93 case SecurityLevel::SW_SECURE_CRYPTO:
94 return DrmPlugin::kSecurityLevelSwSecureCrypto;
95 case SecurityLevel::SW_SECURE_DECODE:
96 return DrmPlugin::kSecurityLevelSwSecureDecode;
97 case SecurityLevel::HW_SECURE_CRYPTO:
98 return DrmPlugin::kSecurityLevelHwSecureCrypto;
99 case SecurityLevel::HW_SECURE_DECODE:
100 return DrmPlugin::kSecurityLevelHwSecureDecode;
101 case SecurityLevel::HW_SECURE_ALL:
102 return DrmPlugin::kSecurityLevelHwSecureAll;
103 default:
104 return DrmPlugin::kSecurityLevelUnknown;
105 }
106}
107
108static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
109 switch(level) {
110 case HdcpLevel::HDCP_NONE:
111 return DrmPlugin::kHdcpNone;
112 case HdcpLevel::HDCP_V1:
113 return DrmPlugin::kHdcpV1;
114 case HdcpLevel::HDCP_V2:
115 return DrmPlugin::kHdcpV2;
116 case HdcpLevel::HDCP_V2_1:
117 return DrmPlugin::kHdcpV2_1;
118 case HdcpLevel::HDCP_V2_2:
119 return DrmPlugin::kHdcpV2_2;
120 case HdcpLevel::HDCP_NO_OUTPUT:
121 return DrmPlugin::kHdcpNoOutput;
122 default:
123 return DrmPlugin::kHdcpLevelUnknown;
124 }
125}
126
Jeff Tinkera53d6552017-01-20 00:31:46 -0800127
128static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
129 keyedVector) {
130 std::vector<KeyValue> stdKeyedVector;
131 for (size_t i = 0; i < keyedVector.size(); i++) {
132 KeyValue keyValue;
133 keyValue.key = toHidlString(keyedVector.keyAt(i));
134 keyValue.value = toHidlString(keyedVector.valueAt(i));
135 stdKeyedVector.push_back(keyValue);
136 }
137 return ::KeyedVector(stdKeyedVector);
138}
139
140static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
141 hKeyedVector) {
142 KeyedVector<String8, String8> keyedVector;
143 for (size_t i = 0; i < hKeyedVector.size(); i++) {
144 keyedVector.add(toString8(hKeyedVector[i].key),
145 toString8(hKeyedVector[i].value));
146 }
147 return keyedVector;
148}
149
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800150static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800151 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800152 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800153 for (size_t i = 0; i < hSecureStops.size(); i++) {
154 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
155 }
156 return secureStops;
157}
158
159static status_t toStatusT(Status status) {
160 switch (status) {
161 case Status::OK:
162 return OK;
163 break;
164 case Status::ERROR_DRM_NO_LICENSE:
165 return ERROR_DRM_NO_LICENSE;
166 break;
167 case Status::ERROR_DRM_LICENSE_EXPIRED:
168 return ERROR_DRM_LICENSE_EXPIRED;
169 break;
170 case Status::ERROR_DRM_SESSION_NOT_OPENED:
171 return ERROR_DRM_SESSION_NOT_OPENED;
172 break;
173 case Status::ERROR_DRM_CANNOT_HANDLE:
174 return ERROR_DRM_CANNOT_HANDLE;
175 break;
176 case Status::ERROR_DRM_INVALID_STATE:
177 return ERROR_DRM_TAMPER_DETECTED;
178 break;
179 case Status::BAD_VALUE:
180 return BAD_VALUE;
181 break;
182 case Status::ERROR_DRM_NOT_PROVISIONED:
183 return ERROR_DRM_NOT_PROVISIONED;
184 break;
185 case Status::ERROR_DRM_RESOURCE_BUSY:
186 return ERROR_DRM_RESOURCE_BUSY;
187 break;
188 case Status::ERROR_DRM_DEVICE_REVOKED:
189 return ERROR_DRM_DEVICE_REVOKED;
190 break;
191 case Status::ERROR_DRM_UNKNOWN:
192 default:
193 return ERROR_DRM_UNKNOWN;
194 break;
195 }
196}
197
198
199Mutex DrmHal::mLock;
200
201struct DrmSessionClient : public DrmSessionClientInterface {
202 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
203
204 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
205 sp<DrmHal> drm = mDrm.promote();
206 if (drm == NULL) {
207 return true;
208 }
209 status_t err = drm->closeSession(sessionId);
210 if (err != OK) {
211 return false;
212 }
213 drm->sendEvent(EventType::SESSION_RECLAIMED,
214 toHidlVec(sessionId), hidl_vec<uint8_t>());
215 return true;
216 }
217
218protected:
219 virtual ~DrmSessionClient() {}
220
221private:
222 wp<DrmHal> mDrm;
223
224 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
225};
226
227DrmHal::DrmHal()
228 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800229 mFactories(makeDrmFactories()),
230 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800231}
232
Jeff Tinker61332812017-05-15 16:53:10 -0700233void DrmHal::closeOpenSessions() {
234 if (mPlugin != NULL) {
235 for (size_t i = 0; i < mOpenSessions.size(); i++) {
236 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
237 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
238 }
239 }
240 mOpenSessions.clear();
241}
242
Jeff Tinkera53d6552017-01-20 00:31:46 -0800243DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700244 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800245 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
246}
247
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800248Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
249 Vector<sp<IDrmFactory>> factories;
250
Jeff Tinker593111f2017-05-25 16:00:21 -0700251 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800252
253 if (manager != NULL) {
254 manager->listByInterface(IDrmFactory::descriptor,
255 [&factories](const hidl_vec<hidl_string> &registered) {
256 for (const auto &instance : registered) {
257 auto factory = IDrmFactory::getService(instance);
258 if (factory != NULL) {
259 factories.push_back(factory);
260 ALOGI("makeDrmFactories: factory instance %s is %s",
261 instance.c_str(),
262 factory->isRemote() ? "Remote" : "Not Remote");
263 }
264 }
265 }
266 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800267 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800268
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800269 if (factories.size() == 0) {
270 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700271 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800272 if (passthrough != NULL) {
273 ALOGI("makeDrmFactories: using default drm instance");
274 factories.push_back(passthrough);
275 } else {
276 ALOGE("Failed to find any drm factories");
277 }
278 }
279 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800280}
281
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800282sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
283 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800284
285 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800286 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800287 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800288 if (status != Status::OK) {
289 ALOGE("Failed to make drm plugin");
290 return;
291 }
292 plugin = hPlugin;
293 }
294 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700295
296 if (!hResult.isOk()) {
297 ALOGE("createPlugin remote call failed");
298 }
299
Jeff Tinkera53d6552017-01-20 00:31:46 -0800300 return plugin;
301}
302
303status_t DrmHal::initCheck() const {
304 return mInitCheck;
305}
306
307status_t DrmHal::setListener(const sp<IDrmClient>& listener)
308{
309 Mutex::Autolock lock(mEventLock);
310 if (mListener != NULL){
311 IInterface::asBinder(mListener)->unlinkToDeath(this);
312 }
313 if (listener != NULL) {
314 IInterface::asBinder(listener)->linkToDeath(this);
315 }
316 mListener = listener;
317 return NO_ERROR;
318}
319
320Return<void> DrmHal::sendEvent(EventType hEventType,
321 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
322
323 mEventLock.lock();
324 sp<IDrmClient> listener = mListener;
325 mEventLock.unlock();
326
327 if (listener != NULL) {
328 Parcel obj;
329 writeByteArray(obj, sessionId);
330 writeByteArray(obj, data);
331
332 Mutex::Autolock lock(mNotifyLock);
333 DrmPlugin::EventType eventType;
334 switch(hEventType) {
335 case EventType::PROVISION_REQUIRED:
336 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
337 break;
338 case EventType::KEY_NEEDED:
339 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
340 break;
341 case EventType::KEY_EXPIRED:
342 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
343 break;
344 case EventType::VENDOR_DEFINED:
345 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
346 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700347 case EventType::SESSION_RECLAIMED:
348 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
349 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800350 default:
351 return Void();
352 }
353 listener->notify(eventType, 0, &obj);
354 }
355 return Void();
356}
357
358Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
359 int64_t expiryTimeInMS) {
360
361 mEventLock.lock();
362 sp<IDrmClient> listener = mListener;
363 mEventLock.unlock();
364
365 if (listener != NULL) {
366 Parcel obj;
367 writeByteArray(obj, sessionId);
368 obj.writeInt64(expiryTimeInMS);
369
370 Mutex::Autolock lock(mNotifyLock);
371 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
372 }
373 return Void();
374}
375
376Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
377 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
378
379 mEventLock.lock();
380 sp<IDrmClient> listener = mListener;
381 mEventLock.unlock();
382
383 if (listener != NULL) {
384 Parcel obj;
385 writeByteArray(obj, sessionId);
386
387 size_t nKeys = keyStatusList.size();
388 obj.writeInt32(nKeys);
389 for (size_t i = 0; i < nKeys; ++i) {
390 const KeyStatus &keyStatus = keyStatusList[i];
391 writeByteArray(obj, keyStatus.keyId);
392 uint32_t type;
393 switch(keyStatus.type) {
394 case KeyStatusType::USABLE:
395 type = DrmPlugin::kKeyStatusType_Usable;
396 break;
397 case KeyStatusType::EXPIRED:
398 type = DrmPlugin::kKeyStatusType_Expired;
399 break;
400 case KeyStatusType::OUTPUTNOTALLOWED:
401 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
402 break;
403 case KeyStatusType::STATUSPENDING:
404 type = DrmPlugin::kKeyStatusType_StatusPending;
405 break;
406 case KeyStatusType::INTERNALERROR:
407 default:
408 type = DrmPlugin::kKeyStatusType_InternalError;
409 break;
410 }
411 obj.writeInt32(type);
412 }
413 obj.writeInt32(hasNewUsableKey);
414
415 Mutex::Autolock lock(mNotifyLock);
416 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
417 }
418 return Void();
419}
420
421bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
422 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800423
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800424 for (size_t i = 0; i < mFactories.size(); i++) {
425 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
426 if (mimeType != "") {
427 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
428 return true;
429 }
430 } else {
431 return true;
432 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800433 }
434 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800435 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800436}
437
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800438status_t DrmHal::createPlugin(const uint8_t uuid[16],
439 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800440 Mutex::Autolock autoLock(mLock);
441
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800442 for (size_t i = 0; i < mFactories.size(); i++) {
443 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
444 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800445 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800446 }
447 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800448
449 if (mPlugin == NULL) {
450 mInitCheck = ERROR_UNSUPPORTED;
451 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700452 if (!mPlugin->setListener(this).isOk()) {
453 mInitCheck = DEAD_OBJECT;
454 } else {
455 mInitCheck = OK;
456 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800457 }
458
459 return mInitCheck;
460}
461
462status_t DrmHal::destroyPlugin() {
463 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800464 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800465
Jeff Tinker61332812017-05-15 16:53:10 -0700466 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700467 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800468 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700469 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470
Jeff Tinker319d5f42017-07-26 15:44:33 -0700471 if (mPlugin != NULL) {
472 if (!mPlugin->setListener(NULL).isOk()) {
473 mInitCheck = DEAD_OBJECT;
474 }
475 }
476 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800477 return OK;
478}
479
480status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
481 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800482 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800483
484 status_t err = UNKNOWN_ERROR;
485
486 bool retry = true;
487 do {
488 hidl_vec<uint8_t> hSessionId;
489
490 Return<void> hResult = mPlugin->openSession(
491 [&](Status status, const hidl_vec<uint8_t>& id) {
492 if (status == Status::OK) {
493 sessionId = toVector(id);
494 }
495 err = toStatusT(status);
496 }
497 );
498
499 if (!hResult.isOk()) {
500 err = DEAD_OBJECT;
501 }
502
503 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
504 mLock.unlock();
505 // reclaimSession may call back to closeSession, since mLock is
506 // shared between Drm instances, we should unlock here to avoid
507 // deadlock.
508 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
509 mLock.lock();
510 } else {
511 retry = false;
512 }
513 } while (retry);
514
515 if (err == OK) {
516 DrmSessionManager::Instance()->addSession(getCallingPid(),
517 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700518 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800519 }
520 return err;
521}
522
523status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
524 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800525 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800526
Jeff Tinker319d5f42017-07-26 15:44:33 -0700527 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
528 if (status.isOk()) {
529 if (status == Status::OK) {
530 DrmSessionManager::Instance()->removeSession(sessionId);
531 for (size_t i = 0; i < mOpenSessions.size(); i++) {
532 if (mOpenSessions[i] == sessionId) {
533 mOpenSessions.removeAt(i);
534 break;
535 }
Jeff Tinker61332812017-05-15 16:53:10 -0700536 }
537 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700538 reportMetrics();
539 return toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800540 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700541 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800542}
543
544status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
545 Vector<uint8_t> const &initData, String8 const &mimeType,
546 DrmPlugin::KeyType keyType, KeyedVector<String8,
547 String8> const &optionalParameters, Vector<uint8_t> &request,
548 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
549 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800550 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800551
552 DrmSessionManager::Instance()->useSession(sessionId);
553
554 KeyType hKeyType;
555 if (keyType == DrmPlugin::kKeyType_Streaming) {
556 hKeyType = KeyType::STREAMING;
557 } else if (keyType == DrmPlugin::kKeyType_Offline) {
558 hKeyType = KeyType::OFFLINE;
559 } else if (keyType == DrmPlugin::kKeyType_Release) {
560 hKeyType = KeyType::RELEASE;
561 } else {
562 return BAD_VALUE;
563 }
564
565 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
566
567 status_t err = UNKNOWN_ERROR;
568
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800569 if (mPluginV1_1 != NULL) {
570 Return<void> hResult =
571 mPluginV1_1->getKeyRequest_1_1(
572 toHidlVec(sessionId), toHidlVec(initData),
573 toHidlString(mimeType), hKeyType, hOptionalParameters,
574 [&](Status status, const hidl_vec<uint8_t>& hRequest,
575 drm::V1_1::KeyRequestType hKeyRequestType,
576 const hidl_string& hDefaultUrl) {
577
578 if (status == Status::OK) {
579 request = toVector(hRequest);
580 defaultUrl = toString8(hDefaultUrl);
581
582 switch (hKeyRequestType) {
583 case drm::V1_1::KeyRequestType::INITIAL:
584 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
585 break;
586 case drm::V1_1::KeyRequestType::RENEWAL:
587 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
588 break;
589 case drm::V1_1::KeyRequestType::RELEASE:
590 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
591 break;
592 case drm::V1_1::KeyRequestType::NONE:
593 *keyRequestType = DrmPlugin::kKeyRequestType_None;
594 break;
595 case drm::V1_1::KeyRequestType::UPDATE:
596 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
597 break;
598 default:
599 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
600 break;
601 }
602 err = toStatusT(status);
603 }
604 });
605 return hResult.isOk() ? err : DEAD_OBJECT;
606 }
607
Jeff Tinkera53d6552017-01-20 00:31:46 -0800608 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
609 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
610 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800611 drm::V1_0::KeyRequestType hKeyRequestType,
612 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800613
614 if (status == Status::OK) {
615 request = toVector(hRequest);
616 defaultUrl = toString8(hDefaultUrl);
617
618 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800619 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800620 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
621 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800622 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800623 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
624 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800625 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800626 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
627 break;
628 default:
629 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
630 break;
631 }
632 err = toStatusT(status);
633 }
634 });
635
636 return hResult.isOk() ? err : DEAD_OBJECT;
637}
638
639status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
640 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
641 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800642 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800643
644 DrmSessionManager::Instance()->useSession(sessionId);
645
646 status_t err = UNKNOWN_ERROR;
647
648 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
649 toHidlVec(response),
650 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
651 if (status == Status::OK) {
652 keySetId = toVector(hKeySetId);
653 }
654 err = toStatusT(status);
655 }
656 );
657
658 return hResult.isOk() ? err : DEAD_OBJECT;
659}
660
661status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
662 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800663 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664
665 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
666}
667
668status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
669 Vector<uint8_t> const &keySetId) {
670 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800671 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800672
673 DrmSessionManager::Instance()->useSession(sessionId);
674
675 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
676 toHidlVec(keySetId)));
677}
678
679status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
680 KeyedVector<String8, String8> &infoMap) const {
681 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800682 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800683
684 DrmSessionManager::Instance()->useSession(sessionId);
685
686 ::KeyedVector hInfoMap;
687
688 status_t err = UNKNOWN_ERROR;
689
690 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
691 [&](Status status, const hidl_vec<KeyValue>& map) {
692 if (status == Status::OK) {
693 infoMap = toKeyedVector(map);
694 }
695 err = toStatusT(status);
696 }
697 );
698
699 return hResult.isOk() ? err : DEAD_OBJECT;
700}
701
702status_t DrmHal::getProvisionRequest(String8 const &certType,
703 String8 const &certAuthority, Vector<uint8_t> &request,
704 String8 &defaultUrl) {
705 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800706 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800707
708 status_t err = UNKNOWN_ERROR;
709
710 Return<void> hResult = mPlugin->getProvisionRequest(
711 toHidlString(certType), toHidlString(certAuthority),
712 [&](Status status, const hidl_vec<uint8_t>& hRequest,
713 const hidl_string& hDefaultUrl) {
714 if (status == Status::OK) {
715 request = toVector(hRequest);
716 defaultUrl = toString8(hDefaultUrl);
717 }
718 err = toStatusT(status);
719 }
720 );
721
722 return hResult.isOk() ? err : DEAD_OBJECT;
723}
724
725status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800726 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800727 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800728 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800729
730 status_t err = UNKNOWN_ERROR;
731
732 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
733 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
734 const hidl_vec<uint8_t>& hWrappedKey) {
735 if (status == Status::OK) {
736 certificate = toVector(hCertificate);
737 wrappedKey = toVector(hWrappedKey);
738 }
739 err = toStatusT(status);
740 }
741 );
742
743 return hResult.isOk() ? err : DEAD_OBJECT;
744}
745
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800746status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800747 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800748 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800749
750 status_t err = UNKNOWN_ERROR;
751
752 Return<void> hResult = mPlugin->getSecureStops(
753 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
754 if (status == Status::OK) {
755 secureStops = toSecureStops(hSecureStops);
756 }
757 err = toStatusT(status);
758 }
759 );
760
761 return hResult.isOk() ? err : DEAD_OBJECT;
762}
763
764
765status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
766 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800767 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800768
769 status_t err = UNKNOWN_ERROR;
770
771 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
772 [&](Status status, const SecureStop& hSecureStop) {
773 if (status == Status::OK) {
774 secureStop = toVector(hSecureStop.opaqueData);
775 }
776 err = toStatusT(status);
777 }
778 );
779
780 return hResult.isOk() ? err : DEAD_OBJECT;
781}
782
783status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
784 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800785 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800786
787 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
788}
789
790status_t DrmHal::releaseAllSecureStops() {
791 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800792 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800793
794 return toStatusT(mPlugin->releaseAllSecureStops());
795}
796
Jeff Tinker6d998b62017-12-18 14:37:43 -0800797status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
798 DrmPlugin::HdcpLevel *max) const {
799 Mutex::Autolock autoLock(mLock);
800 INIT_CHECK();
801
802 if (connected == NULL || max == NULL) {
803 return BAD_VALUE;
804 }
805 status_t err = UNKNOWN_ERROR;
806
807 if (mPluginV1_1 == NULL) {
808 return ERROR_DRM_CANNOT_HANDLE;
809 }
810
811 *connected = DrmPlugin::kHdcpLevelUnknown;
812 *max = DrmPlugin::kHdcpLevelUnknown;
813
814 Return<void> hResult = mPluginV1_1->getHdcpLevels(
815 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
816 if (status == Status::OK) {
817 *connected = toHdcpLevel(hConnected);
818 *max = toHdcpLevel(hMax);
819 }
820 err = toStatusT(status);
821 }
822 );
823
824 return hResult.isOk() ? err : DEAD_OBJECT;
825}
826
827status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
828 Mutex::Autolock autoLock(mLock);
829 INIT_CHECK();
830
831 if (open == NULL || max == NULL) {
832 return BAD_VALUE;
833 }
834 status_t err = UNKNOWN_ERROR;
835
836 *open = 0;
837 *max = 0;
838
839 if (mPluginV1_1 == NULL) {
840 return ERROR_DRM_CANNOT_HANDLE;
841 }
842
843 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
844 [&](Status status, uint32_t hOpen, uint32_t hMax) {
845 if (status == Status::OK) {
846 *open = hOpen;
847 *max = hMax;
848 }
849 err = toStatusT(status);
850 }
851 );
852
853 return hResult.isOk() ? err : DEAD_OBJECT;
854}
855
856status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
857 DrmPlugin::SecurityLevel *level) const {
858 Mutex::Autolock autoLock(mLock);
859 INIT_CHECK();
860
861 if (level == NULL) {
862 return BAD_VALUE;
863 }
864 status_t err = UNKNOWN_ERROR;
865
866 if (mPluginV1_1 == NULL) {
867 return ERROR_DRM_CANNOT_HANDLE;
868 }
869
870 *level = DrmPlugin::kSecurityLevelUnknown;
871
872 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
873 [&](Status status, SecurityLevel hLevel) {
874 if (status == Status::OK) {
875 *level = toSecurityLevel(hLevel);
876 }
877 err = toStatusT(status);
878 }
879 );
880
881 return hResult.isOk() ? err : DEAD_OBJECT;
882}
883
884status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
885 const DrmPlugin::SecurityLevel& level) {
886 Mutex::Autolock autoLock(mLock);
887 INIT_CHECK();
888
889 if (mPluginV1_1 == NULL) {
890 return ERROR_DRM_CANNOT_HANDLE;
891 }
892
893 SecurityLevel hSecurityLevel;
894
895 switch(level) {
896 case DrmPlugin::kSecurityLevelSwSecureCrypto:
897 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
898 break;
899 case DrmPlugin::kSecurityLevelSwSecureDecode:
900 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
901 break;
902 case DrmPlugin::kSecurityLevelHwSecureCrypto:
903 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
904 break;
905 case DrmPlugin::kSecurityLevelHwSecureDecode:
906 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
907 break;
908 case DrmPlugin::kSecurityLevelHwSecureAll:
909 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
910 break;
911 default:
912 return ERROR_DRM_CANNOT_HANDLE;
913 }
914
915 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
916 hSecurityLevel);
917 return toStatusT(status);
918}
919
Jeff Tinkera53d6552017-01-20 00:31:46 -0800920status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
921 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700922 return getPropertyStringInternal(name, value);
923}
924
925status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
926 // This function is internal to the class and should only be called while
927 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800928 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800929
930 status_t err = UNKNOWN_ERROR;
931
932 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
933 [&](Status status, const hidl_string& hValue) {
934 if (status == Status::OK) {
935 value = toString8(hValue);
936 }
937 err = toStatusT(status);
938 }
939 );
940
941 return hResult.isOk() ? err : DEAD_OBJECT;
942}
943
944status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
945 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700946 return getPropertyByteArrayInternal(name, value);
947}
948
949status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
950 // This function is internal to the class and should only be called while
951 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800952 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800953
954 status_t err = UNKNOWN_ERROR;
955
956 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
957 [&](Status status, const hidl_vec<uint8_t>& hValue) {
958 if (status == Status::OK) {
959 value = toVector(hValue);
960 }
961 err = toStatusT(status);
962 }
963 );
964
965 return hResult.isOk() ? err : DEAD_OBJECT;
966}
967
968status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
969 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800970 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800971
Jeff Tinker6d998b62017-12-18 14:37:43 -0800972 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800973 toHidlString(value));
974 return toStatusT(status);
975}
976
977status_t DrmHal::setPropertyByteArray(String8 const &name,
978 Vector<uint8_t> const &value ) const {
979 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800980 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800981
982 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
983 toHidlVec(value));
984 return toStatusT(status);
985}
986
Adam Stoneab394d12017-12-22 12:34:20 -0800987status_t DrmHal::getMetrics(MediaAnalyticsItem* metrics) {
988 // TODO: Replace this with real metrics.
989 metrics->setCString("/drm/mediadrm/dummymetric", "dummy");
990 return OK;
991}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800992
993status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
994 String8 const &algorithm) {
995 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800996 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800997
998 DrmSessionManager::Instance()->useSession(sessionId);
999
1000 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1001 toHidlString(algorithm));
1002 return toStatusT(status);
1003}
1004
1005status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1006 String8 const &algorithm) {
1007 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001008 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001009
1010 DrmSessionManager::Instance()->useSession(sessionId);
1011
1012 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1013 toHidlString(algorithm));
1014 return toStatusT(status);
1015}
1016
1017status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001018 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1019 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001020 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001021 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001022
1023 DrmSessionManager::Instance()->useSession(sessionId);
1024
1025 status_t err = UNKNOWN_ERROR;
1026
1027 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1028 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1029 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1030 if (status == Status::OK) {
1031 output = toVector(hOutput);
1032 }
1033 err = toStatusT(status);
1034 }
1035 );
1036
1037 return hResult.isOk() ? err : DEAD_OBJECT;
1038}
1039
1040status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001041 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1042 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001043 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001044 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001045
1046 DrmSessionManager::Instance()->useSession(sessionId);
1047
1048 status_t err = UNKNOWN_ERROR;
1049
1050 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1051 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1052 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1053 if (status == Status::OK) {
1054 output = toVector(hOutput);
1055 }
1056 err = toStatusT(status);
1057 }
1058 );
1059
1060 return hResult.isOk() ? err : DEAD_OBJECT;
1061}
1062
1063status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001064 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1065 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001066 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001067 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001068
1069 DrmSessionManager::Instance()->useSession(sessionId);
1070
1071 status_t err = UNKNOWN_ERROR;
1072
1073 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1074 toHidlVec(keyId), toHidlVec(message),
1075 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1076 if (status == Status::OK) {
1077 signature = toVector(hSignature);
1078 }
1079 err = toStatusT(status);
1080 }
1081 );
1082
1083 return hResult.isOk() ? err : DEAD_OBJECT;
1084}
1085
1086status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001087 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1088 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001089 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001090 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001091
1092 DrmSessionManager::Instance()->useSession(sessionId);
1093
1094 status_t err = UNKNOWN_ERROR;
1095
1096 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1097 toHidlVec(message), toHidlVec(signature),
1098 [&](Status status, bool hMatch) {
1099 if (status == Status::OK) {
1100 match = hMatch;
1101 } else {
1102 match = false;
1103 }
1104 err = toStatusT(status);
1105 }
1106 );
1107
1108 return hResult.isOk() ? err : DEAD_OBJECT;
1109}
1110
1111status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001112 String8 const &algorithm, Vector<uint8_t> const &message,
1113 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001114 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001115 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001116
1117 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1118 return -EPERM;
1119 }
1120
1121 DrmSessionManager::Instance()->useSession(sessionId);
1122
1123 status_t err = UNKNOWN_ERROR;
1124
1125 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1126 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1127 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1128 if (status == Status::OK) {
1129 signature = toVector(hSignature);
1130 }
1131 err = toStatusT(status);
1132 }
1133 );
1134
1135 return hResult.isOk() ? err : DEAD_OBJECT;
1136}
1137
1138void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1139{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001140 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001141 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001142 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001143 mInitCheck = NO_INIT;
1144
Jeff Tinker70367f52017-06-16 12:41:33 -07001145 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001146 if (!mPlugin->setListener(NULL).isOk()) {
1147 mInitCheck = DEAD_OBJECT;
1148 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001149 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001150 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001151}
1152
1153void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1154{
1155 if (vec.size()) {
1156 obj.writeInt32(vec.size());
1157 obj.write(vec.data(), vec.size());
1158 } else {
1159 obj.writeInt32(0);
1160 }
1161}
1162
Adam Stoneab394d12017-12-22 12:34:20 -08001163
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001164void DrmHal::reportMetrics() const
1165{
1166 Vector<uint8_t> metrics;
1167 String8 vendor;
1168 String8 description;
1169 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1170 getPropertyStringInternal(String8("description"), description) == OK &&
1171 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1172 status_t res = android::reportDrmPluginMetrics(
1173 metrics, vendor, description);
1174 if (res != OK) {
1175 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1176 }
1177 }
1178}
1179
Jeff Tinkera53d6552017-01-20 00:31:46 -08001180} // namespace android