blob: c88c8365b19dde0f687c600df4d239dc98ea71d1 [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);
Adam Stone568b3c42018-01-31 12:57:16 -0800553 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800554 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800555
Adam Stonef0e618d2018-01-17 19:20:41 -0800556 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800557 return err;
558}
559
560status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
561 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800562 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800563
Jeff Tinker319d5f42017-07-26 15:44:33 -0700564 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
565 if (status.isOk()) {
566 if (status == Status::OK) {
567 DrmSessionManager::Instance()->removeSession(sessionId);
568 for (size_t i = 0; i < mOpenSessions.size(); i++) {
569 if (mOpenSessions[i] == sessionId) {
570 mOpenSessions.removeAt(i);
571 break;
572 }
Jeff Tinker61332812017-05-15 16:53:10 -0700573 }
574 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800575 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800576 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800577 mMetrics.mCloseSessionCounter.Increment(response);
Adam Stone568b3c42018-01-31 12:57:16 -0800578 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800579 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800580 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800581 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700582 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583}
584
585status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
586 Vector<uint8_t> const &initData, String8 const &mimeType,
587 DrmPlugin::KeyType keyType, KeyedVector<String8,
588 String8> const &optionalParameters, Vector<uint8_t> &request,
589 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
590 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800591 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800592 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800593
594 DrmSessionManager::Instance()->useSession(sessionId);
595
596 KeyType hKeyType;
597 if (keyType == DrmPlugin::kKeyType_Streaming) {
598 hKeyType = KeyType::STREAMING;
599 } else if (keyType == DrmPlugin::kKeyType_Offline) {
600 hKeyType = KeyType::OFFLINE;
601 } else if (keyType == DrmPlugin::kKeyType_Release) {
602 hKeyType = KeyType::RELEASE;
603 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800604 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800605 return BAD_VALUE;
606 }
607
608 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
609
610 status_t err = UNKNOWN_ERROR;
611
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800612 if (mPluginV1_1 != NULL) {
613 Return<void> hResult =
614 mPluginV1_1->getKeyRequest_1_1(
615 toHidlVec(sessionId), toHidlVec(initData),
616 toHidlString(mimeType), hKeyType, hOptionalParameters,
617 [&](Status status, const hidl_vec<uint8_t>& hRequest,
618 drm::V1_1::KeyRequestType hKeyRequestType,
619 const hidl_string& hDefaultUrl) {
620
621 if (status == Status::OK) {
622 request = toVector(hRequest);
623 defaultUrl = toString8(hDefaultUrl);
624
625 switch (hKeyRequestType) {
626 case drm::V1_1::KeyRequestType::INITIAL:
627 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
628 break;
629 case drm::V1_1::KeyRequestType::RENEWAL:
630 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
631 break;
632 case drm::V1_1::KeyRequestType::RELEASE:
633 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
634 break;
635 case drm::V1_1::KeyRequestType::NONE:
636 *keyRequestType = DrmPlugin::kKeyRequestType_None;
637 break;
638 case drm::V1_1::KeyRequestType::UPDATE:
639 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
640 break;
641 default:
642 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
643 break;
644 }
645 err = toStatusT(status);
646 }
647 });
648 return hResult.isOk() ? err : DEAD_OBJECT;
649 }
650
Jeff Tinkera53d6552017-01-20 00:31:46 -0800651 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
652 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
653 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800654 drm::V1_0::KeyRequestType hKeyRequestType,
655 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800656
657 if (status == Status::OK) {
658 request = toVector(hRequest);
659 defaultUrl = toString8(hDefaultUrl);
660
661 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800662 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800663 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
664 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800665 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800666 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
667 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800668 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800669 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
670 break;
671 default:
672 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
673 break;
674 }
675 err = toStatusT(status);
676 }
677 });
678
Adam Stonef0e618d2018-01-17 19:20:41 -0800679 err = hResult.isOk() ? err : DEAD_OBJECT;
680 keyRequestTimer.SetAttribute(err);
681 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800682}
683
684status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
685 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
686 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800687 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
688
Jeff Tinker6d998b62017-12-18 14:37:43 -0800689 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800690
691 DrmSessionManager::Instance()->useSession(sessionId);
692
693 status_t err = UNKNOWN_ERROR;
694
695 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
696 toHidlVec(response),
697 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
698 if (status == Status::OK) {
699 keySetId = toVector(hKeySetId);
700 }
701 err = toStatusT(status);
702 }
703 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800704 err = hResult.isOk() ? err : DEAD_OBJECT;
705 keyResponseTimer.SetAttribute(err);
706 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800707}
708
709status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
710 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800711 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800712
713 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
714}
715
716status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
717 Vector<uint8_t> const &keySetId) {
718 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800719 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800720
721 DrmSessionManager::Instance()->useSession(sessionId);
722
723 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
724 toHidlVec(keySetId)));
725}
726
727status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
728 KeyedVector<String8, String8> &infoMap) const {
729 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800730 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800731
732 DrmSessionManager::Instance()->useSession(sessionId);
733
734 ::KeyedVector hInfoMap;
735
736 status_t err = UNKNOWN_ERROR;
737
738 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
739 [&](Status status, const hidl_vec<KeyValue>& map) {
740 if (status == Status::OK) {
741 infoMap = toKeyedVector(map);
742 }
743 err = toStatusT(status);
744 }
745 );
746
747 return hResult.isOk() ? err : DEAD_OBJECT;
748}
749
750status_t DrmHal::getProvisionRequest(String8 const &certType,
751 String8 const &certAuthority, Vector<uint8_t> &request,
752 String8 &defaultUrl) {
753 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800754 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800755
756 status_t err = UNKNOWN_ERROR;
757
758 Return<void> hResult = mPlugin->getProvisionRequest(
759 toHidlString(certType), toHidlString(certAuthority),
760 [&](Status status, const hidl_vec<uint8_t>& hRequest,
761 const hidl_string& hDefaultUrl) {
762 if (status == Status::OK) {
763 request = toVector(hRequest);
764 defaultUrl = toString8(hDefaultUrl);
765 }
766 err = toStatusT(status);
767 }
768 );
769
Adam Stonecea91ce2018-01-22 19:23:28 -0800770 err = hResult.isOk() ? err : DEAD_OBJECT;
771 mMetrics.mGetProvisionRequestCounter.Increment(err);
772 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773}
774
775status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800776 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800777 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800778 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800779
780 status_t err = UNKNOWN_ERROR;
781
782 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
783 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
784 const hidl_vec<uint8_t>& hWrappedKey) {
785 if (status == Status::OK) {
786 certificate = toVector(hCertificate);
787 wrappedKey = toVector(hWrappedKey);
788 }
789 err = toStatusT(status);
790 }
791 );
792
Adam Stonecea91ce2018-01-22 19:23:28 -0800793 err = hResult.isOk() ? err : DEAD_OBJECT;
794 mMetrics.mProvideProvisionResponseCounter.Increment(err);
795 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800796}
797
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800798status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800799 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800800 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800801
802 status_t err = UNKNOWN_ERROR;
803
804 Return<void> hResult = mPlugin->getSecureStops(
805 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
806 if (status == Status::OK) {
807 secureStops = toSecureStops(hSecureStops);
808 }
809 err = toStatusT(status);
810 }
811 );
812
813 return hResult.isOk() ? err : DEAD_OBJECT;
814}
815
816
Jeff Tinker15177d72018-01-25 12:57:55 -0800817status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
818 Mutex::Autolock autoLock(mLock);
819
820 if (mInitCheck != OK) {
821 return mInitCheck;
822 }
823
824 if (mPluginV1_1 == NULL) {
825 return ERROR_DRM_CANNOT_HANDLE;
826 }
827
828 status_t err = UNKNOWN_ERROR;
829
830 Return<void> hResult = mPluginV1_1->getSecureStopIds(
831 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
832 if (status == Status::OK) {
833 secureStopIds = toSecureStopIds(hSecureStopIds);
834 }
835 err = toStatusT(status);
836 }
837 );
838
839 return hResult.isOk() ? err : DEAD_OBJECT;
840}
841
842
Jeff Tinkera53d6552017-01-20 00:31:46 -0800843status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
844 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800845 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800846
847 status_t err = UNKNOWN_ERROR;
848
849 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
850 [&](Status status, const SecureStop& hSecureStop) {
851 if (status == Status::OK) {
852 secureStop = toVector(hSecureStop.opaqueData);
853 }
854 err = toStatusT(status);
855 }
856 );
857
858 return hResult.isOk() ? err : DEAD_OBJECT;
859}
860
861status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
862 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800863 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800864
Jeff Tinker15177d72018-01-25 12:57:55 -0800865 if (mPluginV1_1 != NULL) {
866 SecureStopRelease secureStopRelease;
867 secureStopRelease.opaqueData = toHidlVec(ssRelease);
868 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
869 }
870
Jeff Tinkera53d6552017-01-20 00:31:46 -0800871 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
872}
873
Jeff Tinker15177d72018-01-25 12:57:55 -0800874status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
875 Mutex::Autolock autoLock(mLock);
876
877 if (mInitCheck != OK) {
878 return mInitCheck;
879 }
880
881 if (mPluginV1_1 == NULL) {
882 return ERROR_DRM_CANNOT_HANDLE;
883 }
884
885 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
886}
887
888status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800889 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800890 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800891
Jeff Tinker15177d72018-01-25 12:57:55 -0800892 if (mPluginV1_1 != NULL) {
893 return toStatusT(mPluginV1_1->removeAllSecureStops());
894 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800895 return toStatusT(mPlugin->releaseAllSecureStops());
896}
897
Jeff Tinker6d998b62017-12-18 14:37:43 -0800898status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
899 DrmPlugin::HdcpLevel *max) const {
900 Mutex::Autolock autoLock(mLock);
901 INIT_CHECK();
902
903 if (connected == NULL || max == NULL) {
904 return BAD_VALUE;
905 }
906 status_t err = UNKNOWN_ERROR;
907
908 if (mPluginV1_1 == NULL) {
909 return ERROR_DRM_CANNOT_HANDLE;
910 }
911
912 *connected = DrmPlugin::kHdcpLevelUnknown;
913 *max = DrmPlugin::kHdcpLevelUnknown;
914
915 Return<void> hResult = mPluginV1_1->getHdcpLevels(
916 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
917 if (status == Status::OK) {
918 *connected = toHdcpLevel(hConnected);
919 *max = toHdcpLevel(hMax);
920 }
921 err = toStatusT(status);
922 }
923 );
924
925 return hResult.isOk() ? err : DEAD_OBJECT;
926}
927
928status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
929 Mutex::Autolock autoLock(mLock);
930 INIT_CHECK();
931
932 if (open == NULL || max == NULL) {
933 return BAD_VALUE;
934 }
935 status_t err = UNKNOWN_ERROR;
936
937 *open = 0;
938 *max = 0;
939
940 if (mPluginV1_1 == NULL) {
941 return ERROR_DRM_CANNOT_HANDLE;
942 }
943
944 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
945 [&](Status status, uint32_t hOpen, uint32_t hMax) {
946 if (status == Status::OK) {
947 *open = hOpen;
948 *max = hMax;
949 }
950 err = toStatusT(status);
951 }
952 );
953
954 return hResult.isOk() ? err : DEAD_OBJECT;
955}
956
957status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
958 DrmPlugin::SecurityLevel *level) const {
959 Mutex::Autolock autoLock(mLock);
960 INIT_CHECK();
961
962 if (level == NULL) {
963 return BAD_VALUE;
964 }
965 status_t err = UNKNOWN_ERROR;
966
967 if (mPluginV1_1 == NULL) {
968 return ERROR_DRM_CANNOT_HANDLE;
969 }
970
971 *level = DrmPlugin::kSecurityLevelUnknown;
972
973 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
974 [&](Status status, SecurityLevel hLevel) {
975 if (status == Status::OK) {
976 *level = toSecurityLevel(hLevel);
977 }
978 err = toStatusT(status);
979 }
980 );
981
982 return hResult.isOk() ? err : DEAD_OBJECT;
983}
984
985status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
986 const DrmPlugin::SecurityLevel& level) {
987 Mutex::Autolock autoLock(mLock);
988 INIT_CHECK();
989
990 if (mPluginV1_1 == NULL) {
991 return ERROR_DRM_CANNOT_HANDLE;
992 }
993
994 SecurityLevel hSecurityLevel;
995
996 switch(level) {
997 case DrmPlugin::kSecurityLevelSwSecureCrypto:
998 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
999 break;
1000 case DrmPlugin::kSecurityLevelSwSecureDecode:
1001 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
1002 break;
1003 case DrmPlugin::kSecurityLevelHwSecureCrypto:
1004 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
1005 break;
1006 case DrmPlugin::kSecurityLevelHwSecureDecode:
1007 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
1008 break;
1009 case DrmPlugin::kSecurityLevelHwSecureAll:
1010 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
1011 break;
1012 default:
1013 return ERROR_DRM_CANNOT_HANDLE;
1014 }
1015
1016 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
1017 hSecurityLevel);
1018 return toStatusT(status);
1019}
1020
Jeff Tinkera53d6552017-01-20 00:31:46 -08001021status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1022 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001023 return getPropertyStringInternal(name, value);
1024}
1025
1026status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1027 // This function is internal to the class and should only be called while
1028 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001029 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001030
1031 status_t err = UNKNOWN_ERROR;
1032
1033 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1034 [&](Status status, const hidl_string& hValue) {
1035 if (status == Status::OK) {
1036 value = toString8(hValue);
1037 }
1038 err = toStatusT(status);
1039 }
1040 );
1041
1042 return hResult.isOk() ? err : DEAD_OBJECT;
1043}
1044
1045status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1046 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001047 return getPropertyByteArrayInternal(name, value);
1048}
1049
1050status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1051 // This function is internal to the class and should only be called while
1052 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001053 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001054
1055 status_t err = UNKNOWN_ERROR;
1056
1057 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1058 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1059 if (status == Status::OK) {
1060 value = toVector(hValue);
1061 }
1062 err = toStatusT(status);
1063 }
1064 );
1065
Adam Stonecea91ce2018-01-22 19:23:28 -08001066 err = hResult.isOk() ? err : DEAD_OBJECT;
1067 if (name == kPropertyDeviceUniqueId) {
1068 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1069 }
1070 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001071}
1072
1073status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1074 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001075 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001076
Jeff Tinker6d998b62017-12-18 14:37:43 -08001077 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001078 toHidlString(value));
1079 return toStatusT(status);
1080}
1081
1082status_t DrmHal::setPropertyByteArray(String8 const &name,
1083 Vector<uint8_t> const &value ) const {
1084 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001085 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001086
1087 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1088 toHidlVec(value));
1089 return toStatusT(status);
1090}
1091
Adam Stone637b7852018-01-30 12:09:36 -08001092status_t DrmHal::getMetrics(PersistableBundle* item) {
Adam Stonef0e618d2018-01-17 19:20:41 -08001093 if (item == nullptr) {
1094 return UNEXPECTED_NULL;
1095 }
1096
1097 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001098 return OK;
1099}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001100
1101status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1102 String8 const &algorithm) {
1103 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001104 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001105
1106 DrmSessionManager::Instance()->useSession(sessionId);
1107
1108 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1109 toHidlString(algorithm));
1110 return toStatusT(status);
1111}
1112
1113status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1114 String8 const &algorithm) {
1115 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001116 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001117
1118 DrmSessionManager::Instance()->useSession(sessionId);
1119
1120 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1121 toHidlString(algorithm));
1122 return toStatusT(status);
1123}
1124
1125status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001126 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1127 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001128 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001129 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001130
1131 DrmSessionManager::Instance()->useSession(sessionId);
1132
1133 status_t err = UNKNOWN_ERROR;
1134
1135 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1136 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1137 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1138 if (status == Status::OK) {
1139 output = toVector(hOutput);
1140 }
1141 err = toStatusT(status);
1142 }
1143 );
1144
1145 return hResult.isOk() ? err : DEAD_OBJECT;
1146}
1147
1148status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001149 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1150 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001151 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001152 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001153
1154 DrmSessionManager::Instance()->useSession(sessionId);
1155
1156 status_t err = UNKNOWN_ERROR;
1157
1158 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1159 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1160 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1161 if (status == Status::OK) {
1162 output = toVector(hOutput);
1163 }
1164 err = toStatusT(status);
1165 }
1166 );
1167
1168 return hResult.isOk() ? err : DEAD_OBJECT;
1169}
1170
1171status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001172 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1173 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001174 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001175 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001176
1177 DrmSessionManager::Instance()->useSession(sessionId);
1178
1179 status_t err = UNKNOWN_ERROR;
1180
1181 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1182 toHidlVec(keyId), toHidlVec(message),
1183 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1184 if (status == Status::OK) {
1185 signature = toVector(hSignature);
1186 }
1187 err = toStatusT(status);
1188 }
1189 );
1190
1191 return hResult.isOk() ? err : DEAD_OBJECT;
1192}
1193
1194status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001195 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1196 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001197 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001198 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001199
1200 DrmSessionManager::Instance()->useSession(sessionId);
1201
1202 status_t err = UNKNOWN_ERROR;
1203
1204 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1205 toHidlVec(message), toHidlVec(signature),
1206 [&](Status status, bool hMatch) {
1207 if (status == Status::OK) {
1208 match = hMatch;
1209 } else {
1210 match = false;
1211 }
1212 err = toStatusT(status);
1213 }
1214 );
1215
1216 return hResult.isOk() ? err : DEAD_OBJECT;
1217}
1218
1219status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001220 String8 const &algorithm, Vector<uint8_t> const &message,
1221 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001222 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001223 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001224
1225 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1226 return -EPERM;
1227 }
1228
1229 DrmSessionManager::Instance()->useSession(sessionId);
1230
1231 status_t err = UNKNOWN_ERROR;
1232
1233 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1234 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1235 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1236 if (status == Status::OK) {
1237 signature = toVector(hSignature);
1238 }
1239 err = toStatusT(status);
1240 }
1241 );
1242
1243 return hResult.isOk() ? err : DEAD_OBJECT;
1244}
1245
1246void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1247{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001248 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001249 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001250 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001251 mInitCheck = NO_INIT;
1252
Jeff Tinker70367f52017-06-16 12:41:33 -07001253 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001254 if (!mPlugin->setListener(NULL).isOk()) {
1255 mInitCheck = DEAD_OBJECT;
1256 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001257 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001258 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001259}
1260
1261void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1262{
1263 if (vec.size()) {
1264 obj.writeInt32(vec.size());
1265 obj.write(vec.data(), vec.size());
1266 } else {
1267 obj.writeInt32(0);
1268 }
1269}
1270
Adam Stoneab394d12017-12-22 12:34:20 -08001271
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001272void DrmHal::reportMetrics() const
1273{
1274 Vector<uint8_t> metrics;
1275 String8 vendor;
1276 String8 description;
1277 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1278 getPropertyStringInternal(String8("description"), description) == OK &&
1279 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1280 status_t res = android::reportDrmPluginMetrics(
1281 metrics, vendor, description);
1282 if (res != OK) {
1283 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1284 }
1285 }
1286}
1287
Jeff Tinkera53d6552017-01-20 00:31:46 -08001288} // namespace android