blob: f2e9df702243a6372979e14d84466309a5088f27 [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
Adam Stonecea91ce2018-01-22 19:23:28 -080057namespace {
58
59// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
60// in the MediaDrm API.
61constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
62
63}
64
Jeff Tinkera53d6552017-01-20 00:31:46 -080065namespace android {
66
Jeff Tinker6d998b62017-12-18 14:37:43 -080067#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
68
Jeff Tinkera53d6552017-01-20 00:31:46 -080069static inline int getCallingPid() {
70 return IPCThreadState::self()->getCallingPid();
71}
72
73static bool checkPermission(const char* permissionString) {
74 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
75 bool ok = checkCallingPermission(String16(permissionString));
76 if (!ok) ALOGE("Request requires %s", permissionString);
77 return ok;
78}
79
80static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
81 Vector<uint8_t> vector;
82 vector.appendArray(vec.data(), vec.size());
83 return *const_cast<const Vector<uint8_t> *>(&vector);
84}
85
86static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
87 hidl_vec<uint8_t> vec;
88 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
89 return vec;
90}
91
92static String8 toString8(const hidl_string &string) {
93 return String8(string.c_str());
94}
95
96static hidl_string toHidlString(const String8& string) {
97 return hidl_string(string.string());
98}
99
Jeff Tinker6d998b62017-12-18 14:37:43 -0800100static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
101 switch(level) {
102 case SecurityLevel::SW_SECURE_CRYPTO:
103 return DrmPlugin::kSecurityLevelSwSecureCrypto;
104 case SecurityLevel::SW_SECURE_DECODE:
105 return DrmPlugin::kSecurityLevelSwSecureDecode;
106 case SecurityLevel::HW_SECURE_CRYPTO:
107 return DrmPlugin::kSecurityLevelHwSecureCrypto;
108 case SecurityLevel::HW_SECURE_DECODE:
109 return DrmPlugin::kSecurityLevelHwSecureDecode;
110 case SecurityLevel::HW_SECURE_ALL:
111 return DrmPlugin::kSecurityLevelHwSecureAll;
112 default:
113 return DrmPlugin::kSecurityLevelUnknown;
114 }
115}
116
117static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
118 switch(level) {
119 case HdcpLevel::HDCP_NONE:
120 return DrmPlugin::kHdcpNone;
121 case HdcpLevel::HDCP_V1:
122 return DrmPlugin::kHdcpV1;
123 case HdcpLevel::HDCP_V2:
124 return DrmPlugin::kHdcpV2;
125 case HdcpLevel::HDCP_V2_1:
126 return DrmPlugin::kHdcpV2_1;
127 case HdcpLevel::HDCP_V2_2:
128 return DrmPlugin::kHdcpV2_2;
129 case HdcpLevel::HDCP_NO_OUTPUT:
130 return DrmPlugin::kHdcpNoOutput;
131 default:
132 return DrmPlugin::kHdcpLevelUnknown;
133 }
134}
135
Jeff Tinkera53d6552017-01-20 00:31:46 -0800136
137static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
138 keyedVector) {
139 std::vector<KeyValue> stdKeyedVector;
140 for (size_t i = 0; i < keyedVector.size(); i++) {
141 KeyValue keyValue;
142 keyValue.key = toHidlString(keyedVector.keyAt(i));
143 keyValue.value = toHidlString(keyedVector.valueAt(i));
144 stdKeyedVector.push_back(keyValue);
145 }
146 return ::KeyedVector(stdKeyedVector);
147}
148
149static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
150 hKeyedVector) {
151 KeyedVector<String8, String8> keyedVector;
152 for (size_t i = 0; i < hKeyedVector.size(); i++) {
153 keyedVector.add(toString8(hKeyedVector[i].key),
154 toString8(hKeyedVector[i].value));
155 }
156 return keyedVector;
157}
158
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800159static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800160 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800161 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800162 for (size_t i = 0; i < hSecureStops.size(); i++) {
163 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
164 }
165 return secureStops;
166}
167
168static status_t toStatusT(Status status) {
169 switch (status) {
170 case Status::OK:
171 return OK;
172 break;
173 case Status::ERROR_DRM_NO_LICENSE:
174 return ERROR_DRM_NO_LICENSE;
175 break;
176 case Status::ERROR_DRM_LICENSE_EXPIRED:
177 return ERROR_DRM_LICENSE_EXPIRED;
178 break;
179 case Status::ERROR_DRM_SESSION_NOT_OPENED:
180 return ERROR_DRM_SESSION_NOT_OPENED;
181 break;
182 case Status::ERROR_DRM_CANNOT_HANDLE:
183 return ERROR_DRM_CANNOT_HANDLE;
184 break;
185 case Status::ERROR_DRM_INVALID_STATE:
186 return ERROR_DRM_TAMPER_DETECTED;
187 break;
188 case Status::BAD_VALUE:
189 return BAD_VALUE;
190 break;
191 case Status::ERROR_DRM_NOT_PROVISIONED:
192 return ERROR_DRM_NOT_PROVISIONED;
193 break;
194 case Status::ERROR_DRM_RESOURCE_BUSY:
195 return ERROR_DRM_RESOURCE_BUSY;
196 break;
197 case Status::ERROR_DRM_DEVICE_REVOKED:
198 return ERROR_DRM_DEVICE_REVOKED;
199 break;
200 case Status::ERROR_DRM_UNKNOWN:
201 default:
202 return ERROR_DRM_UNKNOWN;
203 break;
204 }
205}
206
207
208Mutex DrmHal::mLock;
209
210struct DrmSessionClient : public DrmSessionClientInterface {
211 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
212
213 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
214 sp<DrmHal> drm = mDrm.promote();
215 if (drm == NULL) {
216 return true;
217 }
218 status_t err = drm->closeSession(sessionId);
219 if (err != OK) {
220 return false;
221 }
222 drm->sendEvent(EventType::SESSION_RECLAIMED,
223 toHidlVec(sessionId), hidl_vec<uint8_t>());
224 return true;
225 }
226
227protected:
228 virtual ~DrmSessionClient() {}
229
230private:
231 wp<DrmHal> mDrm;
232
233 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
234};
235
236DrmHal::DrmHal()
237 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800238 mFactories(makeDrmFactories()),
239 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800240}
241
Jeff Tinker61332812017-05-15 16:53:10 -0700242void DrmHal::closeOpenSessions() {
243 if (mPlugin != NULL) {
244 for (size_t i = 0; i < mOpenSessions.size(); i++) {
245 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
246 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
247 }
248 }
249 mOpenSessions.clear();
250}
251
Jeff Tinkera53d6552017-01-20 00:31:46 -0800252DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700253 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800254 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
255}
256
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800257Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
258 Vector<sp<IDrmFactory>> factories;
259
Jeff Tinker593111f2017-05-25 16:00:21 -0700260 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800261
262 if (manager != NULL) {
263 manager->listByInterface(IDrmFactory::descriptor,
264 [&factories](const hidl_vec<hidl_string> &registered) {
265 for (const auto &instance : registered) {
266 auto factory = IDrmFactory::getService(instance);
267 if (factory != NULL) {
268 factories.push_back(factory);
269 ALOGI("makeDrmFactories: factory instance %s is %s",
270 instance.c_str(),
271 factory->isRemote() ? "Remote" : "Not Remote");
272 }
273 }
274 }
275 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800276 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800277
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800278 if (factories.size() == 0) {
279 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700280 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800281 if (passthrough != NULL) {
282 ALOGI("makeDrmFactories: using default drm instance");
283 factories.push_back(passthrough);
284 } else {
285 ALOGE("Failed to find any drm factories");
286 }
287 }
288 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800289}
290
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800291sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
292 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800293
294 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800295 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800296 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800297 if (status != Status::OK) {
298 ALOGE("Failed to make drm plugin");
299 return;
300 }
301 plugin = hPlugin;
302 }
303 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700304
305 if (!hResult.isOk()) {
306 ALOGE("createPlugin remote call failed");
307 }
308
Jeff Tinkera53d6552017-01-20 00:31:46 -0800309 return plugin;
310}
311
312status_t DrmHal::initCheck() const {
313 return mInitCheck;
314}
315
316status_t DrmHal::setListener(const sp<IDrmClient>& listener)
317{
318 Mutex::Autolock lock(mEventLock);
319 if (mListener != NULL){
320 IInterface::asBinder(mListener)->unlinkToDeath(this);
321 }
322 if (listener != NULL) {
323 IInterface::asBinder(listener)->linkToDeath(this);
324 }
325 mListener = listener;
326 return NO_ERROR;
327}
328
329Return<void> DrmHal::sendEvent(EventType hEventType,
330 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800331 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800332
333 mEventLock.lock();
334 sp<IDrmClient> listener = mListener;
335 mEventLock.unlock();
336
337 if (listener != NULL) {
338 Parcel obj;
339 writeByteArray(obj, sessionId);
340 writeByteArray(obj, data);
341
342 Mutex::Autolock lock(mNotifyLock);
343 DrmPlugin::EventType eventType;
344 switch(hEventType) {
345 case EventType::PROVISION_REQUIRED:
346 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
347 break;
348 case EventType::KEY_NEEDED:
349 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
350 break;
351 case EventType::KEY_EXPIRED:
352 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
353 break;
354 case EventType::VENDOR_DEFINED:
355 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
356 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700357 case EventType::SESSION_RECLAIMED:
358 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
359 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800360 default:
361 return Void();
362 }
363 listener->notify(eventType, 0, &obj);
364 }
365 return Void();
366}
367
368Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
369 int64_t expiryTimeInMS) {
370
371 mEventLock.lock();
372 sp<IDrmClient> listener = mListener;
373 mEventLock.unlock();
374
375 if (listener != NULL) {
376 Parcel obj;
377 writeByteArray(obj, sessionId);
378 obj.writeInt64(expiryTimeInMS);
379
380 Mutex::Autolock lock(mNotifyLock);
381 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
382 }
383 return Void();
384}
385
386Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
387 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
388
389 mEventLock.lock();
390 sp<IDrmClient> listener = mListener;
391 mEventLock.unlock();
392
393 if (listener != NULL) {
394 Parcel obj;
395 writeByteArray(obj, sessionId);
396
397 size_t nKeys = keyStatusList.size();
398 obj.writeInt32(nKeys);
399 for (size_t i = 0; i < nKeys; ++i) {
400 const KeyStatus &keyStatus = keyStatusList[i];
401 writeByteArray(obj, keyStatus.keyId);
402 uint32_t type;
403 switch(keyStatus.type) {
404 case KeyStatusType::USABLE:
405 type = DrmPlugin::kKeyStatusType_Usable;
406 break;
407 case KeyStatusType::EXPIRED:
408 type = DrmPlugin::kKeyStatusType_Expired;
409 break;
410 case KeyStatusType::OUTPUTNOTALLOWED:
411 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
412 break;
413 case KeyStatusType::STATUSPENDING:
414 type = DrmPlugin::kKeyStatusType_StatusPending;
415 break;
416 case KeyStatusType::INTERNALERROR:
417 default:
418 type = DrmPlugin::kKeyStatusType_InternalError;
419 break;
420 }
421 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800422 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800423 }
424 obj.writeInt32(hasNewUsableKey);
425
426 Mutex::Autolock lock(mNotifyLock);
427 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800428 } else {
429 // There's no listener. But we still want to count the key change
430 // events.
431 size_t nKeys = keyStatusList.size();
432 for (size_t i = 0; i < nKeys; i++) {
433 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
434 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800435 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800436
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437 return Void();
438}
439
440bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
441 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800442
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800443 for (size_t i = 0; i < mFactories.size(); i++) {
444 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
445 if (mimeType != "") {
446 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
447 return true;
448 }
449 } else {
450 return true;
451 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800452 }
453 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800454 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800455}
456
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800457status_t DrmHal::createPlugin(const uint8_t uuid[16],
458 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800459 Mutex::Autolock autoLock(mLock);
460
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800461 for (size_t i = 0; i < mFactories.size(); i++) {
462 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
463 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800464 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800465 }
466 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800467
468 if (mPlugin == NULL) {
469 mInitCheck = ERROR_UNSUPPORTED;
470 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700471 if (!mPlugin->setListener(this).isOk()) {
472 mInitCheck = DEAD_OBJECT;
473 } else {
474 mInitCheck = OK;
475 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800476 }
477
478 return mInitCheck;
479}
480
481status_t DrmHal::destroyPlugin() {
482 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800483 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800484
Jeff Tinker61332812017-05-15 16:53:10 -0700485 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700486 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800487 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700488 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800489
Jeff Tinker319d5f42017-07-26 15:44:33 -0700490 if (mPlugin != NULL) {
491 if (!mPlugin->setListener(NULL).isOk()) {
492 mInitCheck = DEAD_OBJECT;
493 }
494 }
495 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800496 return OK;
497}
498
499status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
500 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800501 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800502
503 status_t err = UNKNOWN_ERROR;
504
505 bool retry = true;
506 do {
507 hidl_vec<uint8_t> hSessionId;
508
509 Return<void> hResult = mPlugin->openSession(
510 [&](Status status, const hidl_vec<uint8_t>& id) {
511 if (status == Status::OK) {
512 sessionId = toVector(id);
513 }
514 err = toStatusT(status);
515 }
516 );
517
518 if (!hResult.isOk()) {
519 err = DEAD_OBJECT;
520 }
521
522 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
523 mLock.unlock();
524 // reclaimSession may call back to closeSession, since mLock is
525 // shared between Drm instances, we should unlock here to avoid
526 // deadlock.
527 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
528 mLock.lock();
529 } else {
530 retry = false;
531 }
532 } while (retry);
533
534 if (err == OK) {
535 DrmSessionManager::Instance()->addSession(getCallingPid(),
536 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700537 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800538 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800539
Adam Stonef0e618d2018-01-17 19:20:41 -0800540 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800541 return err;
542}
543
544status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
545 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800546 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800547
Jeff Tinker319d5f42017-07-26 15:44:33 -0700548 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
549 if (status.isOk()) {
550 if (status == Status::OK) {
551 DrmSessionManager::Instance()->removeSession(sessionId);
552 for (size_t i = 0; i < mOpenSessions.size(); i++) {
553 if (mOpenSessions[i] == sessionId) {
554 mOpenSessions.removeAt(i);
555 break;
556 }
Jeff Tinker61332812017-05-15 16:53:10 -0700557 }
558 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700559 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800560 status_t response = toStatusT(status);
561 mMetrics.mCloseSessionCounter.Increment(response);
562 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800563 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800564 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700565 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800566}
567
568status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
569 Vector<uint8_t> const &initData, String8 const &mimeType,
570 DrmPlugin::KeyType keyType, KeyedVector<String8,
571 String8> const &optionalParameters, Vector<uint8_t> &request,
572 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
573 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800574 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800575 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800576
577 DrmSessionManager::Instance()->useSession(sessionId);
578
579 KeyType hKeyType;
580 if (keyType == DrmPlugin::kKeyType_Streaming) {
581 hKeyType = KeyType::STREAMING;
582 } else if (keyType == DrmPlugin::kKeyType_Offline) {
583 hKeyType = KeyType::OFFLINE;
584 } else if (keyType == DrmPlugin::kKeyType_Release) {
585 hKeyType = KeyType::RELEASE;
586 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800587 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800588 return BAD_VALUE;
589 }
590
591 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
592
593 status_t err = UNKNOWN_ERROR;
594
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800595 if (mPluginV1_1 != NULL) {
596 Return<void> hResult =
597 mPluginV1_1->getKeyRequest_1_1(
598 toHidlVec(sessionId), toHidlVec(initData),
599 toHidlString(mimeType), hKeyType, hOptionalParameters,
600 [&](Status status, const hidl_vec<uint8_t>& hRequest,
601 drm::V1_1::KeyRequestType hKeyRequestType,
602 const hidl_string& hDefaultUrl) {
603
604 if (status == Status::OK) {
605 request = toVector(hRequest);
606 defaultUrl = toString8(hDefaultUrl);
607
608 switch (hKeyRequestType) {
609 case drm::V1_1::KeyRequestType::INITIAL:
610 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
611 break;
612 case drm::V1_1::KeyRequestType::RENEWAL:
613 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
614 break;
615 case drm::V1_1::KeyRequestType::RELEASE:
616 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
617 break;
618 case drm::V1_1::KeyRequestType::NONE:
619 *keyRequestType = DrmPlugin::kKeyRequestType_None;
620 break;
621 case drm::V1_1::KeyRequestType::UPDATE:
622 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
623 break;
624 default:
625 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
626 break;
627 }
628 err = toStatusT(status);
629 }
630 });
631 return hResult.isOk() ? err : DEAD_OBJECT;
632 }
633
Jeff Tinkera53d6552017-01-20 00:31:46 -0800634 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
635 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
636 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800637 drm::V1_0::KeyRequestType hKeyRequestType,
638 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800639
640 if (status == Status::OK) {
641 request = toVector(hRequest);
642 defaultUrl = toString8(hDefaultUrl);
643
644 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800645 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800646 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
647 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800648 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800649 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
650 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800651 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800652 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
653 break;
654 default:
655 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
656 break;
657 }
658 err = toStatusT(status);
659 }
660 });
661
Adam Stonef0e618d2018-01-17 19:20:41 -0800662 err = hResult.isOk() ? err : DEAD_OBJECT;
663 keyRequestTimer.SetAttribute(err);
664 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800665}
666
667status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
668 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
669 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800670 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
671
Jeff Tinker6d998b62017-12-18 14:37:43 -0800672 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800673
674 DrmSessionManager::Instance()->useSession(sessionId);
675
676 status_t err = UNKNOWN_ERROR;
677
678 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
679 toHidlVec(response),
680 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
681 if (status == Status::OK) {
682 keySetId = toVector(hKeySetId);
683 }
684 err = toStatusT(status);
685 }
686 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800687 err = hResult.isOk() ? err : DEAD_OBJECT;
688 keyResponseTimer.SetAttribute(err);
689 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800690}
691
692status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
693 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800694 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800695
696 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
697}
698
699status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
700 Vector<uint8_t> const &keySetId) {
701 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800702 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800703
704 DrmSessionManager::Instance()->useSession(sessionId);
705
706 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
707 toHidlVec(keySetId)));
708}
709
710status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
711 KeyedVector<String8, String8> &infoMap) const {
712 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800713 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800714
715 DrmSessionManager::Instance()->useSession(sessionId);
716
717 ::KeyedVector hInfoMap;
718
719 status_t err = UNKNOWN_ERROR;
720
721 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
722 [&](Status status, const hidl_vec<KeyValue>& map) {
723 if (status == Status::OK) {
724 infoMap = toKeyedVector(map);
725 }
726 err = toStatusT(status);
727 }
728 );
729
730 return hResult.isOk() ? err : DEAD_OBJECT;
731}
732
733status_t DrmHal::getProvisionRequest(String8 const &certType,
734 String8 const &certAuthority, Vector<uint8_t> &request,
735 String8 &defaultUrl) {
736 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800737 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800738
739 status_t err = UNKNOWN_ERROR;
740
741 Return<void> hResult = mPlugin->getProvisionRequest(
742 toHidlString(certType), toHidlString(certAuthority),
743 [&](Status status, const hidl_vec<uint8_t>& hRequest,
744 const hidl_string& hDefaultUrl) {
745 if (status == Status::OK) {
746 request = toVector(hRequest);
747 defaultUrl = toString8(hDefaultUrl);
748 }
749 err = toStatusT(status);
750 }
751 );
752
Adam Stonecea91ce2018-01-22 19:23:28 -0800753 err = hResult.isOk() ? err : DEAD_OBJECT;
754 mMetrics.mGetProvisionRequestCounter.Increment(err);
755 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800756}
757
758status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800759 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800760 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800761 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800762
763 status_t err = UNKNOWN_ERROR;
764
765 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
766 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
767 const hidl_vec<uint8_t>& hWrappedKey) {
768 if (status == Status::OK) {
769 certificate = toVector(hCertificate);
770 wrappedKey = toVector(hWrappedKey);
771 }
772 err = toStatusT(status);
773 }
774 );
775
Adam Stonecea91ce2018-01-22 19:23:28 -0800776 err = hResult.isOk() ? err : DEAD_OBJECT;
777 mMetrics.mProvideProvisionResponseCounter.Increment(err);
778 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800779}
780
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800781status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800782 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800783 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800784
785 status_t err = UNKNOWN_ERROR;
786
787 Return<void> hResult = mPlugin->getSecureStops(
788 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
789 if (status == Status::OK) {
790 secureStops = toSecureStops(hSecureStops);
791 }
792 err = toStatusT(status);
793 }
794 );
795
796 return hResult.isOk() ? err : DEAD_OBJECT;
797}
798
799
800status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
801 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800802 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800803
804 status_t err = UNKNOWN_ERROR;
805
806 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
807 [&](Status status, const SecureStop& hSecureStop) {
808 if (status == Status::OK) {
809 secureStop = toVector(hSecureStop.opaqueData);
810 }
811 err = toStatusT(status);
812 }
813 );
814
815 return hResult.isOk() ? err : DEAD_OBJECT;
816}
817
818status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
819 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800820 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800821
822 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
823}
824
825status_t DrmHal::releaseAllSecureStops() {
826 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800827 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800828
829 return toStatusT(mPlugin->releaseAllSecureStops());
830}
831
Jeff Tinker6d998b62017-12-18 14:37:43 -0800832status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
833 DrmPlugin::HdcpLevel *max) const {
834 Mutex::Autolock autoLock(mLock);
835 INIT_CHECK();
836
837 if (connected == NULL || max == NULL) {
838 return BAD_VALUE;
839 }
840 status_t err = UNKNOWN_ERROR;
841
842 if (mPluginV1_1 == NULL) {
843 return ERROR_DRM_CANNOT_HANDLE;
844 }
845
846 *connected = DrmPlugin::kHdcpLevelUnknown;
847 *max = DrmPlugin::kHdcpLevelUnknown;
848
849 Return<void> hResult = mPluginV1_1->getHdcpLevels(
850 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
851 if (status == Status::OK) {
852 *connected = toHdcpLevel(hConnected);
853 *max = toHdcpLevel(hMax);
854 }
855 err = toStatusT(status);
856 }
857 );
858
859 return hResult.isOk() ? err : DEAD_OBJECT;
860}
861
862status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
863 Mutex::Autolock autoLock(mLock);
864 INIT_CHECK();
865
866 if (open == NULL || max == NULL) {
867 return BAD_VALUE;
868 }
869 status_t err = UNKNOWN_ERROR;
870
871 *open = 0;
872 *max = 0;
873
874 if (mPluginV1_1 == NULL) {
875 return ERROR_DRM_CANNOT_HANDLE;
876 }
877
878 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
879 [&](Status status, uint32_t hOpen, uint32_t hMax) {
880 if (status == Status::OK) {
881 *open = hOpen;
882 *max = hMax;
883 }
884 err = toStatusT(status);
885 }
886 );
887
888 return hResult.isOk() ? err : DEAD_OBJECT;
889}
890
891status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
892 DrmPlugin::SecurityLevel *level) const {
893 Mutex::Autolock autoLock(mLock);
894 INIT_CHECK();
895
896 if (level == NULL) {
897 return BAD_VALUE;
898 }
899 status_t err = UNKNOWN_ERROR;
900
901 if (mPluginV1_1 == NULL) {
902 return ERROR_DRM_CANNOT_HANDLE;
903 }
904
905 *level = DrmPlugin::kSecurityLevelUnknown;
906
907 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
908 [&](Status status, SecurityLevel hLevel) {
909 if (status == Status::OK) {
910 *level = toSecurityLevel(hLevel);
911 }
912 err = toStatusT(status);
913 }
914 );
915
916 return hResult.isOk() ? err : DEAD_OBJECT;
917}
918
919status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
920 const DrmPlugin::SecurityLevel& level) {
921 Mutex::Autolock autoLock(mLock);
922 INIT_CHECK();
923
924 if (mPluginV1_1 == NULL) {
925 return ERROR_DRM_CANNOT_HANDLE;
926 }
927
928 SecurityLevel hSecurityLevel;
929
930 switch(level) {
931 case DrmPlugin::kSecurityLevelSwSecureCrypto:
932 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
933 break;
934 case DrmPlugin::kSecurityLevelSwSecureDecode:
935 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
936 break;
937 case DrmPlugin::kSecurityLevelHwSecureCrypto:
938 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
939 break;
940 case DrmPlugin::kSecurityLevelHwSecureDecode:
941 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
942 break;
943 case DrmPlugin::kSecurityLevelHwSecureAll:
944 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
945 break;
946 default:
947 return ERROR_DRM_CANNOT_HANDLE;
948 }
949
950 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
951 hSecurityLevel);
952 return toStatusT(status);
953}
954
Jeff Tinkera53d6552017-01-20 00:31:46 -0800955status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
956 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700957 return getPropertyStringInternal(name, value);
958}
959
960status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
961 // This function is internal to the class and should only be called while
962 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800963 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800964
965 status_t err = UNKNOWN_ERROR;
966
967 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
968 [&](Status status, const hidl_string& hValue) {
969 if (status == Status::OK) {
970 value = toString8(hValue);
971 }
972 err = toStatusT(status);
973 }
974 );
975
976 return hResult.isOk() ? err : DEAD_OBJECT;
977}
978
979status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
980 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700981 return getPropertyByteArrayInternal(name, value);
982}
983
984status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
985 // This function is internal to the class and should only be called while
986 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800987 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800988
989 status_t err = UNKNOWN_ERROR;
990
991 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
992 [&](Status status, const hidl_vec<uint8_t>& hValue) {
993 if (status == Status::OK) {
994 value = toVector(hValue);
995 }
996 err = toStatusT(status);
997 }
998 );
999
Adam Stonecea91ce2018-01-22 19:23:28 -08001000 err = hResult.isOk() ? err : DEAD_OBJECT;
1001 if (name == kPropertyDeviceUniqueId) {
1002 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1003 }
1004 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001005}
1006
1007status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1008 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001009 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001010
Jeff Tinker6d998b62017-12-18 14:37:43 -08001011 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001012 toHidlString(value));
1013 return toStatusT(status);
1014}
1015
1016status_t DrmHal::setPropertyByteArray(String8 const &name,
1017 Vector<uint8_t> const &value ) const {
1018 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001019 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001020
1021 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1022 toHidlVec(value));
1023 return toStatusT(status);
1024}
1025
Adam Stonef0e618d2018-01-17 19:20:41 -08001026status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
1027 if (item == nullptr) {
1028 return UNEXPECTED_NULL;
1029 }
1030
1031 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001032 return OK;
1033}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001034
1035status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1036 String8 const &algorithm) {
1037 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001038 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001039
1040 DrmSessionManager::Instance()->useSession(sessionId);
1041
1042 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1043 toHidlString(algorithm));
1044 return toStatusT(status);
1045}
1046
1047status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1048 String8 const &algorithm) {
1049 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001050 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001051
1052 DrmSessionManager::Instance()->useSession(sessionId);
1053
1054 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1055 toHidlString(algorithm));
1056 return toStatusT(status);
1057}
1058
1059status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001060 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1061 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001062 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001063 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001064
1065 DrmSessionManager::Instance()->useSession(sessionId);
1066
1067 status_t err = UNKNOWN_ERROR;
1068
1069 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1070 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1071 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1072 if (status == Status::OK) {
1073 output = toVector(hOutput);
1074 }
1075 err = toStatusT(status);
1076 }
1077 );
1078
1079 return hResult.isOk() ? err : DEAD_OBJECT;
1080}
1081
1082status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001083 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1084 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001085 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001086 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001087
1088 DrmSessionManager::Instance()->useSession(sessionId);
1089
1090 status_t err = UNKNOWN_ERROR;
1091
1092 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1093 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1094 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1095 if (status == Status::OK) {
1096 output = toVector(hOutput);
1097 }
1098 err = toStatusT(status);
1099 }
1100 );
1101
1102 return hResult.isOk() ? err : DEAD_OBJECT;
1103}
1104
1105status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001106 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1107 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001108 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001109 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001110
1111 DrmSessionManager::Instance()->useSession(sessionId);
1112
1113 status_t err = UNKNOWN_ERROR;
1114
1115 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1116 toHidlVec(keyId), toHidlVec(message),
1117 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1118 if (status == Status::OK) {
1119 signature = toVector(hSignature);
1120 }
1121 err = toStatusT(status);
1122 }
1123 );
1124
1125 return hResult.isOk() ? err : DEAD_OBJECT;
1126}
1127
1128status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001129 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1130 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001131 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001132 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001133
1134 DrmSessionManager::Instance()->useSession(sessionId);
1135
1136 status_t err = UNKNOWN_ERROR;
1137
1138 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1139 toHidlVec(message), toHidlVec(signature),
1140 [&](Status status, bool hMatch) {
1141 if (status == Status::OK) {
1142 match = hMatch;
1143 } else {
1144 match = false;
1145 }
1146 err = toStatusT(status);
1147 }
1148 );
1149
1150 return hResult.isOk() ? err : DEAD_OBJECT;
1151}
1152
1153status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001154 String8 const &algorithm, Vector<uint8_t> const &message,
1155 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001156 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001157 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001158
1159 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1160 return -EPERM;
1161 }
1162
1163 DrmSessionManager::Instance()->useSession(sessionId);
1164
1165 status_t err = UNKNOWN_ERROR;
1166
1167 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1168 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1169 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1170 if (status == Status::OK) {
1171 signature = toVector(hSignature);
1172 }
1173 err = toStatusT(status);
1174 }
1175 );
1176
1177 return hResult.isOk() ? err : DEAD_OBJECT;
1178}
1179
1180void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1181{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001182 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001183 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001184 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001185 mInitCheck = NO_INIT;
1186
Jeff Tinker70367f52017-06-16 12:41:33 -07001187 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001188 if (!mPlugin->setListener(NULL).isOk()) {
1189 mInitCheck = DEAD_OBJECT;
1190 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001191 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001192 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001193}
1194
1195void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1196{
1197 if (vec.size()) {
1198 obj.writeInt32(vec.size());
1199 obj.write(vec.data(), vec.size());
1200 } else {
1201 obj.writeInt32(0);
1202 }
1203}
1204
Adam Stoneab394d12017-12-22 12:34:20 -08001205
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001206void DrmHal::reportMetrics() const
1207{
1208 Vector<uint8_t> metrics;
1209 String8 vendor;
1210 String8 description;
1211 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1212 getPropertyStringInternal(String8("description"), description) == OK &&
1213 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1214 status_t res = android::reportDrmPluginMetrics(
1215 metrics, vendor, description);
1216 if (res != OK) {
1217 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1218 }
1219 }
1220}
1221
Jeff Tinkera53d6552017-01-20 00:31:46 -08001222} // namespace android