blob: b5c1ddf137b52bca2b1b66c824cd2ab7750be302 [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;
Jeff Tinker15177d72018-01-25 12:57:55 -080047using drm::V1_1::SecureStopRelease;
48using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080049using drm::V1_1::SecurityLevel;
50using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080051using ::android::hardware::hidl_array;
52using ::android::hardware::hidl_string;
53using ::android::hardware::hidl_vec;
54using ::android::hardware::Return;
55using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080056using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080057using ::android::sp;
58
Adam Stonecea91ce2018-01-22 19:23:28 -080059namespace {
60
61// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
62// in the MediaDrm API.
63constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
64
65}
66
Jeff Tinkera53d6552017-01-20 00:31:46 -080067namespace android {
68
Jeff Tinker6d998b62017-12-18 14:37:43 -080069#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
70
Jeff Tinkera53d6552017-01-20 00:31:46 -080071static inline int getCallingPid() {
72 return IPCThreadState::self()->getCallingPid();
73}
74
75static bool checkPermission(const char* permissionString) {
76 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
77 bool ok = checkCallingPermission(String16(permissionString));
78 if (!ok) ALOGE("Request requires %s", permissionString);
79 return ok;
80}
81
82static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
83 Vector<uint8_t> vector;
84 vector.appendArray(vec.data(), vec.size());
85 return *const_cast<const Vector<uint8_t> *>(&vector);
86}
87
88static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
89 hidl_vec<uint8_t> vec;
90 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
91 return vec;
92}
93
94static String8 toString8(const hidl_string &string) {
95 return String8(string.c_str());
96}
97
98static hidl_string toHidlString(const String8& string) {
99 return hidl_string(string.string());
100}
101
Jeff Tinker6d998b62017-12-18 14:37:43 -0800102static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
103 switch(level) {
104 case SecurityLevel::SW_SECURE_CRYPTO:
105 return DrmPlugin::kSecurityLevelSwSecureCrypto;
106 case SecurityLevel::SW_SECURE_DECODE:
107 return DrmPlugin::kSecurityLevelSwSecureDecode;
108 case SecurityLevel::HW_SECURE_CRYPTO:
109 return DrmPlugin::kSecurityLevelHwSecureCrypto;
110 case SecurityLevel::HW_SECURE_DECODE:
111 return DrmPlugin::kSecurityLevelHwSecureDecode;
112 case SecurityLevel::HW_SECURE_ALL:
113 return DrmPlugin::kSecurityLevelHwSecureAll;
114 default:
115 return DrmPlugin::kSecurityLevelUnknown;
116 }
117}
118
119static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
120 switch(level) {
121 case HdcpLevel::HDCP_NONE:
122 return DrmPlugin::kHdcpNone;
123 case HdcpLevel::HDCP_V1:
124 return DrmPlugin::kHdcpV1;
125 case HdcpLevel::HDCP_V2:
126 return DrmPlugin::kHdcpV2;
127 case HdcpLevel::HDCP_V2_1:
128 return DrmPlugin::kHdcpV2_1;
129 case HdcpLevel::HDCP_V2_2:
130 return DrmPlugin::kHdcpV2_2;
131 case HdcpLevel::HDCP_NO_OUTPUT:
132 return DrmPlugin::kHdcpNoOutput;
133 default:
134 return DrmPlugin::kHdcpLevelUnknown;
135 }
136}
137
Jeff Tinkera53d6552017-01-20 00:31:46 -0800138
139static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
140 keyedVector) {
141 std::vector<KeyValue> stdKeyedVector;
142 for (size_t i = 0; i < keyedVector.size(); i++) {
143 KeyValue keyValue;
144 keyValue.key = toHidlString(keyedVector.keyAt(i));
145 keyValue.value = toHidlString(keyedVector.valueAt(i));
146 stdKeyedVector.push_back(keyValue);
147 }
148 return ::KeyedVector(stdKeyedVector);
149}
150
151static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
152 hKeyedVector) {
153 KeyedVector<String8, String8> keyedVector;
154 for (size_t i = 0; i < hKeyedVector.size(); i++) {
155 keyedVector.add(toString8(hKeyedVector[i].key),
156 toString8(hKeyedVector[i].value));
157 }
158 return keyedVector;
159}
160
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800161static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800162 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800163 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800164 for (size_t i = 0; i < hSecureStops.size(); i++) {
165 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
166 }
167 return secureStops;
168}
169
Jeff Tinker15177d72018-01-25 12:57:55 -0800170static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
171 hSecureStopIds) {
172 List<Vector<uint8_t>> secureStopIds;
173 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
174 secureStopIds.push_back(toVector(hSecureStopIds[i]));
175 }
176 return secureStopIds;
177}
178
Jeff Tinkera53d6552017-01-20 00:31:46 -0800179static status_t toStatusT(Status status) {
180 switch (status) {
181 case Status::OK:
182 return OK;
183 break;
184 case Status::ERROR_DRM_NO_LICENSE:
185 return ERROR_DRM_NO_LICENSE;
186 break;
187 case Status::ERROR_DRM_LICENSE_EXPIRED:
188 return ERROR_DRM_LICENSE_EXPIRED;
189 break;
190 case Status::ERROR_DRM_SESSION_NOT_OPENED:
191 return ERROR_DRM_SESSION_NOT_OPENED;
192 break;
193 case Status::ERROR_DRM_CANNOT_HANDLE:
194 return ERROR_DRM_CANNOT_HANDLE;
195 break;
196 case Status::ERROR_DRM_INVALID_STATE:
197 return ERROR_DRM_TAMPER_DETECTED;
198 break;
199 case Status::BAD_VALUE:
200 return BAD_VALUE;
201 break;
202 case Status::ERROR_DRM_NOT_PROVISIONED:
203 return ERROR_DRM_NOT_PROVISIONED;
204 break;
205 case Status::ERROR_DRM_RESOURCE_BUSY:
206 return ERROR_DRM_RESOURCE_BUSY;
207 break;
208 case Status::ERROR_DRM_DEVICE_REVOKED:
209 return ERROR_DRM_DEVICE_REVOKED;
210 break;
211 case Status::ERROR_DRM_UNKNOWN:
212 default:
213 return ERROR_DRM_UNKNOWN;
214 break;
215 }
216}
217
218
219Mutex DrmHal::mLock;
220
221struct DrmSessionClient : public DrmSessionClientInterface {
222 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
223
224 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
225 sp<DrmHal> drm = mDrm.promote();
226 if (drm == NULL) {
227 return true;
228 }
229 status_t err = drm->closeSession(sessionId);
230 if (err != OK) {
231 return false;
232 }
233 drm->sendEvent(EventType::SESSION_RECLAIMED,
234 toHidlVec(sessionId), hidl_vec<uint8_t>());
235 return true;
236 }
237
238protected:
239 virtual ~DrmSessionClient() {}
240
241private:
242 wp<DrmHal> mDrm;
243
244 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
245};
246
247DrmHal::DrmHal()
248 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800249 mFactories(makeDrmFactories()),
250 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800251}
252
Jeff Tinker61332812017-05-15 16:53:10 -0700253void DrmHal::closeOpenSessions() {
254 if (mPlugin != NULL) {
Jeff Tinker09a90ab2018-01-23 17:43:29 -0800255 auto openSessions = mOpenSessions;
256 for (size_t i = 0; i < openSessions.size(); i++) {
257 closeSession(openSessions[i]);
Jeff Tinker61332812017-05-15 16:53:10 -0700258 }
259 }
260 mOpenSessions.clear();
261}
262
Jeff Tinkera53d6552017-01-20 00:31:46 -0800263DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700264 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800265 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
266}
267
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800268Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
269 Vector<sp<IDrmFactory>> factories;
270
Jeff Tinker593111f2017-05-25 16:00:21 -0700271 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800272
273 if (manager != NULL) {
274 manager->listByInterface(IDrmFactory::descriptor,
275 [&factories](const hidl_vec<hidl_string> &registered) {
276 for (const auto &instance : registered) {
277 auto factory = IDrmFactory::getService(instance);
278 if (factory != NULL) {
279 factories.push_back(factory);
280 ALOGI("makeDrmFactories: factory instance %s is %s",
281 instance.c_str(),
282 factory->isRemote() ? "Remote" : "Not Remote");
283 }
284 }
285 }
286 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800287 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800288
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800289 if (factories.size() == 0) {
290 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700291 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800292 if (passthrough != NULL) {
293 ALOGI("makeDrmFactories: using default drm instance");
294 factories.push_back(passthrough);
295 } else {
296 ALOGE("Failed to find any drm factories");
297 }
298 }
299 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800300}
301
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800302sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
303 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800304
305 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800306 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800307 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800308 if (status != Status::OK) {
309 ALOGE("Failed to make drm plugin");
310 return;
311 }
312 plugin = hPlugin;
313 }
314 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700315
316 if (!hResult.isOk()) {
317 ALOGE("createPlugin remote call failed");
318 }
319
Jeff Tinkera53d6552017-01-20 00:31:46 -0800320 return plugin;
321}
322
323status_t DrmHal::initCheck() const {
324 return mInitCheck;
325}
326
327status_t DrmHal::setListener(const sp<IDrmClient>& listener)
328{
329 Mutex::Autolock lock(mEventLock);
330 if (mListener != NULL){
331 IInterface::asBinder(mListener)->unlinkToDeath(this);
332 }
333 if (listener != NULL) {
334 IInterface::asBinder(listener)->linkToDeath(this);
335 }
336 mListener = listener;
337 return NO_ERROR;
338}
339
340Return<void> DrmHal::sendEvent(EventType hEventType,
341 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800342 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800343
344 mEventLock.lock();
345 sp<IDrmClient> listener = mListener;
346 mEventLock.unlock();
347
348 if (listener != NULL) {
349 Parcel obj;
350 writeByteArray(obj, sessionId);
351 writeByteArray(obj, data);
352
353 Mutex::Autolock lock(mNotifyLock);
354 DrmPlugin::EventType eventType;
355 switch(hEventType) {
356 case EventType::PROVISION_REQUIRED:
357 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
358 break;
359 case EventType::KEY_NEEDED:
360 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
361 break;
362 case EventType::KEY_EXPIRED:
363 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
364 break;
365 case EventType::VENDOR_DEFINED:
366 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
367 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700368 case EventType::SESSION_RECLAIMED:
369 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
370 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800371 default:
372 return Void();
373 }
374 listener->notify(eventType, 0, &obj);
375 }
376 return Void();
377}
378
379Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
380 int64_t expiryTimeInMS) {
381
382 mEventLock.lock();
383 sp<IDrmClient> listener = mListener;
384 mEventLock.unlock();
385
386 if (listener != NULL) {
387 Parcel obj;
388 writeByteArray(obj, sessionId);
389 obj.writeInt64(expiryTimeInMS);
390
391 Mutex::Autolock lock(mNotifyLock);
392 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
393 }
394 return Void();
395}
396
397Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
398 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
399
400 mEventLock.lock();
401 sp<IDrmClient> listener = mListener;
402 mEventLock.unlock();
403
404 if (listener != NULL) {
405 Parcel obj;
406 writeByteArray(obj, sessionId);
407
408 size_t nKeys = keyStatusList.size();
409 obj.writeInt32(nKeys);
410 for (size_t i = 0; i < nKeys; ++i) {
411 const KeyStatus &keyStatus = keyStatusList[i];
412 writeByteArray(obj, keyStatus.keyId);
413 uint32_t type;
414 switch(keyStatus.type) {
415 case KeyStatusType::USABLE:
416 type = DrmPlugin::kKeyStatusType_Usable;
417 break;
418 case KeyStatusType::EXPIRED:
419 type = DrmPlugin::kKeyStatusType_Expired;
420 break;
421 case KeyStatusType::OUTPUTNOTALLOWED:
422 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
423 break;
424 case KeyStatusType::STATUSPENDING:
425 type = DrmPlugin::kKeyStatusType_StatusPending;
426 break;
427 case KeyStatusType::INTERNALERROR:
428 default:
429 type = DrmPlugin::kKeyStatusType_InternalError;
430 break;
431 }
432 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800433 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800434 }
435 obj.writeInt32(hasNewUsableKey);
436
437 Mutex::Autolock lock(mNotifyLock);
438 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800439 } else {
440 // There's no listener. But we still want to count the key change
441 // events.
442 size_t nKeys = keyStatusList.size();
443 for (size_t i = 0; i < nKeys; i++) {
444 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
445 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800446 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800447
Jeff Tinkera53d6552017-01-20 00:31:46 -0800448 return Void();
449}
450
451bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
452 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800453
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800454 for (size_t i = 0; i < mFactories.size(); i++) {
455 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
456 if (mimeType != "") {
457 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
458 return true;
459 }
460 } else {
461 return true;
462 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800463 }
464 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800465 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800466}
467
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800468status_t DrmHal::createPlugin(const uint8_t uuid[16],
469 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470 Mutex::Autolock autoLock(mLock);
471
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800472 for (size_t i = 0; i < mFactories.size(); i++) {
473 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
474 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800475 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800476 }
477 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800478
479 if (mPlugin == NULL) {
480 mInitCheck = ERROR_UNSUPPORTED;
481 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700482 if (!mPlugin->setListener(this).isOk()) {
483 mInitCheck = DEAD_OBJECT;
484 } else {
485 mInitCheck = OK;
486 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800487 }
488
489 return mInitCheck;
490}
491
492status_t DrmHal::destroyPlugin() {
493 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800494 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800495
Jeff Tinker61332812017-05-15 16:53:10 -0700496 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700497 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800498 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700499 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800500
Jeff Tinker319d5f42017-07-26 15:44:33 -0700501 if (mPlugin != NULL) {
502 if (!mPlugin->setListener(NULL).isOk()) {
503 mInitCheck = DEAD_OBJECT;
504 }
505 }
506 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800507 return OK;
508}
509
510status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
511 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800512 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800513
514 status_t err = UNKNOWN_ERROR;
515
516 bool retry = true;
517 do {
518 hidl_vec<uint8_t> hSessionId;
519
520 Return<void> hResult = mPlugin->openSession(
521 [&](Status status, const hidl_vec<uint8_t>& id) {
522 if (status == Status::OK) {
523 sessionId = toVector(id);
524 }
525 err = toStatusT(status);
526 }
527 );
528
529 if (!hResult.isOk()) {
530 err = DEAD_OBJECT;
531 }
532
533 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
534 mLock.unlock();
535 // reclaimSession may call back to closeSession, since mLock is
536 // shared between Drm instances, we should unlock here to avoid
537 // deadlock.
538 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
539 mLock.lock();
540 } else {
541 retry = false;
542 }
543 } while (retry);
544
545 if (err == OK) {
546 DrmSessionManager::Instance()->addSession(getCallingPid(),
547 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700548 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800549 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800550
Adam Stonef0e618d2018-01-17 19:20:41 -0800551 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552 return err;
553}
554
555status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
556 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800557 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800558
Jeff Tinker319d5f42017-07-26 15:44:33 -0700559 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
560 if (status.isOk()) {
561 if (status == Status::OK) {
562 DrmSessionManager::Instance()->removeSession(sessionId);
563 for (size_t i = 0; i < mOpenSessions.size(); i++) {
564 if (mOpenSessions[i] == sessionId) {
565 mOpenSessions.removeAt(i);
566 break;
567 }
Jeff Tinker61332812017-05-15 16:53:10 -0700568 }
569 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700570 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800571 status_t response = toStatusT(status);
572 mMetrics.mCloseSessionCounter.Increment(response);
573 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800574 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800575 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700576 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800577}
578
579status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
580 Vector<uint8_t> const &initData, String8 const &mimeType,
581 DrmPlugin::KeyType keyType, KeyedVector<String8,
582 String8> const &optionalParameters, Vector<uint8_t> &request,
583 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
584 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800585 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800586 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800587
588 DrmSessionManager::Instance()->useSession(sessionId);
589
590 KeyType hKeyType;
591 if (keyType == DrmPlugin::kKeyType_Streaming) {
592 hKeyType = KeyType::STREAMING;
593 } else if (keyType == DrmPlugin::kKeyType_Offline) {
594 hKeyType = KeyType::OFFLINE;
595 } else if (keyType == DrmPlugin::kKeyType_Release) {
596 hKeyType = KeyType::RELEASE;
597 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800598 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800599 return BAD_VALUE;
600 }
601
602 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
603
604 status_t err = UNKNOWN_ERROR;
605
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800606 if (mPluginV1_1 != NULL) {
607 Return<void> hResult =
608 mPluginV1_1->getKeyRequest_1_1(
609 toHidlVec(sessionId), toHidlVec(initData),
610 toHidlString(mimeType), hKeyType, hOptionalParameters,
611 [&](Status status, const hidl_vec<uint8_t>& hRequest,
612 drm::V1_1::KeyRequestType hKeyRequestType,
613 const hidl_string& hDefaultUrl) {
614
615 if (status == Status::OK) {
616 request = toVector(hRequest);
617 defaultUrl = toString8(hDefaultUrl);
618
619 switch (hKeyRequestType) {
620 case drm::V1_1::KeyRequestType::INITIAL:
621 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
622 break;
623 case drm::V1_1::KeyRequestType::RENEWAL:
624 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
625 break;
626 case drm::V1_1::KeyRequestType::RELEASE:
627 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
628 break;
629 case drm::V1_1::KeyRequestType::NONE:
630 *keyRequestType = DrmPlugin::kKeyRequestType_None;
631 break;
632 case drm::V1_1::KeyRequestType::UPDATE:
633 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
634 break;
635 default:
636 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
637 break;
638 }
639 err = toStatusT(status);
640 }
641 });
642 return hResult.isOk() ? err : DEAD_OBJECT;
643 }
644
Jeff Tinkera53d6552017-01-20 00:31:46 -0800645 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
646 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
647 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800648 drm::V1_0::KeyRequestType hKeyRequestType,
649 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800650
651 if (status == Status::OK) {
652 request = toVector(hRequest);
653 defaultUrl = toString8(hDefaultUrl);
654
655 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800656 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800657 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
658 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800659 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800660 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
661 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800662 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800663 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
664 break;
665 default:
666 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
667 break;
668 }
669 err = toStatusT(status);
670 }
671 });
672
Adam Stonef0e618d2018-01-17 19:20:41 -0800673 err = hResult.isOk() ? err : DEAD_OBJECT;
674 keyRequestTimer.SetAttribute(err);
675 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800676}
677
678status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
679 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
680 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800681 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
682
Jeff Tinker6d998b62017-12-18 14:37:43 -0800683 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800684
685 DrmSessionManager::Instance()->useSession(sessionId);
686
687 status_t err = UNKNOWN_ERROR;
688
689 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
690 toHidlVec(response),
691 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
692 if (status == Status::OK) {
693 keySetId = toVector(hKeySetId);
694 }
695 err = toStatusT(status);
696 }
697 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800698 err = hResult.isOk() ? err : DEAD_OBJECT;
699 keyResponseTimer.SetAttribute(err);
700 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800701}
702
703status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
704 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800705 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800706
707 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
708}
709
710status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
711 Vector<uint8_t> const &keySetId) {
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 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
718 toHidlVec(keySetId)));
719}
720
721status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
722 KeyedVector<String8, String8> &infoMap) const {
723 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800724 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800725
726 DrmSessionManager::Instance()->useSession(sessionId);
727
728 ::KeyedVector hInfoMap;
729
730 status_t err = UNKNOWN_ERROR;
731
732 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
733 [&](Status status, const hidl_vec<KeyValue>& map) {
734 if (status == Status::OK) {
735 infoMap = toKeyedVector(map);
736 }
737 err = toStatusT(status);
738 }
739 );
740
741 return hResult.isOk() ? err : DEAD_OBJECT;
742}
743
744status_t DrmHal::getProvisionRequest(String8 const &certType,
745 String8 const &certAuthority, Vector<uint8_t> &request,
746 String8 &defaultUrl) {
747 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->getProvisionRequest(
753 toHidlString(certType), toHidlString(certAuthority),
754 [&](Status status, const hidl_vec<uint8_t>& hRequest,
755 const hidl_string& hDefaultUrl) {
756 if (status == Status::OK) {
757 request = toVector(hRequest);
758 defaultUrl = toString8(hDefaultUrl);
759 }
760 err = toStatusT(status);
761 }
762 );
763
Adam Stonecea91ce2018-01-22 19:23:28 -0800764 err = hResult.isOk() ? err : DEAD_OBJECT;
765 mMetrics.mGetProvisionRequestCounter.Increment(err);
766 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800767}
768
769status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800770 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800771 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800772 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773
774 status_t err = UNKNOWN_ERROR;
775
776 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
777 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
778 const hidl_vec<uint8_t>& hWrappedKey) {
779 if (status == Status::OK) {
780 certificate = toVector(hCertificate);
781 wrappedKey = toVector(hWrappedKey);
782 }
783 err = toStatusT(status);
784 }
785 );
786
Adam Stonecea91ce2018-01-22 19:23:28 -0800787 err = hResult.isOk() ? err : DEAD_OBJECT;
788 mMetrics.mProvideProvisionResponseCounter.Increment(err);
789 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800790}
791
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800792status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800793 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800794 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800795
796 status_t err = UNKNOWN_ERROR;
797
798 Return<void> hResult = mPlugin->getSecureStops(
799 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
800 if (status == Status::OK) {
801 secureStops = toSecureStops(hSecureStops);
802 }
803 err = toStatusT(status);
804 }
805 );
806
807 return hResult.isOk() ? err : DEAD_OBJECT;
808}
809
810
Jeff Tinker15177d72018-01-25 12:57:55 -0800811status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
812 Mutex::Autolock autoLock(mLock);
813
814 if (mInitCheck != OK) {
815 return mInitCheck;
816 }
817
818 if (mPluginV1_1 == NULL) {
819 return ERROR_DRM_CANNOT_HANDLE;
820 }
821
822 status_t err = UNKNOWN_ERROR;
823
824 Return<void> hResult = mPluginV1_1->getSecureStopIds(
825 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
826 if (status == Status::OK) {
827 secureStopIds = toSecureStopIds(hSecureStopIds);
828 }
829 err = toStatusT(status);
830 }
831 );
832
833 return hResult.isOk() ? err : DEAD_OBJECT;
834}
835
836
Jeff Tinkera53d6552017-01-20 00:31:46 -0800837status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
838 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800839 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800840
841 status_t err = UNKNOWN_ERROR;
842
843 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
844 [&](Status status, const SecureStop& hSecureStop) {
845 if (status == Status::OK) {
846 secureStop = toVector(hSecureStop.opaqueData);
847 }
848 err = toStatusT(status);
849 }
850 );
851
852 return hResult.isOk() ? err : DEAD_OBJECT;
853}
854
855status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
856 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800857 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800858
Jeff Tinker15177d72018-01-25 12:57:55 -0800859 if (mPluginV1_1 != NULL) {
860 SecureStopRelease secureStopRelease;
861 secureStopRelease.opaqueData = toHidlVec(ssRelease);
862 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
863 }
864
Jeff Tinkera53d6552017-01-20 00:31:46 -0800865 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
866}
867
Jeff Tinker15177d72018-01-25 12:57:55 -0800868status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
869 Mutex::Autolock autoLock(mLock);
870
871 if (mInitCheck != OK) {
872 return mInitCheck;
873 }
874
875 if (mPluginV1_1 == NULL) {
876 return ERROR_DRM_CANNOT_HANDLE;
877 }
878
879 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
880}
881
882status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800883 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800884 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800885
Jeff Tinker15177d72018-01-25 12:57:55 -0800886 if (mPluginV1_1 != NULL) {
887 return toStatusT(mPluginV1_1->removeAllSecureStops());
888 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800889 return toStatusT(mPlugin->releaseAllSecureStops());
890}
891
Jeff Tinker6d998b62017-12-18 14:37:43 -0800892status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
893 DrmPlugin::HdcpLevel *max) const {
894 Mutex::Autolock autoLock(mLock);
895 INIT_CHECK();
896
897 if (connected == NULL || max == NULL) {
898 return BAD_VALUE;
899 }
900 status_t err = UNKNOWN_ERROR;
901
902 if (mPluginV1_1 == NULL) {
903 return ERROR_DRM_CANNOT_HANDLE;
904 }
905
906 *connected = DrmPlugin::kHdcpLevelUnknown;
907 *max = DrmPlugin::kHdcpLevelUnknown;
908
909 Return<void> hResult = mPluginV1_1->getHdcpLevels(
910 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
911 if (status == Status::OK) {
912 *connected = toHdcpLevel(hConnected);
913 *max = toHdcpLevel(hMax);
914 }
915 err = toStatusT(status);
916 }
917 );
918
919 return hResult.isOk() ? err : DEAD_OBJECT;
920}
921
922status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
923 Mutex::Autolock autoLock(mLock);
924 INIT_CHECK();
925
926 if (open == NULL || max == NULL) {
927 return BAD_VALUE;
928 }
929 status_t err = UNKNOWN_ERROR;
930
931 *open = 0;
932 *max = 0;
933
934 if (mPluginV1_1 == NULL) {
935 return ERROR_DRM_CANNOT_HANDLE;
936 }
937
938 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
939 [&](Status status, uint32_t hOpen, uint32_t hMax) {
940 if (status == Status::OK) {
941 *open = hOpen;
942 *max = hMax;
943 }
944 err = toStatusT(status);
945 }
946 );
947
948 return hResult.isOk() ? err : DEAD_OBJECT;
949}
950
951status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
952 DrmPlugin::SecurityLevel *level) const {
953 Mutex::Autolock autoLock(mLock);
954 INIT_CHECK();
955
956 if (level == NULL) {
957 return BAD_VALUE;
958 }
959 status_t err = UNKNOWN_ERROR;
960
961 if (mPluginV1_1 == NULL) {
962 return ERROR_DRM_CANNOT_HANDLE;
963 }
964
965 *level = DrmPlugin::kSecurityLevelUnknown;
966
967 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
968 [&](Status status, SecurityLevel hLevel) {
969 if (status == Status::OK) {
970 *level = toSecurityLevel(hLevel);
971 }
972 err = toStatusT(status);
973 }
974 );
975
976 return hResult.isOk() ? err : DEAD_OBJECT;
977}
978
979status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
980 const DrmPlugin::SecurityLevel& level) {
981 Mutex::Autolock autoLock(mLock);
982 INIT_CHECK();
983
984 if (mPluginV1_1 == NULL) {
985 return ERROR_DRM_CANNOT_HANDLE;
986 }
987
988 SecurityLevel hSecurityLevel;
989
990 switch(level) {
991 case DrmPlugin::kSecurityLevelSwSecureCrypto:
992 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
993 break;
994 case DrmPlugin::kSecurityLevelSwSecureDecode:
995 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
996 break;
997 case DrmPlugin::kSecurityLevelHwSecureCrypto:
998 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
999 break;
1000 case DrmPlugin::kSecurityLevelHwSecureDecode:
1001 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
1002 break;
1003 case DrmPlugin::kSecurityLevelHwSecureAll:
1004 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
1005 break;
1006 default:
1007 return ERROR_DRM_CANNOT_HANDLE;
1008 }
1009
1010 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
1011 hSecurityLevel);
1012 return toStatusT(status);
1013}
1014
Jeff Tinkera53d6552017-01-20 00:31:46 -08001015status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1016 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001017 return getPropertyStringInternal(name, value);
1018}
1019
1020status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1021 // This function is internal to the class and should only be called while
1022 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001023 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001024
1025 status_t err = UNKNOWN_ERROR;
1026
1027 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1028 [&](Status status, const hidl_string& hValue) {
1029 if (status == Status::OK) {
1030 value = toString8(hValue);
1031 }
1032 err = toStatusT(status);
1033 }
1034 );
1035
1036 return hResult.isOk() ? err : DEAD_OBJECT;
1037}
1038
1039status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1040 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001041 return getPropertyByteArrayInternal(name, value);
1042}
1043
1044status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1045 // This function is internal to the class and should only be called while
1046 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001047 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001048
1049 status_t err = UNKNOWN_ERROR;
1050
1051 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1052 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1053 if (status == Status::OK) {
1054 value = toVector(hValue);
1055 }
1056 err = toStatusT(status);
1057 }
1058 );
1059
Adam Stonecea91ce2018-01-22 19:23:28 -08001060 err = hResult.isOk() ? err : DEAD_OBJECT;
1061 if (name == kPropertyDeviceUniqueId) {
1062 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1063 }
1064 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001065}
1066
1067status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1068 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001069 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001070
Jeff Tinker6d998b62017-12-18 14:37:43 -08001071 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001072 toHidlString(value));
1073 return toStatusT(status);
1074}
1075
1076status_t DrmHal::setPropertyByteArray(String8 const &name,
1077 Vector<uint8_t> const &value ) const {
1078 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001079 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001080
1081 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1082 toHidlVec(value));
1083 return toStatusT(status);
1084}
1085
Adam Stonef0e618d2018-01-17 19:20:41 -08001086status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
1087 if (item == nullptr) {
1088 return UNEXPECTED_NULL;
1089 }
1090
1091 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001092 return OK;
1093}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001094
1095status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1096 String8 const &algorithm) {
1097 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001098 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001099
1100 DrmSessionManager::Instance()->useSession(sessionId);
1101
1102 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1103 toHidlString(algorithm));
1104 return toStatusT(status);
1105}
1106
1107status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1108 String8 const &algorithm) {
1109 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001110 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001111
1112 DrmSessionManager::Instance()->useSession(sessionId);
1113
1114 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1115 toHidlString(algorithm));
1116 return toStatusT(status);
1117}
1118
1119status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001120 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1121 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001122 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001123 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001124
1125 DrmSessionManager::Instance()->useSession(sessionId);
1126
1127 status_t err = UNKNOWN_ERROR;
1128
1129 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1130 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1131 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1132 if (status == Status::OK) {
1133 output = toVector(hOutput);
1134 }
1135 err = toStatusT(status);
1136 }
1137 );
1138
1139 return hResult.isOk() ? err : DEAD_OBJECT;
1140}
1141
1142status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001143 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1144 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001145 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001146 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001147
1148 DrmSessionManager::Instance()->useSession(sessionId);
1149
1150 status_t err = UNKNOWN_ERROR;
1151
1152 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1153 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1154 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1155 if (status == Status::OK) {
1156 output = toVector(hOutput);
1157 }
1158 err = toStatusT(status);
1159 }
1160 );
1161
1162 return hResult.isOk() ? err : DEAD_OBJECT;
1163}
1164
1165status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001166 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1167 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001168 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001169 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001170
1171 DrmSessionManager::Instance()->useSession(sessionId);
1172
1173 status_t err = UNKNOWN_ERROR;
1174
1175 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1176 toHidlVec(keyId), toHidlVec(message),
1177 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1178 if (status == Status::OK) {
1179 signature = toVector(hSignature);
1180 }
1181 err = toStatusT(status);
1182 }
1183 );
1184
1185 return hResult.isOk() ? err : DEAD_OBJECT;
1186}
1187
1188status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001189 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1190 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001191 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001192 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001193
1194 DrmSessionManager::Instance()->useSession(sessionId);
1195
1196 status_t err = UNKNOWN_ERROR;
1197
1198 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1199 toHidlVec(message), toHidlVec(signature),
1200 [&](Status status, bool hMatch) {
1201 if (status == Status::OK) {
1202 match = hMatch;
1203 } else {
1204 match = false;
1205 }
1206 err = toStatusT(status);
1207 }
1208 );
1209
1210 return hResult.isOk() ? err : DEAD_OBJECT;
1211}
1212
1213status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001214 String8 const &algorithm, Vector<uint8_t> const &message,
1215 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001216 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001217 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001218
1219 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1220 return -EPERM;
1221 }
1222
1223 DrmSessionManager::Instance()->useSession(sessionId);
1224
1225 status_t err = UNKNOWN_ERROR;
1226
1227 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1228 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1229 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1230 if (status == Status::OK) {
1231 signature = toVector(hSignature);
1232 }
1233 err = toStatusT(status);
1234 }
1235 );
1236
1237 return hResult.isOk() ? err : DEAD_OBJECT;
1238}
1239
1240void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1241{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001242 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001243 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001244 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001245 mInitCheck = NO_INIT;
1246
Jeff Tinker70367f52017-06-16 12:41:33 -07001247 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001248 if (!mPlugin->setListener(NULL).isOk()) {
1249 mInitCheck = DEAD_OBJECT;
1250 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001251 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001252 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001253}
1254
1255void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1256{
1257 if (vec.size()) {
1258 obj.writeInt32(vec.size());
1259 obj.write(vec.data(), vec.size());
1260 } else {
1261 obj.writeInt32(0);
1262 }
1263}
1264
Adam Stoneab394d12017-12-22 12:34:20 -08001265
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001266void DrmHal::reportMetrics() const
1267{
1268 Vector<uint8_t> metrics;
1269 String8 vendor;
1270 String8 description;
1271 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1272 getPropertyStringInternal(String8("description"), description) == OK &&
1273 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1274 status_t res = android::reportDrmPluginMetrics(
1275 metrics, vendor, description);
1276 if (res != OK) {
1277 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1278 }
1279 }
1280}
1281
Jeff Tinkera53d6552017-01-20 00:31:46 -08001282} // namespace android