blob: 84456e23468d5c62313b929beb5ab88ad48398d7 [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;
Adam Stone637b7852018-01-30 12:09:36 -080057using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080058using ::android::sp;
59
Adam Stonecea91ce2018-01-22 19:23:28 -080060namespace {
61
62// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
63// in the MediaDrm API.
64constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
65
66}
67
Jeff Tinkera53d6552017-01-20 00:31:46 -080068namespace android {
69
Jeff Tinker6d998b62017-12-18 14:37:43 -080070#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
71
Jeff Tinkera53d6552017-01-20 00:31:46 -080072static inline int getCallingPid() {
73 return IPCThreadState::self()->getCallingPid();
74}
75
76static bool checkPermission(const char* permissionString) {
77 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
78 bool ok = checkCallingPermission(String16(permissionString));
79 if (!ok) ALOGE("Request requires %s", permissionString);
80 return ok;
81}
82
83static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
84 Vector<uint8_t> vector;
85 vector.appendArray(vec.data(), vec.size());
86 return *const_cast<const Vector<uint8_t> *>(&vector);
87}
88
89static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
90 hidl_vec<uint8_t> vec;
91 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
92 return vec;
93}
94
95static String8 toString8(const hidl_string &string) {
96 return String8(string.c_str());
97}
98
99static hidl_string toHidlString(const String8& string) {
100 return hidl_string(string.string());
101}
102
Jeff Tinker6d998b62017-12-18 14:37:43 -0800103static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
104 switch(level) {
105 case SecurityLevel::SW_SECURE_CRYPTO:
106 return DrmPlugin::kSecurityLevelSwSecureCrypto;
107 case SecurityLevel::SW_SECURE_DECODE:
108 return DrmPlugin::kSecurityLevelSwSecureDecode;
109 case SecurityLevel::HW_SECURE_CRYPTO:
110 return DrmPlugin::kSecurityLevelHwSecureCrypto;
111 case SecurityLevel::HW_SECURE_DECODE:
112 return DrmPlugin::kSecurityLevelHwSecureDecode;
113 case SecurityLevel::HW_SECURE_ALL:
114 return DrmPlugin::kSecurityLevelHwSecureAll;
115 default:
116 return DrmPlugin::kSecurityLevelUnknown;
117 }
118}
119
120static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
121 switch(level) {
122 case HdcpLevel::HDCP_NONE:
123 return DrmPlugin::kHdcpNone;
124 case HdcpLevel::HDCP_V1:
125 return DrmPlugin::kHdcpV1;
126 case HdcpLevel::HDCP_V2:
127 return DrmPlugin::kHdcpV2;
128 case HdcpLevel::HDCP_V2_1:
129 return DrmPlugin::kHdcpV2_1;
130 case HdcpLevel::HDCP_V2_2:
131 return DrmPlugin::kHdcpV2_2;
132 case HdcpLevel::HDCP_NO_OUTPUT:
133 return DrmPlugin::kHdcpNoOutput;
134 default:
135 return DrmPlugin::kHdcpLevelUnknown;
136 }
137}
138
Jeff Tinkera53d6552017-01-20 00:31:46 -0800139
140static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
141 keyedVector) {
142 std::vector<KeyValue> stdKeyedVector;
143 for (size_t i = 0; i < keyedVector.size(); i++) {
144 KeyValue keyValue;
145 keyValue.key = toHidlString(keyedVector.keyAt(i));
146 keyValue.value = toHidlString(keyedVector.valueAt(i));
147 stdKeyedVector.push_back(keyValue);
148 }
149 return ::KeyedVector(stdKeyedVector);
150}
151
152static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
153 hKeyedVector) {
154 KeyedVector<String8, String8> keyedVector;
155 for (size_t i = 0; i < hKeyedVector.size(); i++) {
156 keyedVector.add(toString8(hKeyedVector[i].key),
157 toString8(hKeyedVector[i].value));
158 }
159 return keyedVector;
160}
161
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800162static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800163 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800164 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800165 for (size_t i = 0; i < hSecureStops.size(); i++) {
166 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
167 }
168 return secureStops;
169}
170
Jeff Tinker15177d72018-01-25 12:57:55 -0800171static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
172 hSecureStopIds) {
173 List<Vector<uint8_t>> secureStopIds;
174 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
175 secureStopIds.push_back(toVector(hSecureStopIds[i]));
176 }
177 return secureStopIds;
178}
179
Jeff Tinkera53d6552017-01-20 00:31:46 -0800180static status_t toStatusT(Status status) {
181 switch (status) {
182 case Status::OK:
183 return OK;
184 break;
185 case Status::ERROR_DRM_NO_LICENSE:
186 return ERROR_DRM_NO_LICENSE;
187 break;
188 case Status::ERROR_DRM_LICENSE_EXPIRED:
189 return ERROR_DRM_LICENSE_EXPIRED;
190 break;
191 case Status::ERROR_DRM_SESSION_NOT_OPENED:
192 return ERROR_DRM_SESSION_NOT_OPENED;
193 break;
194 case Status::ERROR_DRM_CANNOT_HANDLE:
195 return ERROR_DRM_CANNOT_HANDLE;
196 break;
197 case Status::ERROR_DRM_INVALID_STATE:
198 return ERROR_DRM_TAMPER_DETECTED;
199 break;
200 case Status::BAD_VALUE:
201 return BAD_VALUE;
202 break;
203 case Status::ERROR_DRM_NOT_PROVISIONED:
204 return ERROR_DRM_NOT_PROVISIONED;
205 break;
206 case Status::ERROR_DRM_RESOURCE_BUSY:
207 return ERROR_DRM_RESOURCE_BUSY;
208 break;
209 case Status::ERROR_DRM_DEVICE_REVOKED:
210 return ERROR_DRM_DEVICE_REVOKED;
211 break;
212 case Status::ERROR_DRM_UNKNOWN:
213 default:
214 return ERROR_DRM_UNKNOWN;
215 break;
216 }
217}
218
219
220Mutex DrmHal::mLock;
221
222struct DrmSessionClient : public DrmSessionClientInterface {
223 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
224
225 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
226 sp<DrmHal> drm = mDrm.promote();
227 if (drm == NULL) {
228 return true;
229 }
230 status_t err = drm->closeSession(sessionId);
231 if (err != OK) {
232 return false;
233 }
234 drm->sendEvent(EventType::SESSION_RECLAIMED,
235 toHidlVec(sessionId), hidl_vec<uint8_t>());
236 return true;
237 }
238
239protected:
240 virtual ~DrmSessionClient() {}
241
242private:
243 wp<DrmHal> mDrm;
244
245 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
246};
247
248DrmHal::DrmHal()
249 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800250 mFactories(makeDrmFactories()),
251 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800252}
253
Jeff Tinker61332812017-05-15 16:53:10 -0700254void DrmHal::closeOpenSessions() {
255 if (mPlugin != NULL) {
Jeff Tinkerb2b66fa2018-01-30 19:19:34 +0000256 for (size_t i = 0; i < mOpenSessions.size(); i++) {
257 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
258 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
Jeff Tinker61332812017-05-15 16:53:10 -0700259 }
260 }
261 mOpenSessions.clear();
262}
263
Jeff Tinkera53d6552017-01-20 00:31:46 -0800264DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700265 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800266 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
267}
268
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800269Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
270 Vector<sp<IDrmFactory>> factories;
271
Jeff Tinker593111f2017-05-25 16:00:21 -0700272 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800273
274 if (manager != NULL) {
275 manager->listByInterface(IDrmFactory::descriptor,
276 [&factories](const hidl_vec<hidl_string> &registered) {
277 for (const auto &instance : registered) {
278 auto factory = IDrmFactory::getService(instance);
279 if (factory != NULL) {
280 factories.push_back(factory);
281 ALOGI("makeDrmFactories: factory instance %s is %s",
282 instance.c_str(),
283 factory->isRemote() ? "Remote" : "Not Remote");
284 }
285 }
286 }
287 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800288 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800289
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800290 if (factories.size() == 0) {
291 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700292 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800293 if (passthrough != NULL) {
294 ALOGI("makeDrmFactories: using default drm instance");
295 factories.push_back(passthrough);
296 } else {
297 ALOGE("Failed to find any drm factories");
298 }
299 }
300 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800301}
302
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800303sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
304 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800305
306 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800307 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800308 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800309 if (status != Status::OK) {
310 ALOGE("Failed to make drm plugin");
311 return;
312 }
313 plugin = hPlugin;
314 }
315 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700316
317 if (!hResult.isOk()) {
318 ALOGE("createPlugin remote call failed");
319 }
320
Jeff Tinkera53d6552017-01-20 00:31:46 -0800321 return plugin;
322}
323
324status_t DrmHal::initCheck() const {
325 return mInitCheck;
326}
327
328status_t DrmHal::setListener(const sp<IDrmClient>& listener)
329{
330 Mutex::Autolock lock(mEventLock);
331 if (mListener != NULL){
332 IInterface::asBinder(mListener)->unlinkToDeath(this);
333 }
334 if (listener != NULL) {
335 IInterface::asBinder(listener)->linkToDeath(this);
336 }
337 mListener = listener;
338 return NO_ERROR;
339}
340
341Return<void> DrmHal::sendEvent(EventType hEventType,
342 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800343 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800344
345 mEventLock.lock();
346 sp<IDrmClient> listener = mListener;
347 mEventLock.unlock();
348
349 if (listener != NULL) {
350 Parcel obj;
351 writeByteArray(obj, sessionId);
352 writeByteArray(obj, data);
353
354 Mutex::Autolock lock(mNotifyLock);
355 DrmPlugin::EventType eventType;
356 switch(hEventType) {
357 case EventType::PROVISION_REQUIRED:
358 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
359 break;
360 case EventType::KEY_NEEDED:
361 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
362 break;
363 case EventType::KEY_EXPIRED:
364 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
365 break;
366 case EventType::VENDOR_DEFINED:
367 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
368 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700369 case EventType::SESSION_RECLAIMED:
370 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
371 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800372 default:
373 return Void();
374 }
375 listener->notify(eventType, 0, &obj);
376 }
377 return Void();
378}
379
380Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
381 int64_t expiryTimeInMS) {
382
383 mEventLock.lock();
384 sp<IDrmClient> listener = mListener;
385 mEventLock.unlock();
386
387 if (listener != NULL) {
388 Parcel obj;
389 writeByteArray(obj, sessionId);
390 obj.writeInt64(expiryTimeInMS);
391
392 Mutex::Autolock lock(mNotifyLock);
393 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
394 }
395 return Void();
396}
397
398Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
399 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
400
401 mEventLock.lock();
402 sp<IDrmClient> listener = mListener;
403 mEventLock.unlock();
404
405 if (listener != NULL) {
406 Parcel obj;
407 writeByteArray(obj, sessionId);
408
409 size_t nKeys = keyStatusList.size();
410 obj.writeInt32(nKeys);
411 for (size_t i = 0; i < nKeys; ++i) {
412 const KeyStatus &keyStatus = keyStatusList[i];
413 writeByteArray(obj, keyStatus.keyId);
414 uint32_t type;
415 switch(keyStatus.type) {
416 case KeyStatusType::USABLE:
417 type = DrmPlugin::kKeyStatusType_Usable;
418 break;
419 case KeyStatusType::EXPIRED:
420 type = DrmPlugin::kKeyStatusType_Expired;
421 break;
422 case KeyStatusType::OUTPUTNOTALLOWED:
423 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
424 break;
425 case KeyStatusType::STATUSPENDING:
426 type = DrmPlugin::kKeyStatusType_StatusPending;
427 break;
428 case KeyStatusType::INTERNALERROR:
429 default:
430 type = DrmPlugin::kKeyStatusType_InternalError;
431 break;
432 }
433 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800434 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800435 }
436 obj.writeInt32(hasNewUsableKey);
437
438 Mutex::Autolock lock(mNotifyLock);
439 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800440 } else {
441 // There's no listener. But we still want to count the key change
442 // events.
443 size_t nKeys = keyStatusList.size();
444 for (size_t i = 0; i < nKeys; i++) {
445 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
446 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800447 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800448
Jeff Tinkera53d6552017-01-20 00:31:46 -0800449 return Void();
450}
451
452bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
453 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800454
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800455 for (size_t i = 0; i < mFactories.size(); i++) {
456 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
457 if (mimeType != "") {
458 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
459 return true;
460 }
461 } else {
462 return true;
463 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800464 }
465 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800466 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800467}
468
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800469status_t DrmHal::createPlugin(const uint8_t uuid[16],
470 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800471 Mutex::Autolock autoLock(mLock);
472
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800473 for (size_t i = 0; i < mFactories.size(); i++) {
474 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
475 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Edwin Wong5641aa22018-01-30 17:52:21 -0800476 if (mPlugin != NULL) {
477 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
478 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800479 }
480 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800481
482 if (mPlugin == NULL) {
483 mInitCheck = ERROR_UNSUPPORTED;
484 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700485 if (!mPlugin->setListener(this).isOk()) {
486 mInitCheck = DEAD_OBJECT;
487 } else {
488 mInitCheck = OK;
489 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800490 }
491
492 return mInitCheck;
493}
494
495status_t DrmHal::destroyPlugin() {
496 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800497 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800498
Jeff Tinker61332812017-05-15 16:53:10 -0700499 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700500 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800501 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700502 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800503
Jeff Tinker319d5f42017-07-26 15:44:33 -0700504 if (mPlugin != NULL) {
505 if (!mPlugin->setListener(NULL).isOk()) {
506 mInitCheck = DEAD_OBJECT;
507 }
508 }
509 mPlugin.clear();
Edwin Wong5641aa22018-01-30 17:52:21 -0800510 mPluginV1_1.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800511 return OK;
512}
513
514status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
515 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800516 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800517
518 status_t err = UNKNOWN_ERROR;
519
520 bool retry = true;
521 do {
522 hidl_vec<uint8_t> hSessionId;
523
524 Return<void> hResult = mPlugin->openSession(
525 [&](Status status, const hidl_vec<uint8_t>& id) {
526 if (status == Status::OK) {
527 sessionId = toVector(id);
528 }
529 err = toStatusT(status);
530 }
531 );
532
533 if (!hResult.isOk()) {
534 err = DEAD_OBJECT;
535 }
536
537 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
538 mLock.unlock();
539 // reclaimSession may call back to closeSession, since mLock is
540 // shared between Drm instances, we should unlock here to avoid
541 // deadlock.
542 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
543 mLock.lock();
544 } else {
545 retry = false;
546 }
547 } while (retry);
548
549 if (err == OK) {
550 DrmSessionManager::Instance()->addSession(getCallingPid(),
551 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700552 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800553 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800554
Adam Stonef0e618d2018-01-17 19:20:41 -0800555 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800556 return err;
557}
558
559status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
560 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800561 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800562
Jeff Tinker319d5f42017-07-26 15:44:33 -0700563 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
564 if (status.isOk()) {
565 if (status == Status::OK) {
566 DrmSessionManager::Instance()->removeSession(sessionId);
567 for (size_t i = 0; i < mOpenSessions.size(); i++) {
568 if (mOpenSessions[i] == sessionId) {
569 mOpenSessions.removeAt(i);
570 break;
571 }
Jeff Tinker61332812017-05-15 16:53:10 -0700572 }
573 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700574 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800575 status_t response = toStatusT(status);
576 mMetrics.mCloseSessionCounter.Increment(response);
577 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800578 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800579 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700580 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800581}
582
583status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
584 Vector<uint8_t> const &initData, String8 const &mimeType,
585 DrmPlugin::KeyType keyType, KeyedVector<String8,
586 String8> const &optionalParameters, Vector<uint8_t> &request,
587 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
588 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800589 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800590 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800591
592 DrmSessionManager::Instance()->useSession(sessionId);
593
594 KeyType hKeyType;
595 if (keyType == DrmPlugin::kKeyType_Streaming) {
596 hKeyType = KeyType::STREAMING;
597 } else if (keyType == DrmPlugin::kKeyType_Offline) {
598 hKeyType = KeyType::OFFLINE;
599 } else if (keyType == DrmPlugin::kKeyType_Release) {
600 hKeyType = KeyType::RELEASE;
601 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800602 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800603 return BAD_VALUE;
604 }
605
606 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
607
608 status_t err = UNKNOWN_ERROR;
609
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800610 if (mPluginV1_1 != NULL) {
611 Return<void> hResult =
612 mPluginV1_1->getKeyRequest_1_1(
613 toHidlVec(sessionId), toHidlVec(initData),
614 toHidlString(mimeType), hKeyType, hOptionalParameters,
615 [&](Status status, const hidl_vec<uint8_t>& hRequest,
616 drm::V1_1::KeyRequestType hKeyRequestType,
617 const hidl_string& hDefaultUrl) {
618
619 if (status == Status::OK) {
620 request = toVector(hRequest);
621 defaultUrl = toString8(hDefaultUrl);
622
623 switch (hKeyRequestType) {
624 case drm::V1_1::KeyRequestType::INITIAL:
625 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
626 break;
627 case drm::V1_1::KeyRequestType::RENEWAL:
628 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
629 break;
630 case drm::V1_1::KeyRequestType::RELEASE:
631 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
632 break;
633 case drm::V1_1::KeyRequestType::NONE:
634 *keyRequestType = DrmPlugin::kKeyRequestType_None;
635 break;
636 case drm::V1_1::KeyRequestType::UPDATE:
637 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
638 break;
639 default:
640 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
641 break;
642 }
643 err = toStatusT(status);
644 }
645 });
646 return hResult.isOk() ? err : DEAD_OBJECT;
647 }
648
Jeff Tinkera53d6552017-01-20 00:31:46 -0800649 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
650 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
651 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800652 drm::V1_0::KeyRequestType hKeyRequestType,
653 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800654
655 if (status == Status::OK) {
656 request = toVector(hRequest);
657 defaultUrl = toString8(hDefaultUrl);
658
659 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800660 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800661 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
662 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800663 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
665 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800666 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800667 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
668 break;
669 default:
670 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
671 break;
672 }
673 err = toStatusT(status);
674 }
675 });
676
Adam Stonef0e618d2018-01-17 19:20:41 -0800677 err = hResult.isOk() ? err : DEAD_OBJECT;
678 keyRequestTimer.SetAttribute(err);
679 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800680}
681
682status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
683 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
684 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800685 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
686
Jeff Tinker6d998b62017-12-18 14:37:43 -0800687 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800688
689 DrmSessionManager::Instance()->useSession(sessionId);
690
691 status_t err = UNKNOWN_ERROR;
692
693 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
694 toHidlVec(response),
695 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
696 if (status == Status::OK) {
697 keySetId = toVector(hKeySetId);
698 }
699 err = toStatusT(status);
700 }
701 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800702 err = hResult.isOk() ? err : DEAD_OBJECT;
703 keyResponseTimer.SetAttribute(err);
704 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800705}
706
707status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
708 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800709 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800710
711 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
712}
713
714status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
715 Vector<uint8_t> const &keySetId) {
716 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800717 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800718
719 DrmSessionManager::Instance()->useSession(sessionId);
720
721 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
722 toHidlVec(keySetId)));
723}
724
725status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
726 KeyedVector<String8, String8> &infoMap) const {
727 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800728 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800729
730 DrmSessionManager::Instance()->useSession(sessionId);
731
732 ::KeyedVector hInfoMap;
733
734 status_t err = UNKNOWN_ERROR;
735
736 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
737 [&](Status status, const hidl_vec<KeyValue>& map) {
738 if (status == Status::OK) {
739 infoMap = toKeyedVector(map);
740 }
741 err = toStatusT(status);
742 }
743 );
744
745 return hResult.isOk() ? err : DEAD_OBJECT;
746}
747
748status_t DrmHal::getProvisionRequest(String8 const &certType,
749 String8 const &certAuthority, Vector<uint8_t> &request,
750 String8 &defaultUrl) {
751 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800752 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800753
754 status_t err = UNKNOWN_ERROR;
755
756 Return<void> hResult = mPlugin->getProvisionRequest(
757 toHidlString(certType), toHidlString(certAuthority),
758 [&](Status status, const hidl_vec<uint8_t>& hRequest,
759 const hidl_string& hDefaultUrl) {
760 if (status == Status::OK) {
761 request = toVector(hRequest);
762 defaultUrl = toString8(hDefaultUrl);
763 }
764 err = toStatusT(status);
765 }
766 );
767
Adam Stonecea91ce2018-01-22 19:23:28 -0800768 err = hResult.isOk() ? err : DEAD_OBJECT;
769 mMetrics.mGetProvisionRequestCounter.Increment(err);
770 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800771}
772
773status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800774 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800775 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800776 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800777
778 status_t err = UNKNOWN_ERROR;
779
780 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
781 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
782 const hidl_vec<uint8_t>& hWrappedKey) {
783 if (status == Status::OK) {
784 certificate = toVector(hCertificate);
785 wrappedKey = toVector(hWrappedKey);
786 }
787 err = toStatusT(status);
788 }
789 );
790
Adam Stonecea91ce2018-01-22 19:23:28 -0800791 err = hResult.isOk() ? err : DEAD_OBJECT;
792 mMetrics.mProvideProvisionResponseCounter.Increment(err);
793 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800794}
795
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800796status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800797 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800798 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800799
800 status_t err = UNKNOWN_ERROR;
801
802 Return<void> hResult = mPlugin->getSecureStops(
803 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
804 if (status == Status::OK) {
805 secureStops = toSecureStops(hSecureStops);
806 }
807 err = toStatusT(status);
808 }
809 );
810
811 return hResult.isOk() ? err : DEAD_OBJECT;
812}
813
814
Jeff Tinker15177d72018-01-25 12:57:55 -0800815status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
816 Mutex::Autolock autoLock(mLock);
817
818 if (mInitCheck != OK) {
819 return mInitCheck;
820 }
821
822 if (mPluginV1_1 == NULL) {
823 return ERROR_DRM_CANNOT_HANDLE;
824 }
825
826 status_t err = UNKNOWN_ERROR;
827
828 Return<void> hResult = mPluginV1_1->getSecureStopIds(
829 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
830 if (status == Status::OK) {
831 secureStopIds = toSecureStopIds(hSecureStopIds);
832 }
833 err = toStatusT(status);
834 }
835 );
836
837 return hResult.isOk() ? err : DEAD_OBJECT;
838}
839
840
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
842 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800843 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800844
845 status_t err = UNKNOWN_ERROR;
846
847 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
848 [&](Status status, const SecureStop& hSecureStop) {
849 if (status == Status::OK) {
850 secureStop = toVector(hSecureStop.opaqueData);
851 }
852 err = toStatusT(status);
853 }
854 );
855
856 return hResult.isOk() ? err : DEAD_OBJECT;
857}
858
859status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
860 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800861 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800862
Jeff Tinker15177d72018-01-25 12:57:55 -0800863 if (mPluginV1_1 != NULL) {
864 SecureStopRelease secureStopRelease;
865 secureStopRelease.opaqueData = toHidlVec(ssRelease);
866 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
867 }
868
Jeff Tinkera53d6552017-01-20 00:31:46 -0800869 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
870}
871
Jeff Tinker15177d72018-01-25 12:57:55 -0800872status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
873 Mutex::Autolock autoLock(mLock);
874
875 if (mInitCheck != OK) {
876 return mInitCheck;
877 }
878
879 if (mPluginV1_1 == NULL) {
880 return ERROR_DRM_CANNOT_HANDLE;
881 }
882
883 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
884}
885
886status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800887 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800888 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800889
Jeff Tinker15177d72018-01-25 12:57:55 -0800890 if (mPluginV1_1 != NULL) {
891 return toStatusT(mPluginV1_1->removeAllSecureStops());
892 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800893 return toStatusT(mPlugin->releaseAllSecureStops());
894}
895
Jeff Tinker6d998b62017-12-18 14:37:43 -0800896status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
897 DrmPlugin::HdcpLevel *max) const {
898 Mutex::Autolock autoLock(mLock);
899 INIT_CHECK();
900
901 if (connected == NULL || max == NULL) {
902 return BAD_VALUE;
903 }
904 status_t err = UNKNOWN_ERROR;
905
906 if (mPluginV1_1 == NULL) {
907 return ERROR_DRM_CANNOT_HANDLE;
908 }
909
910 *connected = DrmPlugin::kHdcpLevelUnknown;
911 *max = DrmPlugin::kHdcpLevelUnknown;
912
913 Return<void> hResult = mPluginV1_1->getHdcpLevels(
914 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
915 if (status == Status::OK) {
916 *connected = toHdcpLevel(hConnected);
917 *max = toHdcpLevel(hMax);
918 }
919 err = toStatusT(status);
920 }
921 );
922
923 return hResult.isOk() ? err : DEAD_OBJECT;
924}
925
926status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
927 Mutex::Autolock autoLock(mLock);
928 INIT_CHECK();
929
930 if (open == NULL || max == NULL) {
931 return BAD_VALUE;
932 }
933 status_t err = UNKNOWN_ERROR;
934
935 *open = 0;
936 *max = 0;
937
938 if (mPluginV1_1 == NULL) {
939 return ERROR_DRM_CANNOT_HANDLE;
940 }
941
942 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
943 [&](Status status, uint32_t hOpen, uint32_t hMax) {
944 if (status == Status::OK) {
945 *open = hOpen;
946 *max = hMax;
947 }
948 err = toStatusT(status);
949 }
950 );
951
952 return hResult.isOk() ? err : DEAD_OBJECT;
953}
954
955status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
956 DrmPlugin::SecurityLevel *level) const {
957 Mutex::Autolock autoLock(mLock);
958 INIT_CHECK();
959
960 if (level == NULL) {
961 return BAD_VALUE;
962 }
963 status_t err = UNKNOWN_ERROR;
964
965 if (mPluginV1_1 == NULL) {
966 return ERROR_DRM_CANNOT_HANDLE;
967 }
968
969 *level = DrmPlugin::kSecurityLevelUnknown;
970
971 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
972 [&](Status status, SecurityLevel hLevel) {
973 if (status == Status::OK) {
974 *level = toSecurityLevel(hLevel);
975 }
976 err = toStatusT(status);
977 }
978 );
979
980 return hResult.isOk() ? err : DEAD_OBJECT;
981}
982
983status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
984 const DrmPlugin::SecurityLevel& level) {
985 Mutex::Autolock autoLock(mLock);
986 INIT_CHECK();
987
988 if (mPluginV1_1 == NULL) {
989 return ERROR_DRM_CANNOT_HANDLE;
990 }
991
992 SecurityLevel hSecurityLevel;
993
994 switch(level) {
995 case DrmPlugin::kSecurityLevelSwSecureCrypto:
996 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
997 break;
998 case DrmPlugin::kSecurityLevelSwSecureDecode:
999 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
1000 break;
1001 case DrmPlugin::kSecurityLevelHwSecureCrypto:
1002 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
1003 break;
1004 case DrmPlugin::kSecurityLevelHwSecureDecode:
1005 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
1006 break;
1007 case DrmPlugin::kSecurityLevelHwSecureAll:
1008 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
1009 break;
1010 default:
1011 return ERROR_DRM_CANNOT_HANDLE;
1012 }
1013
1014 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
1015 hSecurityLevel);
1016 return toStatusT(status);
1017}
1018
Jeff Tinkera53d6552017-01-20 00:31:46 -08001019status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1020 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001021 return getPropertyStringInternal(name, value);
1022}
1023
1024status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1025 // This function is internal to the class and should only be called while
1026 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001027 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001028
1029 status_t err = UNKNOWN_ERROR;
1030
1031 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1032 [&](Status status, const hidl_string& hValue) {
1033 if (status == Status::OK) {
1034 value = toString8(hValue);
1035 }
1036 err = toStatusT(status);
1037 }
1038 );
1039
1040 return hResult.isOk() ? err : DEAD_OBJECT;
1041}
1042
1043status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1044 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001045 return getPropertyByteArrayInternal(name, value);
1046}
1047
1048status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1049 // This function is internal to the class and should only be called while
1050 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001051 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001052
1053 status_t err = UNKNOWN_ERROR;
1054
1055 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1056 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1057 if (status == Status::OK) {
1058 value = toVector(hValue);
1059 }
1060 err = toStatusT(status);
1061 }
1062 );
1063
Adam Stonecea91ce2018-01-22 19:23:28 -08001064 err = hResult.isOk() ? err : DEAD_OBJECT;
1065 if (name == kPropertyDeviceUniqueId) {
1066 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1067 }
1068 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001069}
1070
1071status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1072 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001073 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001074
Jeff Tinker6d998b62017-12-18 14:37:43 -08001075 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001076 toHidlString(value));
1077 return toStatusT(status);
1078}
1079
1080status_t DrmHal::setPropertyByteArray(String8 const &name,
1081 Vector<uint8_t> const &value ) const {
1082 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001083 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001084
1085 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1086 toHidlVec(value));
1087 return toStatusT(status);
1088}
1089
Adam Stone637b7852018-01-30 12:09:36 -08001090status_t DrmHal::getMetrics(PersistableBundle* item) {
Adam Stonef0e618d2018-01-17 19:20:41 -08001091 if (item == nullptr) {
1092 return UNEXPECTED_NULL;
1093 }
1094
1095 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001096 return OK;
1097}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001098
1099status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1100 String8 const &algorithm) {
1101 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001102 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001103
1104 DrmSessionManager::Instance()->useSession(sessionId);
1105
1106 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1107 toHidlString(algorithm));
1108 return toStatusT(status);
1109}
1110
1111status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1112 String8 const &algorithm) {
1113 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001114 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001115
1116 DrmSessionManager::Instance()->useSession(sessionId);
1117
1118 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1119 toHidlString(algorithm));
1120 return toStatusT(status);
1121}
1122
1123status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001124 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1125 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001126 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001127 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001128
1129 DrmSessionManager::Instance()->useSession(sessionId);
1130
1131 status_t err = UNKNOWN_ERROR;
1132
1133 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1134 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1135 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1136 if (status == Status::OK) {
1137 output = toVector(hOutput);
1138 }
1139 err = toStatusT(status);
1140 }
1141 );
1142
1143 return hResult.isOk() ? err : DEAD_OBJECT;
1144}
1145
1146status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001147 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1148 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001149 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001150 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001151
1152 DrmSessionManager::Instance()->useSession(sessionId);
1153
1154 status_t err = UNKNOWN_ERROR;
1155
1156 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1157 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1158 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1159 if (status == Status::OK) {
1160 output = toVector(hOutput);
1161 }
1162 err = toStatusT(status);
1163 }
1164 );
1165
1166 return hResult.isOk() ? err : DEAD_OBJECT;
1167}
1168
1169status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001170 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1171 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001172 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001173 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001174
1175 DrmSessionManager::Instance()->useSession(sessionId);
1176
1177 status_t err = UNKNOWN_ERROR;
1178
1179 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1180 toHidlVec(keyId), toHidlVec(message),
1181 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1182 if (status == Status::OK) {
1183 signature = toVector(hSignature);
1184 }
1185 err = toStatusT(status);
1186 }
1187 );
1188
1189 return hResult.isOk() ? err : DEAD_OBJECT;
1190}
1191
1192status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001193 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1194 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001195 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001196 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001197
1198 DrmSessionManager::Instance()->useSession(sessionId);
1199
1200 status_t err = UNKNOWN_ERROR;
1201
1202 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1203 toHidlVec(message), toHidlVec(signature),
1204 [&](Status status, bool hMatch) {
1205 if (status == Status::OK) {
1206 match = hMatch;
1207 } else {
1208 match = false;
1209 }
1210 err = toStatusT(status);
1211 }
1212 );
1213
1214 return hResult.isOk() ? err : DEAD_OBJECT;
1215}
1216
1217status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001218 String8 const &algorithm, Vector<uint8_t> const &message,
1219 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001220 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001221 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001222
1223 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1224 return -EPERM;
1225 }
1226
1227 DrmSessionManager::Instance()->useSession(sessionId);
1228
1229 status_t err = UNKNOWN_ERROR;
1230
1231 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1232 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1233 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1234 if (status == Status::OK) {
1235 signature = toVector(hSignature);
1236 }
1237 err = toStatusT(status);
1238 }
1239 );
1240
1241 return hResult.isOk() ? err : DEAD_OBJECT;
1242}
1243
1244void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1245{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001246 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001247 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001248 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001249 mInitCheck = NO_INIT;
1250
Jeff Tinker70367f52017-06-16 12:41:33 -07001251 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001252 if (!mPlugin->setListener(NULL).isOk()) {
1253 mInitCheck = DEAD_OBJECT;
1254 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001255 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001256 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001257}
1258
1259void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1260{
1261 if (vec.size()) {
1262 obj.writeInt32(vec.size());
1263 obj.write(vec.data(), vec.size());
1264 } else {
1265 obj.writeInt32(0);
1266 }
1267}
1268
Adam Stoneab394d12017-12-22 12:34:20 -08001269
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001270void DrmHal::reportMetrics() const
1271{
1272 Vector<uint8_t> metrics;
1273 String8 vendor;
1274 String8 description;
1275 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1276 getPropertyStringInternal(String8("description"), description) == OK &&
1277 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1278 status_t res = android::reportDrmPluginMetrics(
1279 metrics, vendor, description);
1280 if (res != OK) {
1281 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1282 }
1283 }
1284}
1285
Jeff Tinkera53d6552017-01-20 00:31:46 -08001286} // namespace android