blob: ff7ed5864ab3331a57d2c3d362d3b1306a994491 [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>
Adam Stonef0e618d2018-01-17 19:20:41 -080033#include <media/EventMetric.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070034#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080035#include <media/drm/DrmAPI.h>
36#include <media/stagefright/foundation/ADebug.h>
37#include <media/stagefright/foundation/AString.h>
38#include <media/stagefright/foundation/hexdump.h>
39#include <media/stagefright/MediaErrors.h>
40
Jeff Tinker6d998b62017-12-18 14:37:43 -080041using drm::V1_0::KeyedVector;
Jeff Tinker6d998b62017-12-18 14:37:43 -080042using drm::V1_0::KeyStatusType;
43using drm::V1_0::KeyType;
44using drm::V1_0::KeyValue;
45using drm::V1_1::HdcpLevel;;
46using drm::V1_0::SecureStop;
47using drm::V1_1::SecurityLevel;
48using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080049using ::android::hardware::hidl_array;
50using ::android::hardware::hidl_string;
51using ::android::hardware::hidl_vec;
52using ::android::hardware::Return;
53using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080054using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080055using ::android::sp;
56
57namespace android {
58
Jeff Tinker6d998b62017-12-18 14:37:43 -080059#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
60
Jeff Tinkera53d6552017-01-20 00:31:46 -080061static inline int getCallingPid() {
62 return IPCThreadState::self()->getCallingPid();
63}
64
65static bool checkPermission(const char* permissionString) {
66 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
67 bool ok = checkCallingPermission(String16(permissionString));
68 if (!ok) ALOGE("Request requires %s", permissionString);
69 return ok;
70}
71
72static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
73 Vector<uint8_t> vector;
74 vector.appendArray(vec.data(), vec.size());
75 return *const_cast<const Vector<uint8_t> *>(&vector);
76}
77
78static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
79 hidl_vec<uint8_t> vec;
80 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
81 return vec;
82}
83
84static String8 toString8(const hidl_string &string) {
85 return String8(string.c_str());
86}
87
88static hidl_string toHidlString(const String8& string) {
89 return hidl_string(string.string());
90}
91
Jeff Tinker6d998b62017-12-18 14:37:43 -080092static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
93 switch(level) {
94 case SecurityLevel::SW_SECURE_CRYPTO:
95 return DrmPlugin::kSecurityLevelSwSecureCrypto;
96 case SecurityLevel::SW_SECURE_DECODE:
97 return DrmPlugin::kSecurityLevelSwSecureDecode;
98 case SecurityLevel::HW_SECURE_CRYPTO:
99 return DrmPlugin::kSecurityLevelHwSecureCrypto;
100 case SecurityLevel::HW_SECURE_DECODE:
101 return DrmPlugin::kSecurityLevelHwSecureDecode;
102 case SecurityLevel::HW_SECURE_ALL:
103 return DrmPlugin::kSecurityLevelHwSecureAll;
104 default:
105 return DrmPlugin::kSecurityLevelUnknown;
106 }
107}
108
109static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
110 switch(level) {
111 case HdcpLevel::HDCP_NONE:
112 return DrmPlugin::kHdcpNone;
113 case HdcpLevel::HDCP_V1:
114 return DrmPlugin::kHdcpV1;
115 case HdcpLevel::HDCP_V2:
116 return DrmPlugin::kHdcpV2;
117 case HdcpLevel::HDCP_V2_1:
118 return DrmPlugin::kHdcpV2_1;
119 case HdcpLevel::HDCP_V2_2:
120 return DrmPlugin::kHdcpV2_2;
121 case HdcpLevel::HDCP_NO_OUTPUT:
122 return DrmPlugin::kHdcpNoOutput;
123 default:
124 return DrmPlugin::kHdcpLevelUnknown;
125 }
126}
127
Jeff Tinkera53d6552017-01-20 00:31:46 -0800128
129static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
130 keyedVector) {
131 std::vector<KeyValue> stdKeyedVector;
132 for (size_t i = 0; i < keyedVector.size(); i++) {
133 KeyValue keyValue;
134 keyValue.key = toHidlString(keyedVector.keyAt(i));
135 keyValue.value = toHidlString(keyedVector.valueAt(i));
136 stdKeyedVector.push_back(keyValue);
137 }
138 return ::KeyedVector(stdKeyedVector);
139}
140
141static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
142 hKeyedVector) {
143 KeyedVector<String8, String8> keyedVector;
144 for (size_t i = 0; i < hKeyedVector.size(); i++) {
145 keyedVector.add(toString8(hKeyedVector[i].key),
146 toString8(hKeyedVector[i].value));
147 }
148 return keyedVector;
149}
150
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800151static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800152 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800153 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800154 for (size_t i = 0; i < hSecureStops.size(); i++) {
155 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
156 }
157 return secureStops;
158}
159
160static status_t toStatusT(Status status) {
161 switch (status) {
162 case Status::OK:
163 return OK;
164 break;
165 case Status::ERROR_DRM_NO_LICENSE:
166 return ERROR_DRM_NO_LICENSE;
167 break;
168 case Status::ERROR_DRM_LICENSE_EXPIRED:
169 return ERROR_DRM_LICENSE_EXPIRED;
170 break;
171 case Status::ERROR_DRM_SESSION_NOT_OPENED:
172 return ERROR_DRM_SESSION_NOT_OPENED;
173 break;
174 case Status::ERROR_DRM_CANNOT_HANDLE:
175 return ERROR_DRM_CANNOT_HANDLE;
176 break;
177 case Status::ERROR_DRM_INVALID_STATE:
178 return ERROR_DRM_TAMPER_DETECTED;
179 break;
180 case Status::BAD_VALUE:
181 return BAD_VALUE;
182 break;
183 case Status::ERROR_DRM_NOT_PROVISIONED:
184 return ERROR_DRM_NOT_PROVISIONED;
185 break;
186 case Status::ERROR_DRM_RESOURCE_BUSY:
187 return ERROR_DRM_RESOURCE_BUSY;
188 break;
189 case Status::ERROR_DRM_DEVICE_REVOKED:
190 return ERROR_DRM_DEVICE_REVOKED;
191 break;
192 case Status::ERROR_DRM_UNKNOWN:
193 default:
194 return ERROR_DRM_UNKNOWN;
195 break;
196 }
197}
198
199
200Mutex DrmHal::mLock;
201
202struct DrmSessionClient : public DrmSessionClientInterface {
203 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
204
205 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
206 sp<DrmHal> drm = mDrm.promote();
207 if (drm == NULL) {
208 return true;
209 }
210 status_t err = drm->closeSession(sessionId);
211 if (err != OK) {
212 return false;
213 }
214 drm->sendEvent(EventType::SESSION_RECLAIMED,
215 toHidlVec(sessionId), hidl_vec<uint8_t>());
216 return true;
217 }
218
219protected:
220 virtual ~DrmSessionClient() {}
221
222private:
223 wp<DrmHal> mDrm;
224
225 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
226};
227
228DrmHal::DrmHal()
229 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800230 mFactories(makeDrmFactories()),
231 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800232}
233
Jeff Tinker61332812017-05-15 16:53:10 -0700234void DrmHal::closeOpenSessions() {
235 if (mPlugin != NULL) {
236 for (size_t i = 0; i < mOpenSessions.size(); i++) {
237 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
238 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
239 }
240 }
241 mOpenSessions.clear();
242}
243
Jeff Tinkera53d6552017-01-20 00:31:46 -0800244DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700245 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800246 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
247}
248
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800249Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
250 Vector<sp<IDrmFactory>> factories;
251
Jeff Tinker593111f2017-05-25 16:00:21 -0700252 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800253
254 if (manager != NULL) {
255 manager->listByInterface(IDrmFactory::descriptor,
256 [&factories](const hidl_vec<hidl_string> &registered) {
257 for (const auto &instance : registered) {
258 auto factory = IDrmFactory::getService(instance);
259 if (factory != NULL) {
260 factories.push_back(factory);
261 ALOGI("makeDrmFactories: factory instance %s is %s",
262 instance.c_str(),
263 factory->isRemote() ? "Remote" : "Not Remote");
264 }
265 }
266 }
267 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800268 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800269
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800270 if (factories.size() == 0) {
271 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700272 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800273 if (passthrough != NULL) {
274 ALOGI("makeDrmFactories: using default drm instance");
275 factories.push_back(passthrough);
276 } else {
277 ALOGE("Failed to find any drm factories");
278 }
279 }
280 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800281}
282
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800283sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
284 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800285
286 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800287 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800288 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800289 if (status != Status::OK) {
290 ALOGE("Failed to make drm plugin");
291 return;
292 }
293 plugin = hPlugin;
294 }
295 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700296
297 if (!hResult.isOk()) {
298 ALOGE("createPlugin remote call failed");
299 }
300
Jeff Tinkera53d6552017-01-20 00:31:46 -0800301 return plugin;
302}
303
304status_t DrmHal::initCheck() const {
305 return mInitCheck;
306}
307
308status_t DrmHal::setListener(const sp<IDrmClient>& listener)
309{
310 Mutex::Autolock lock(mEventLock);
311 if (mListener != NULL){
312 IInterface::asBinder(mListener)->unlinkToDeath(this);
313 }
314 if (listener != NULL) {
315 IInterface::asBinder(listener)->linkToDeath(this);
316 }
317 mListener = listener;
318 return NO_ERROR;
319}
320
321Return<void> DrmHal::sendEvent(EventType hEventType,
322 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
323
324 mEventLock.lock();
325 sp<IDrmClient> listener = mListener;
326 mEventLock.unlock();
327
328 if (listener != NULL) {
329 Parcel obj;
330 writeByteArray(obj, sessionId);
331 writeByteArray(obj, data);
332
333 Mutex::Autolock lock(mNotifyLock);
334 DrmPlugin::EventType eventType;
335 switch(hEventType) {
336 case EventType::PROVISION_REQUIRED:
337 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
338 break;
339 case EventType::KEY_NEEDED:
340 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
341 break;
342 case EventType::KEY_EXPIRED:
343 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
344 break;
345 case EventType::VENDOR_DEFINED:
346 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
347 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700348 case EventType::SESSION_RECLAIMED:
349 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
350 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800351 default:
352 return Void();
353 }
354 listener->notify(eventType, 0, &obj);
355 }
356 return Void();
357}
358
359Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
360 int64_t expiryTimeInMS) {
361
362 mEventLock.lock();
363 sp<IDrmClient> listener = mListener;
364 mEventLock.unlock();
365
366 if (listener != NULL) {
367 Parcel obj;
368 writeByteArray(obj, sessionId);
369 obj.writeInt64(expiryTimeInMS);
370
371 Mutex::Autolock lock(mNotifyLock);
372 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
373 }
374 return Void();
375}
376
377Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
378 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
379
380 mEventLock.lock();
381 sp<IDrmClient> listener = mListener;
382 mEventLock.unlock();
383
384 if (listener != NULL) {
385 Parcel obj;
386 writeByteArray(obj, sessionId);
387
388 size_t nKeys = keyStatusList.size();
389 obj.writeInt32(nKeys);
390 for (size_t i = 0; i < nKeys; ++i) {
391 const KeyStatus &keyStatus = keyStatusList[i];
392 writeByteArray(obj, keyStatus.keyId);
393 uint32_t type;
394 switch(keyStatus.type) {
395 case KeyStatusType::USABLE:
396 type = DrmPlugin::kKeyStatusType_Usable;
397 break;
398 case KeyStatusType::EXPIRED:
399 type = DrmPlugin::kKeyStatusType_Expired;
400 break;
401 case KeyStatusType::OUTPUTNOTALLOWED:
402 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
403 break;
404 case KeyStatusType::STATUSPENDING:
405 type = DrmPlugin::kKeyStatusType_StatusPending;
406 break;
407 case KeyStatusType::INTERNALERROR:
408 default:
409 type = DrmPlugin::kKeyStatusType_InternalError;
410 break;
411 }
412 obj.writeInt32(type);
413 }
414 obj.writeInt32(hasNewUsableKey);
415
416 Mutex::Autolock lock(mNotifyLock);
417 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
418 }
419 return Void();
420}
421
422bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
423 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800425 for (size_t i = 0; i < mFactories.size(); i++) {
426 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
427 if (mimeType != "") {
428 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
429 return true;
430 }
431 } else {
432 return true;
433 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800434 }
435 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800436 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437}
438
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800439status_t DrmHal::createPlugin(const uint8_t uuid[16],
440 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800441 Mutex::Autolock autoLock(mLock);
442
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800443 for (size_t i = 0; i < mFactories.size(); i++) {
444 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
445 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800446 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800447 }
448 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800449
450 if (mPlugin == NULL) {
451 mInitCheck = ERROR_UNSUPPORTED;
452 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700453 if (!mPlugin->setListener(this).isOk()) {
454 mInitCheck = DEAD_OBJECT;
455 } else {
456 mInitCheck = OK;
457 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800458 }
459
460 return mInitCheck;
461}
462
463status_t DrmHal::destroyPlugin() {
464 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800465 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800466
Jeff Tinker61332812017-05-15 16:53:10 -0700467 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700468 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800469 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700470 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800471
Jeff Tinker319d5f42017-07-26 15:44:33 -0700472 if (mPlugin != NULL) {
473 if (!mPlugin->setListener(NULL).isOk()) {
474 mInitCheck = DEAD_OBJECT;
475 }
476 }
477 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800478 return OK;
479}
480
481status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
482 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800483 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800484
485 status_t err = UNKNOWN_ERROR;
486
487 bool retry = true;
488 do {
489 hidl_vec<uint8_t> hSessionId;
490
491 Return<void> hResult = mPlugin->openSession(
492 [&](Status status, const hidl_vec<uint8_t>& id) {
493 if (status == Status::OK) {
494 sessionId = toVector(id);
495 }
496 err = toStatusT(status);
497 }
498 );
499
500 if (!hResult.isOk()) {
501 err = DEAD_OBJECT;
502 }
503
504 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
505 mLock.unlock();
506 // reclaimSession may call back to closeSession, since mLock is
507 // shared between Drm instances, we should unlock here to avoid
508 // deadlock.
509 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
510 mLock.lock();
511 } else {
512 retry = false;
513 }
514 } while (retry);
515
516 if (err == OK) {
517 DrmSessionManager::Instance()->addSession(getCallingPid(),
518 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700519 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800520 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800521
Adam Stonef0e618d2018-01-17 19:20:41 -0800522 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800523 return err;
524}
525
526status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
527 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800528 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800529
Jeff Tinker319d5f42017-07-26 15:44:33 -0700530 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
531 if (status.isOk()) {
532 if (status == Status::OK) {
533 DrmSessionManager::Instance()->removeSession(sessionId);
534 for (size_t i = 0; i < mOpenSessions.size(); i++) {
535 if (mOpenSessions[i] == sessionId) {
536 mOpenSessions.removeAt(i);
537 break;
538 }
Jeff Tinker61332812017-05-15 16:53:10 -0700539 }
540 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700541 reportMetrics();
542 return toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800543 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700544 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800545}
546
547status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
548 Vector<uint8_t> const &initData, String8 const &mimeType,
549 DrmPlugin::KeyType keyType, KeyedVector<String8,
550 String8> const &optionalParameters, Vector<uint8_t> &request,
551 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
552 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800553 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800554 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800555
556 DrmSessionManager::Instance()->useSession(sessionId);
557
558 KeyType hKeyType;
559 if (keyType == DrmPlugin::kKeyType_Streaming) {
560 hKeyType = KeyType::STREAMING;
561 } else if (keyType == DrmPlugin::kKeyType_Offline) {
562 hKeyType = KeyType::OFFLINE;
563 } else if (keyType == DrmPlugin::kKeyType_Release) {
564 hKeyType = KeyType::RELEASE;
565 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800566 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800567 return BAD_VALUE;
568 }
569
570 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
571
572 status_t err = UNKNOWN_ERROR;
573
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800574 if (mPluginV1_1 != NULL) {
575 Return<void> hResult =
576 mPluginV1_1->getKeyRequest_1_1(
577 toHidlVec(sessionId), toHidlVec(initData),
578 toHidlString(mimeType), hKeyType, hOptionalParameters,
579 [&](Status status, const hidl_vec<uint8_t>& hRequest,
580 drm::V1_1::KeyRequestType hKeyRequestType,
581 const hidl_string& hDefaultUrl) {
582
583 if (status == Status::OK) {
584 request = toVector(hRequest);
585 defaultUrl = toString8(hDefaultUrl);
586
587 switch (hKeyRequestType) {
588 case drm::V1_1::KeyRequestType::INITIAL:
589 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
590 break;
591 case drm::V1_1::KeyRequestType::RENEWAL:
592 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
593 break;
594 case drm::V1_1::KeyRequestType::RELEASE:
595 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
596 break;
597 case drm::V1_1::KeyRequestType::NONE:
598 *keyRequestType = DrmPlugin::kKeyRequestType_None;
599 break;
600 case drm::V1_1::KeyRequestType::UPDATE:
601 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
602 break;
603 default:
604 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
605 break;
606 }
607 err = toStatusT(status);
608 }
609 });
610 return hResult.isOk() ? err : DEAD_OBJECT;
611 }
612
Jeff Tinkera53d6552017-01-20 00:31:46 -0800613 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
614 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
615 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800616 drm::V1_0::KeyRequestType hKeyRequestType,
617 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800618
619 if (status == Status::OK) {
620 request = toVector(hRequest);
621 defaultUrl = toString8(hDefaultUrl);
622
623 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800624 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800625 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
626 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800627 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800628 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
629 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800630 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800631 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
632 break;
633 default:
634 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
635 break;
636 }
637 err = toStatusT(status);
638 }
639 });
640
Adam Stonef0e618d2018-01-17 19:20:41 -0800641 err = hResult.isOk() ? err : DEAD_OBJECT;
642 keyRequestTimer.SetAttribute(err);
643 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800644}
645
646status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
647 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
648 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800649 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800650
651 DrmSessionManager::Instance()->useSession(sessionId);
652
653 status_t err = UNKNOWN_ERROR;
654
655 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
656 toHidlVec(response),
657 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
658 if (status == Status::OK) {
659 keySetId = toVector(hKeySetId);
660 }
661 err = toStatusT(status);
662 }
663 );
664
665 return hResult.isOk() ? err : DEAD_OBJECT;
666}
667
668status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
669 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800670 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800671
672 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
673}
674
675status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
676 Vector<uint8_t> const &keySetId) {
677 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800678 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800679
680 DrmSessionManager::Instance()->useSession(sessionId);
681
682 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
683 toHidlVec(keySetId)));
684}
685
686status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
687 KeyedVector<String8, String8> &infoMap) const {
688 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800689 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800690
691 DrmSessionManager::Instance()->useSession(sessionId);
692
693 ::KeyedVector hInfoMap;
694
695 status_t err = UNKNOWN_ERROR;
696
697 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
698 [&](Status status, const hidl_vec<KeyValue>& map) {
699 if (status == Status::OK) {
700 infoMap = toKeyedVector(map);
701 }
702 err = toStatusT(status);
703 }
704 );
705
706 return hResult.isOk() ? err : DEAD_OBJECT;
707}
708
709status_t DrmHal::getProvisionRequest(String8 const &certType,
710 String8 const &certAuthority, Vector<uint8_t> &request,
711 String8 &defaultUrl) {
712 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800713 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800714
715 status_t err = UNKNOWN_ERROR;
716
717 Return<void> hResult = mPlugin->getProvisionRequest(
718 toHidlString(certType), toHidlString(certAuthority),
719 [&](Status status, const hidl_vec<uint8_t>& hRequest,
720 const hidl_string& hDefaultUrl) {
721 if (status == Status::OK) {
722 request = toVector(hRequest);
723 defaultUrl = toString8(hDefaultUrl);
724 }
725 err = toStatusT(status);
726 }
727 );
728
729 return hResult.isOk() ? err : DEAD_OBJECT;
730}
731
732status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800733 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800734 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800735 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800736
737 status_t err = UNKNOWN_ERROR;
738
739 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
740 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
741 const hidl_vec<uint8_t>& hWrappedKey) {
742 if (status == Status::OK) {
743 certificate = toVector(hCertificate);
744 wrappedKey = toVector(hWrappedKey);
745 }
746 err = toStatusT(status);
747 }
748 );
749
750 return hResult.isOk() ? err : DEAD_OBJECT;
751}
752
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800753status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800754 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800755 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800756
757 status_t err = UNKNOWN_ERROR;
758
759 Return<void> hResult = mPlugin->getSecureStops(
760 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
761 if (status == Status::OK) {
762 secureStops = toSecureStops(hSecureStops);
763 }
764 err = toStatusT(status);
765 }
766 );
767
768 return hResult.isOk() ? err : DEAD_OBJECT;
769}
770
771
772status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
773 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800774 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800775
776 status_t err = UNKNOWN_ERROR;
777
778 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
779 [&](Status status, const SecureStop& hSecureStop) {
780 if (status == Status::OK) {
781 secureStop = toVector(hSecureStop.opaqueData);
782 }
783 err = toStatusT(status);
784 }
785 );
786
787 return hResult.isOk() ? err : DEAD_OBJECT;
788}
789
790status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
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->releaseSecureStop(toHidlVec(ssRelease)));
795}
796
797status_t DrmHal::releaseAllSecureStops() {
798 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800799 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800800
801 return toStatusT(mPlugin->releaseAllSecureStops());
802}
803
Jeff Tinker6d998b62017-12-18 14:37:43 -0800804status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
805 DrmPlugin::HdcpLevel *max) const {
806 Mutex::Autolock autoLock(mLock);
807 INIT_CHECK();
808
809 if (connected == NULL || max == NULL) {
810 return BAD_VALUE;
811 }
812 status_t err = UNKNOWN_ERROR;
813
814 if (mPluginV1_1 == NULL) {
815 return ERROR_DRM_CANNOT_HANDLE;
816 }
817
818 *connected = DrmPlugin::kHdcpLevelUnknown;
819 *max = DrmPlugin::kHdcpLevelUnknown;
820
821 Return<void> hResult = mPluginV1_1->getHdcpLevels(
822 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
823 if (status == Status::OK) {
824 *connected = toHdcpLevel(hConnected);
825 *max = toHdcpLevel(hMax);
826 }
827 err = toStatusT(status);
828 }
829 );
830
831 return hResult.isOk() ? err : DEAD_OBJECT;
832}
833
834status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
835 Mutex::Autolock autoLock(mLock);
836 INIT_CHECK();
837
838 if (open == NULL || max == NULL) {
839 return BAD_VALUE;
840 }
841 status_t err = UNKNOWN_ERROR;
842
843 *open = 0;
844 *max = 0;
845
846 if (mPluginV1_1 == NULL) {
847 return ERROR_DRM_CANNOT_HANDLE;
848 }
849
850 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
851 [&](Status status, uint32_t hOpen, uint32_t hMax) {
852 if (status == Status::OK) {
853 *open = hOpen;
854 *max = hMax;
855 }
856 err = toStatusT(status);
857 }
858 );
859
860 return hResult.isOk() ? err : DEAD_OBJECT;
861}
862
863status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
864 DrmPlugin::SecurityLevel *level) const {
865 Mutex::Autolock autoLock(mLock);
866 INIT_CHECK();
867
868 if (level == NULL) {
869 return BAD_VALUE;
870 }
871 status_t err = UNKNOWN_ERROR;
872
873 if (mPluginV1_1 == NULL) {
874 return ERROR_DRM_CANNOT_HANDLE;
875 }
876
877 *level = DrmPlugin::kSecurityLevelUnknown;
878
879 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
880 [&](Status status, SecurityLevel hLevel) {
881 if (status == Status::OK) {
882 *level = toSecurityLevel(hLevel);
883 }
884 err = toStatusT(status);
885 }
886 );
887
888 return hResult.isOk() ? err : DEAD_OBJECT;
889}
890
891status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
892 const DrmPlugin::SecurityLevel& level) {
893 Mutex::Autolock autoLock(mLock);
894 INIT_CHECK();
895
896 if (mPluginV1_1 == NULL) {
897 return ERROR_DRM_CANNOT_HANDLE;
898 }
899
900 SecurityLevel hSecurityLevel;
901
902 switch(level) {
903 case DrmPlugin::kSecurityLevelSwSecureCrypto:
904 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
905 break;
906 case DrmPlugin::kSecurityLevelSwSecureDecode:
907 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
908 break;
909 case DrmPlugin::kSecurityLevelHwSecureCrypto:
910 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
911 break;
912 case DrmPlugin::kSecurityLevelHwSecureDecode:
913 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
914 break;
915 case DrmPlugin::kSecurityLevelHwSecureAll:
916 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
917 break;
918 default:
919 return ERROR_DRM_CANNOT_HANDLE;
920 }
921
922 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
923 hSecurityLevel);
924 return toStatusT(status);
925}
926
Jeff Tinkera53d6552017-01-20 00:31:46 -0800927status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
928 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700929 return getPropertyStringInternal(name, value);
930}
931
932status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
933 // This function is internal to the class and should only be called while
934 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800935 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800936
937 status_t err = UNKNOWN_ERROR;
938
939 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
940 [&](Status status, const hidl_string& hValue) {
941 if (status == Status::OK) {
942 value = toString8(hValue);
943 }
944 err = toStatusT(status);
945 }
946 );
947
948 return hResult.isOk() ? err : DEAD_OBJECT;
949}
950
951status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
952 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700953 return getPropertyByteArrayInternal(name, value);
954}
955
956status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
957 // This function is internal to the class and should only be called while
958 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800959 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800960
961 status_t err = UNKNOWN_ERROR;
962
963 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
964 [&](Status status, const hidl_vec<uint8_t>& hValue) {
965 if (status == Status::OK) {
966 value = toVector(hValue);
967 }
968 err = toStatusT(status);
969 }
970 );
971
972 return hResult.isOk() ? err : DEAD_OBJECT;
973}
974
975status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
976 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800977 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800978
Jeff Tinker6d998b62017-12-18 14:37:43 -0800979 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800980 toHidlString(value));
981 return toStatusT(status);
982}
983
984status_t DrmHal::setPropertyByteArray(String8 const &name,
985 Vector<uint8_t> const &value ) const {
986 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800987 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800988
989 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
990 toHidlVec(value));
991 return toStatusT(status);
992}
993
Adam Stonef0e618d2018-01-17 19:20:41 -0800994status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
995 if (item == nullptr) {
996 return UNEXPECTED_NULL;
997 }
998
999 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001000 return OK;
1001}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001002
1003status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1004 String8 const &algorithm) {
1005 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001006 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001007
1008 DrmSessionManager::Instance()->useSession(sessionId);
1009
1010 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1011 toHidlString(algorithm));
1012 return toStatusT(status);
1013}
1014
1015status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1016 String8 const &algorithm) {
1017 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001018 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001019
1020 DrmSessionManager::Instance()->useSession(sessionId);
1021
1022 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1023 toHidlString(algorithm));
1024 return toStatusT(status);
1025}
1026
1027status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001028 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1029 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001030 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001031 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001032
1033 DrmSessionManager::Instance()->useSession(sessionId);
1034
1035 status_t err = UNKNOWN_ERROR;
1036
1037 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1038 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1039 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1040 if (status == Status::OK) {
1041 output = toVector(hOutput);
1042 }
1043 err = toStatusT(status);
1044 }
1045 );
1046
1047 return hResult.isOk() ? err : DEAD_OBJECT;
1048}
1049
1050status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001051 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1052 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001053 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001054 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001055
1056 DrmSessionManager::Instance()->useSession(sessionId);
1057
1058 status_t err = UNKNOWN_ERROR;
1059
1060 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1061 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1062 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1063 if (status == Status::OK) {
1064 output = toVector(hOutput);
1065 }
1066 err = toStatusT(status);
1067 }
1068 );
1069
1070 return hResult.isOk() ? err : DEAD_OBJECT;
1071}
1072
1073status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001074 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1075 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001076 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001077 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001078
1079 DrmSessionManager::Instance()->useSession(sessionId);
1080
1081 status_t err = UNKNOWN_ERROR;
1082
1083 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1084 toHidlVec(keyId), toHidlVec(message),
1085 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1086 if (status == Status::OK) {
1087 signature = toVector(hSignature);
1088 }
1089 err = toStatusT(status);
1090 }
1091 );
1092
1093 return hResult.isOk() ? err : DEAD_OBJECT;
1094}
1095
1096status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001097 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1098 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001099 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001100 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001101
1102 DrmSessionManager::Instance()->useSession(sessionId);
1103
1104 status_t err = UNKNOWN_ERROR;
1105
1106 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1107 toHidlVec(message), toHidlVec(signature),
1108 [&](Status status, bool hMatch) {
1109 if (status == Status::OK) {
1110 match = hMatch;
1111 } else {
1112 match = false;
1113 }
1114 err = toStatusT(status);
1115 }
1116 );
1117
1118 return hResult.isOk() ? err : DEAD_OBJECT;
1119}
1120
1121status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001122 String8 const &algorithm, Vector<uint8_t> const &message,
1123 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001124 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001125 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001126
1127 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1128 return -EPERM;
1129 }
1130
1131 DrmSessionManager::Instance()->useSession(sessionId);
1132
1133 status_t err = UNKNOWN_ERROR;
1134
1135 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1136 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1137 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1138 if (status == Status::OK) {
1139 signature = toVector(hSignature);
1140 }
1141 err = toStatusT(status);
1142 }
1143 );
1144
1145 return hResult.isOk() ? err : DEAD_OBJECT;
1146}
1147
1148void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1149{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001150 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001151 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001152 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001153 mInitCheck = NO_INIT;
1154
Jeff Tinker70367f52017-06-16 12:41:33 -07001155 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001156 if (!mPlugin->setListener(NULL).isOk()) {
1157 mInitCheck = DEAD_OBJECT;
1158 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001159 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001160 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001161}
1162
1163void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1164{
1165 if (vec.size()) {
1166 obj.writeInt32(vec.size());
1167 obj.write(vec.data(), vec.size());
1168 } else {
1169 obj.writeInt32(0);
1170 }
1171}
1172
Adam Stoneab394d12017-12-22 12:34:20 -08001173
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001174void DrmHal::reportMetrics() const
1175{
1176 Vector<uint8_t> metrics;
1177 String8 vendor;
1178 String8 description;
1179 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1180 getPropertyStringInternal(String8("description"), description) == OK &&
1181 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1182 status_t res = android::reportDrmPluginMetrics(
1183 metrics, vendor, description);
1184 if (res != OK) {
1185 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1186 }
1187 }
1188}
1189
Jeff Tinkera53d6552017-01-20 00:31:46 -08001190} // namespace android