blob: 039e1e994bfb215c128e00fe020ffb5aef705497 [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
Jeff Tinkera53d6552017-01-20 00:31:46 -080024#include <android/hardware/drm/1.0/types.h>
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080025#include <android/hidl/manager/1.0/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070026#include <hidl/ServiceManagement.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080027
28#include <media/DrmHal.h>
29#include <media/DrmSessionClientInterface.h>
30#include <media/DrmSessionManager.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080031#include <media/EventMetric.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070032#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080033#include <media/drm/DrmAPI.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AString.h>
36#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/MediaErrors.h>
38
Jeff Tinker6d998b62017-12-18 14:37:43 -080039using drm::V1_0::KeyedVector;
Jeff Tinker6d998b62017-12-18 14:37:43 -080040using drm::V1_0::KeyStatusType;
41using drm::V1_0::KeyType;
42using drm::V1_0::KeyValue;
43using drm::V1_1::HdcpLevel;;
44using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080045using drm::V1_1::SecureStopRelease;
46using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_1::SecurityLevel;
48using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080049using ::android::hardware::hidl_array;
50using ::android::hardware::hidl_string;
51using ::android::hardware::hidl_vec;
52using ::android::hardware::Return;
53using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080054using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080055using ::android::sp;
56
Adam Stonecea91ce2018-01-22 19:23:28 -080057namespace {
58
59// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
60// in the MediaDrm API.
61constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
62
63}
64
Jeff Tinkera53d6552017-01-20 00:31:46 -080065namespace android {
66
Jeff Tinker6d998b62017-12-18 14:37:43 -080067#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
68
Jeff Tinkera53d6552017-01-20 00:31:46 -080069static inline int getCallingPid() {
70 return IPCThreadState::self()->getCallingPid();
71}
72
73static bool checkPermission(const char* permissionString) {
74 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
75 bool ok = checkCallingPermission(String16(permissionString));
76 if (!ok) ALOGE("Request requires %s", permissionString);
77 return ok;
78}
79
80static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
81 Vector<uint8_t> vector;
82 vector.appendArray(vec.data(), vec.size());
83 return *const_cast<const Vector<uint8_t> *>(&vector);
84}
85
86static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
87 hidl_vec<uint8_t> vec;
88 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
89 return vec;
90}
91
92static String8 toString8(const hidl_string &string) {
93 return String8(string.c_str());
94}
95
96static hidl_string toHidlString(const String8& string) {
97 return hidl_string(string.string());
98}
99
Jeff Tinker6d998b62017-12-18 14:37:43 -0800100static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
101 switch(level) {
102 case SecurityLevel::SW_SECURE_CRYPTO:
103 return DrmPlugin::kSecurityLevelSwSecureCrypto;
104 case SecurityLevel::SW_SECURE_DECODE:
105 return DrmPlugin::kSecurityLevelSwSecureDecode;
106 case SecurityLevel::HW_SECURE_CRYPTO:
107 return DrmPlugin::kSecurityLevelHwSecureCrypto;
108 case SecurityLevel::HW_SECURE_DECODE:
109 return DrmPlugin::kSecurityLevelHwSecureDecode;
110 case SecurityLevel::HW_SECURE_ALL:
111 return DrmPlugin::kSecurityLevelHwSecureAll;
112 default:
113 return DrmPlugin::kSecurityLevelUnknown;
114 }
115}
116
117static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
118 switch(level) {
119 case HdcpLevel::HDCP_NONE:
120 return DrmPlugin::kHdcpNone;
121 case HdcpLevel::HDCP_V1:
122 return DrmPlugin::kHdcpV1;
123 case HdcpLevel::HDCP_V2:
124 return DrmPlugin::kHdcpV2;
125 case HdcpLevel::HDCP_V2_1:
126 return DrmPlugin::kHdcpV2_1;
127 case HdcpLevel::HDCP_V2_2:
128 return DrmPlugin::kHdcpV2_2;
129 case HdcpLevel::HDCP_NO_OUTPUT:
130 return DrmPlugin::kHdcpNoOutput;
131 default:
132 return DrmPlugin::kHdcpLevelUnknown;
133 }
134}
135
Jeff Tinkera53d6552017-01-20 00:31:46 -0800136
137static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
138 keyedVector) {
139 std::vector<KeyValue> stdKeyedVector;
140 for (size_t i = 0; i < keyedVector.size(); i++) {
141 KeyValue keyValue;
142 keyValue.key = toHidlString(keyedVector.keyAt(i));
143 keyValue.value = toHidlString(keyedVector.valueAt(i));
144 stdKeyedVector.push_back(keyValue);
145 }
146 return ::KeyedVector(stdKeyedVector);
147}
148
149static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
150 hKeyedVector) {
151 KeyedVector<String8, String8> keyedVector;
152 for (size_t i = 0; i < hKeyedVector.size(); i++) {
153 keyedVector.add(toString8(hKeyedVector[i].key),
154 toString8(hKeyedVector[i].value));
155 }
156 return keyedVector;
157}
158
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800159static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800160 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800161 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800162 for (size_t i = 0; i < hSecureStops.size(); i++) {
163 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
164 }
165 return secureStops;
166}
167
Jeff Tinker15177d72018-01-25 12:57:55 -0800168static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
169 hSecureStopIds) {
170 List<Vector<uint8_t>> secureStopIds;
171 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
172 secureStopIds.push_back(toVector(hSecureStopIds[i]));
173 }
174 return secureStopIds;
175}
176
Jeff Tinkera53d6552017-01-20 00:31:46 -0800177static status_t toStatusT(Status status) {
178 switch (status) {
179 case Status::OK:
180 return OK;
181 break;
182 case Status::ERROR_DRM_NO_LICENSE:
183 return ERROR_DRM_NO_LICENSE;
184 break;
185 case Status::ERROR_DRM_LICENSE_EXPIRED:
186 return ERROR_DRM_LICENSE_EXPIRED;
187 break;
188 case Status::ERROR_DRM_SESSION_NOT_OPENED:
189 return ERROR_DRM_SESSION_NOT_OPENED;
190 break;
191 case Status::ERROR_DRM_CANNOT_HANDLE:
192 return ERROR_DRM_CANNOT_HANDLE;
193 break;
194 case Status::ERROR_DRM_INVALID_STATE:
195 return ERROR_DRM_TAMPER_DETECTED;
196 break;
197 case Status::BAD_VALUE:
198 return BAD_VALUE;
199 break;
200 case Status::ERROR_DRM_NOT_PROVISIONED:
201 return ERROR_DRM_NOT_PROVISIONED;
202 break;
203 case Status::ERROR_DRM_RESOURCE_BUSY:
204 return ERROR_DRM_RESOURCE_BUSY;
205 break;
206 case Status::ERROR_DRM_DEVICE_REVOKED:
207 return ERROR_DRM_DEVICE_REVOKED;
208 break;
209 case Status::ERROR_DRM_UNKNOWN:
210 default:
211 return ERROR_DRM_UNKNOWN;
212 break;
213 }
214}
215
216
217Mutex DrmHal::mLock;
218
219struct DrmSessionClient : public DrmSessionClientInterface {
220 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
221
222 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
223 sp<DrmHal> drm = mDrm.promote();
224 if (drm == NULL) {
225 return true;
226 }
227 status_t err = drm->closeSession(sessionId);
228 if (err != OK) {
229 return false;
230 }
231 drm->sendEvent(EventType::SESSION_RECLAIMED,
232 toHidlVec(sessionId), hidl_vec<uint8_t>());
233 return true;
234 }
235
236protected:
237 virtual ~DrmSessionClient() {}
238
239private:
240 wp<DrmHal> mDrm;
241
242 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
243};
244
245DrmHal::DrmHal()
246 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800247 mFactories(makeDrmFactories()),
248 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800249}
250
Jeff Tinker61332812017-05-15 16:53:10 -0700251void DrmHal::closeOpenSessions() {
252 if (mPlugin != NULL) {
Jeff Tinkerb2b66fa2018-01-30 19:19:34 +0000253 for (size_t i = 0; i < mOpenSessions.size(); i++) {
254 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
255 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
Jeff Tinker61332812017-05-15 16:53:10 -0700256 }
257 }
258 mOpenSessions.clear();
259}
260
Jeff Tinkera53d6552017-01-20 00:31:46 -0800261DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700262 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800263 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
264}
265
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800266Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
267 Vector<sp<IDrmFactory>> factories;
268
Jeff Tinker593111f2017-05-25 16:00:21 -0700269 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800270
271 if (manager != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000272 manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800273 [&factories](const hidl_vec<hidl_string> &registered) {
274 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000275 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800276 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000277 ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800278 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000279 }
280 }
281 }
282 );
283 manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
284 [&factories](const hidl_vec<hidl_string> &registered) {
285 for (const auto &instance : registered) {
286 auto factory = drm::V1_1::IDrmFactory::getService(instance);
287 if (factory != NULL) {
288 ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
289 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800290 }
291 }
292 }
293 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800294 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800295
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800296 if (factories.size() == 0) {
297 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700298 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800299 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000300 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800301 factories.push_back(passthrough);
302 } else {
303 ALOGE("Failed to find any drm factories");
304 }
305 }
306 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800307}
308
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800309sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
310 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800311
312 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800313 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800314 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800315 if (status != Status::OK) {
316 ALOGE("Failed to make drm plugin");
317 return;
318 }
319 plugin = hPlugin;
320 }
321 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700322
323 if (!hResult.isOk()) {
324 ALOGE("createPlugin remote call failed");
325 }
326
Jeff Tinkera53d6552017-01-20 00:31:46 -0800327 return plugin;
328}
329
330status_t DrmHal::initCheck() const {
331 return mInitCheck;
332}
333
334status_t DrmHal::setListener(const sp<IDrmClient>& listener)
335{
336 Mutex::Autolock lock(mEventLock);
337 if (mListener != NULL){
338 IInterface::asBinder(mListener)->unlinkToDeath(this);
339 }
340 if (listener != NULL) {
341 IInterface::asBinder(listener)->linkToDeath(this);
342 }
343 mListener = listener;
344 return NO_ERROR;
345}
346
347Return<void> DrmHal::sendEvent(EventType hEventType,
348 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800349 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800350
351 mEventLock.lock();
352 sp<IDrmClient> listener = mListener;
353 mEventLock.unlock();
354
355 if (listener != NULL) {
356 Parcel obj;
357 writeByteArray(obj, sessionId);
358 writeByteArray(obj, data);
359
360 Mutex::Autolock lock(mNotifyLock);
361 DrmPlugin::EventType eventType;
362 switch(hEventType) {
363 case EventType::PROVISION_REQUIRED:
364 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
365 break;
366 case EventType::KEY_NEEDED:
367 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
368 break;
369 case EventType::KEY_EXPIRED:
370 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
371 break;
372 case EventType::VENDOR_DEFINED:
373 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
374 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700375 case EventType::SESSION_RECLAIMED:
376 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
377 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800378 default:
379 return Void();
380 }
381 listener->notify(eventType, 0, &obj);
382 }
383 return Void();
384}
385
386Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
387 int64_t expiryTimeInMS) {
388
389 mEventLock.lock();
390 sp<IDrmClient> listener = mListener;
391 mEventLock.unlock();
392
393 if (listener != NULL) {
394 Parcel obj;
395 writeByteArray(obj, sessionId);
396 obj.writeInt64(expiryTimeInMS);
397
398 Mutex::Autolock lock(mNotifyLock);
399 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
400 }
401 return Void();
402}
403
404Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
405 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
406
407 mEventLock.lock();
408 sp<IDrmClient> listener = mListener;
409 mEventLock.unlock();
410
411 if (listener != NULL) {
412 Parcel obj;
413 writeByteArray(obj, sessionId);
414
415 size_t nKeys = keyStatusList.size();
416 obj.writeInt32(nKeys);
417 for (size_t i = 0; i < nKeys; ++i) {
418 const KeyStatus &keyStatus = keyStatusList[i];
419 writeByteArray(obj, keyStatus.keyId);
420 uint32_t type;
421 switch(keyStatus.type) {
422 case KeyStatusType::USABLE:
423 type = DrmPlugin::kKeyStatusType_Usable;
424 break;
425 case KeyStatusType::EXPIRED:
426 type = DrmPlugin::kKeyStatusType_Expired;
427 break;
428 case KeyStatusType::OUTPUTNOTALLOWED:
429 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
430 break;
431 case KeyStatusType::STATUSPENDING:
432 type = DrmPlugin::kKeyStatusType_StatusPending;
433 break;
434 case KeyStatusType::INTERNALERROR:
435 default:
436 type = DrmPlugin::kKeyStatusType_InternalError;
437 break;
438 }
439 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800440 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800441 }
442 obj.writeInt32(hasNewUsableKey);
443
444 Mutex::Autolock lock(mNotifyLock);
445 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800446 } else {
447 // There's no listener. But we still want to count the key change
448 // events.
449 size_t nKeys = keyStatusList.size();
450 for (size_t i = 0; i < nKeys; i++) {
451 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
452 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800453 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800454
Jeff Tinkera53d6552017-01-20 00:31:46 -0800455 return Void();
456}
457
458bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
459 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800460
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800461 for (size_t i = 0; i < mFactories.size(); i++) {
462 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
463 if (mimeType != "") {
464 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
465 return true;
466 }
467 } else {
468 return true;
469 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470 }
471 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800472 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800473}
474
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800475status_t DrmHal::createPlugin(const uint8_t uuid[16],
476 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800477 Mutex::Autolock autoLock(mLock);
478
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800479 for (size_t i = 0; i < mFactories.size(); i++) {
480 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
481 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Edwin Wong5641aa22018-01-30 17:52:21 -0800482 if (mPlugin != NULL) {
483 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
484 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800485 }
486 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800487
488 if (mPlugin == NULL) {
489 mInitCheck = ERROR_UNSUPPORTED;
490 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700491 if (!mPlugin->setListener(this).isOk()) {
492 mInitCheck = DEAD_OBJECT;
493 } else {
494 mInitCheck = OK;
495 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800496 }
497
498 return mInitCheck;
499}
500
501status_t DrmHal::destroyPlugin() {
502 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800503 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800504
Jeff Tinker61332812017-05-15 16:53:10 -0700505 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700506 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800507 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700508 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800509
Jeff Tinker319d5f42017-07-26 15:44:33 -0700510 if (mPlugin != NULL) {
511 if (!mPlugin->setListener(NULL).isOk()) {
512 mInitCheck = DEAD_OBJECT;
513 }
514 }
515 mPlugin.clear();
Edwin Wong5641aa22018-01-30 17:52:21 -0800516 mPluginV1_1.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800517 return OK;
518}
519
Jeff Tinker41d279a2018-02-11 19:52:08 +0000520status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
521 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800522 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800523 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800524
Jeff Tinker41d279a2018-02-11 19:52:08 +0000525 SecurityLevel hSecurityLevel;
526 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000527
Jeff Tinker41d279a2018-02-11 19:52:08 +0000528 switch(level) {
529 case DrmPlugin::kSecurityLevelSwSecureCrypto:
530 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
531 break;
532 case DrmPlugin::kSecurityLevelSwSecureDecode:
533 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
534 break;
535 case DrmPlugin::kSecurityLevelHwSecureCrypto:
536 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
537 break;
538 case DrmPlugin::kSecurityLevelHwSecureDecode:
539 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
540 break;
541 case DrmPlugin::kSecurityLevelHwSecureAll:
542 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
543 break;
544 case DrmPlugin::kSecurityLevelMax:
545 setSecurityLevel = false;
546 break;
547 default:
548 return ERROR_DRM_CANNOT_HANDLE;
549 }
550
551 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552 bool retry = true;
553 do {
554 hidl_vec<uint8_t> hSessionId;
555
Jeff Tinker41d279a2018-02-11 19:52:08 +0000556 Return<void> hResult;
557 if (mPluginV1_1 == NULL || !setSecurityLevel) {
558 hResult = mPlugin->openSession(
559 [&](Status status,const hidl_vec<uint8_t>& id) {
560 if (status == Status::OK) {
561 sessionId = toVector(id);
562 }
563 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800564 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000565 );
566 } else {
567 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
568 [&](Status status, const hidl_vec<uint8_t>& id) {
569 if (status == Status::OK) {
570 sessionId = toVector(id);
571 }
572 err = toStatusT(status);
573 }
574 );
575 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800576
577 if (!hResult.isOk()) {
578 err = DEAD_OBJECT;
579 }
580
581 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
582 mLock.unlock();
583 // reclaimSession may call back to closeSession, since mLock is
584 // shared between Drm instances, we should unlock here to avoid
585 // deadlock.
586 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
587 mLock.lock();
588 } else {
589 retry = false;
590 }
591 } while (retry);
592
593 if (err == OK) {
594 DrmSessionManager::Instance()->addSession(getCallingPid(),
595 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700596 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800597 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800598
Adam Stonef0e618d2018-01-17 19:20:41 -0800599 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800600 return err;
601}
602
603status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
604 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800605 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800606
Jeff Tinker319d5f42017-07-26 15:44:33 -0700607 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
608 if (status.isOk()) {
609 if (status == Status::OK) {
610 DrmSessionManager::Instance()->removeSession(sessionId);
611 for (size_t i = 0; i < mOpenSessions.size(); i++) {
612 if (mOpenSessions[i] == sessionId) {
613 mOpenSessions.removeAt(i);
614 break;
615 }
Jeff Tinker61332812017-05-15 16:53:10 -0700616 }
617 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700618 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800619 status_t response = toStatusT(status);
620 mMetrics.mCloseSessionCounter.Increment(response);
621 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800622 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800623 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700624 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800625}
626
627status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
628 Vector<uint8_t> const &initData, String8 const &mimeType,
629 DrmPlugin::KeyType keyType, KeyedVector<String8,
630 String8> const &optionalParameters, Vector<uint8_t> &request,
631 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
632 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800633 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800634 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800635
636 DrmSessionManager::Instance()->useSession(sessionId);
637
638 KeyType hKeyType;
639 if (keyType == DrmPlugin::kKeyType_Streaming) {
640 hKeyType = KeyType::STREAMING;
641 } else if (keyType == DrmPlugin::kKeyType_Offline) {
642 hKeyType = KeyType::OFFLINE;
643 } else if (keyType == DrmPlugin::kKeyType_Release) {
644 hKeyType = KeyType::RELEASE;
645 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800646 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800647 return BAD_VALUE;
648 }
649
650 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
651
652 status_t err = UNKNOWN_ERROR;
653
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800654 if (mPluginV1_1 != NULL) {
655 Return<void> hResult =
656 mPluginV1_1->getKeyRequest_1_1(
657 toHidlVec(sessionId), toHidlVec(initData),
658 toHidlString(mimeType), hKeyType, hOptionalParameters,
659 [&](Status status, const hidl_vec<uint8_t>& hRequest,
660 drm::V1_1::KeyRequestType hKeyRequestType,
661 const hidl_string& hDefaultUrl) {
662
663 if (status == Status::OK) {
664 request = toVector(hRequest);
665 defaultUrl = toString8(hDefaultUrl);
666
667 switch (hKeyRequestType) {
668 case drm::V1_1::KeyRequestType::INITIAL:
669 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
670 break;
671 case drm::V1_1::KeyRequestType::RENEWAL:
672 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
673 break;
674 case drm::V1_1::KeyRequestType::RELEASE:
675 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
676 break;
677 case drm::V1_1::KeyRequestType::NONE:
678 *keyRequestType = DrmPlugin::kKeyRequestType_None;
679 break;
680 case drm::V1_1::KeyRequestType::UPDATE:
681 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
682 break;
683 default:
684 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
685 break;
686 }
687 err = toStatusT(status);
688 }
689 });
690 return hResult.isOk() ? err : DEAD_OBJECT;
691 }
692
Jeff Tinkera53d6552017-01-20 00:31:46 -0800693 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
694 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
695 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800696 drm::V1_0::KeyRequestType hKeyRequestType,
697 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800698
699 if (status == Status::OK) {
700 request = toVector(hRequest);
701 defaultUrl = toString8(hDefaultUrl);
702
703 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800704 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800705 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
706 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800707 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800708 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
709 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800710 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800711 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
712 break;
713 default:
714 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
715 break;
716 }
717 err = toStatusT(status);
718 }
719 });
720
Adam Stonef0e618d2018-01-17 19:20:41 -0800721 err = hResult.isOk() ? err : DEAD_OBJECT;
722 keyRequestTimer.SetAttribute(err);
723 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800724}
725
726status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
727 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
728 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800729 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
730
Jeff Tinker6d998b62017-12-18 14:37:43 -0800731 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800732
733 DrmSessionManager::Instance()->useSession(sessionId);
734
735 status_t err = UNKNOWN_ERROR;
736
737 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
738 toHidlVec(response),
739 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
740 if (status == Status::OK) {
741 keySetId = toVector(hKeySetId);
742 }
743 err = toStatusT(status);
744 }
745 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800746 err = hResult.isOk() ? err : DEAD_OBJECT;
747 keyResponseTimer.SetAttribute(err);
748 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800749}
750
751status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
752 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800753 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800754
755 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
756}
757
758status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
759 Vector<uint8_t> const &keySetId) {
760 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800761 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800762
763 DrmSessionManager::Instance()->useSession(sessionId);
764
765 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
766 toHidlVec(keySetId)));
767}
768
769status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
770 KeyedVector<String8, String8> &infoMap) const {
771 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800772 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773
774 DrmSessionManager::Instance()->useSession(sessionId);
775
776 ::KeyedVector hInfoMap;
777
778 status_t err = UNKNOWN_ERROR;
779
780 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
781 [&](Status status, const hidl_vec<KeyValue>& map) {
782 if (status == Status::OK) {
783 infoMap = toKeyedVector(map);
784 }
785 err = toStatusT(status);
786 }
787 );
788
789 return hResult.isOk() ? err : DEAD_OBJECT;
790}
791
792status_t DrmHal::getProvisionRequest(String8 const &certType,
793 String8 const &certAuthority, Vector<uint8_t> &request,
794 String8 &defaultUrl) {
795 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800796 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800797
798 status_t err = UNKNOWN_ERROR;
799
800 Return<void> hResult = mPlugin->getProvisionRequest(
801 toHidlString(certType), toHidlString(certAuthority),
802 [&](Status status, const hidl_vec<uint8_t>& hRequest,
803 const hidl_string& hDefaultUrl) {
804 if (status == Status::OK) {
805 request = toVector(hRequest);
806 defaultUrl = toString8(hDefaultUrl);
807 }
808 err = toStatusT(status);
809 }
810 );
811
Adam Stonecea91ce2018-01-22 19:23:28 -0800812 err = hResult.isOk() ? err : DEAD_OBJECT;
813 mMetrics.mGetProvisionRequestCounter.Increment(err);
814 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800815}
816
817status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800818 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800819 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800820 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800821
822 status_t err = UNKNOWN_ERROR;
823
824 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
825 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
826 const hidl_vec<uint8_t>& hWrappedKey) {
827 if (status == Status::OK) {
828 certificate = toVector(hCertificate);
829 wrappedKey = toVector(hWrappedKey);
830 }
831 err = toStatusT(status);
832 }
833 );
834
Adam Stonecea91ce2018-01-22 19:23:28 -0800835 err = hResult.isOk() ? err : DEAD_OBJECT;
836 mMetrics.mProvideProvisionResponseCounter.Increment(err);
837 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800838}
839
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800840status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800842 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800843
844 status_t err = UNKNOWN_ERROR;
845
846 Return<void> hResult = mPlugin->getSecureStops(
847 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
848 if (status == Status::OK) {
849 secureStops = toSecureStops(hSecureStops);
850 }
851 err = toStatusT(status);
852 }
853 );
854
855 return hResult.isOk() ? err : DEAD_OBJECT;
856}
857
858
Jeff Tinker15177d72018-01-25 12:57:55 -0800859status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
860 Mutex::Autolock autoLock(mLock);
861
862 if (mInitCheck != OK) {
863 return mInitCheck;
864 }
865
866 if (mPluginV1_1 == NULL) {
867 return ERROR_DRM_CANNOT_HANDLE;
868 }
869
870 status_t err = UNKNOWN_ERROR;
871
872 Return<void> hResult = mPluginV1_1->getSecureStopIds(
873 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
874 if (status == Status::OK) {
875 secureStopIds = toSecureStopIds(hSecureStopIds);
876 }
877 err = toStatusT(status);
878 }
879 );
880
881 return hResult.isOk() ? err : DEAD_OBJECT;
882}
883
884
Jeff Tinkera53d6552017-01-20 00:31:46 -0800885status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
886 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800887 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800888
889 status_t err = UNKNOWN_ERROR;
890
891 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
892 [&](Status status, const SecureStop& hSecureStop) {
893 if (status == Status::OK) {
894 secureStop = toVector(hSecureStop.opaqueData);
895 }
896 err = toStatusT(status);
897 }
898 );
899
900 return hResult.isOk() ? err : DEAD_OBJECT;
901}
902
903status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
904 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800905 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800906
Jeff Tinker15177d72018-01-25 12:57:55 -0800907 if (mPluginV1_1 != NULL) {
908 SecureStopRelease secureStopRelease;
909 secureStopRelease.opaqueData = toHidlVec(ssRelease);
910 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
911 }
912
Jeff Tinkera53d6552017-01-20 00:31:46 -0800913 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
914}
915
Jeff Tinker15177d72018-01-25 12:57:55 -0800916status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
917 Mutex::Autolock autoLock(mLock);
918
919 if (mInitCheck != OK) {
920 return mInitCheck;
921 }
922
923 if (mPluginV1_1 == NULL) {
924 return ERROR_DRM_CANNOT_HANDLE;
925 }
926
927 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
928}
929
930status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800931 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800932 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800933
Jeff Tinker15177d72018-01-25 12:57:55 -0800934 if (mPluginV1_1 != NULL) {
935 return toStatusT(mPluginV1_1->removeAllSecureStops());
936 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937 return toStatusT(mPlugin->releaseAllSecureStops());
938}
939
Jeff Tinker6d998b62017-12-18 14:37:43 -0800940status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
941 DrmPlugin::HdcpLevel *max) const {
942 Mutex::Autolock autoLock(mLock);
943 INIT_CHECK();
944
945 if (connected == NULL || max == NULL) {
946 return BAD_VALUE;
947 }
948 status_t err = UNKNOWN_ERROR;
949
950 if (mPluginV1_1 == NULL) {
951 return ERROR_DRM_CANNOT_HANDLE;
952 }
953
954 *connected = DrmPlugin::kHdcpLevelUnknown;
955 *max = DrmPlugin::kHdcpLevelUnknown;
956
957 Return<void> hResult = mPluginV1_1->getHdcpLevels(
958 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
959 if (status == Status::OK) {
960 *connected = toHdcpLevel(hConnected);
961 *max = toHdcpLevel(hMax);
962 }
963 err = toStatusT(status);
964 }
965 );
966
967 return hResult.isOk() ? err : DEAD_OBJECT;
968}
969
970status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
971 Mutex::Autolock autoLock(mLock);
972 INIT_CHECK();
973
974 if (open == NULL || max == NULL) {
975 return BAD_VALUE;
976 }
977 status_t err = UNKNOWN_ERROR;
978
979 *open = 0;
980 *max = 0;
981
982 if (mPluginV1_1 == NULL) {
983 return ERROR_DRM_CANNOT_HANDLE;
984 }
985
986 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
987 [&](Status status, uint32_t hOpen, uint32_t hMax) {
988 if (status == Status::OK) {
989 *open = hOpen;
990 *max = hMax;
991 }
992 err = toStatusT(status);
993 }
994 );
995
996 return hResult.isOk() ? err : DEAD_OBJECT;
997}
998
999status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1000 DrmPlugin::SecurityLevel *level) const {
1001 Mutex::Autolock autoLock(mLock);
1002 INIT_CHECK();
1003
1004 if (level == NULL) {
1005 return BAD_VALUE;
1006 }
1007 status_t err = UNKNOWN_ERROR;
1008
1009 if (mPluginV1_1 == NULL) {
1010 return ERROR_DRM_CANNOT_HANDLE;
1011 }
1012
1013 *level = DrmPlugin::kSecurityLevelUnknown;
1014
1015 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1016 [&](Status status, SecurityLevel hLevel) {
1017 if (status == Status::OK) {
1018 *level = toSecurityLevel(hLevel);
1019 }
1020 err = toStatusT(status);
1021 }
1022 );
1023
1024 return hResult.isOk() ? err : DEAD_OBJECT;
1025}
1026
Jeff Tinkera53d6552017-01-20 00:31:46 -08001027status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1028 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001029 return getPropertyStringInternal(name, value);
1030}
1031
1032status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1033 // This function is internal to the class and should only be called while
1034 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001035 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001036
1037 status_t err = UNKNOWN_ERROR;
1038
1039 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1040 [&](Status status, const hidl_string& hValue) {
1041 if (status == Status::OK) {
1042 value = toString8(hValue);
1043 }
1044 err = toStatusT(status);
1045 }
1046 );
1047
1048 return hResult.isOk() ? err : DEAD_OBJECT;
1049}
1050
1051status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1052 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001053 return getPropertyByteArrayInternal(name, value);
1054}
1055
1056status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1057 // This function is internal to the class and should only be called while
1058 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001059 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001060
1061 status_t err = UNKNOWN_ERROR;
1062
1063 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1064 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1065 if (status == Status::OK) {
1066 value = toVector(hValue);
1067 }
1068 err = toStatusT(status);
1069 }
1070 );
1071
Adam Stonecea91ce2018-01-22 19:23:28 -08001072 err = hResult.isOk() ? err : DEAD_OBJECT;
1073 if (name == kPropertyDeviceUniqueId) {
1074 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1075 }
1076 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001077}
1078
1079status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1080 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001081 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001082
Jeff Tinker6d998b62017-12-18 14:37:43 -08001083 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001084 toHidlString(value));
1085 return toStatusT(status);
1086}
1087
1088status_t DrmHal::setPropertyByteArray(String8 const &name,
1089 Vector<uint8_t> const &value ) const {
1090 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001091 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001092
1093 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1094 toHidlVec(value));
1095 return toStatusT(status);
1096}
1097
Adam Stonef0e618d2018-01-17 19:20:41 -08001098status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
1099 if (item == nullptr) {
1100 return UNEXPECTED_NULL;
1101 }
1102
1103 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001104 return OK;
1105}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001106
1107status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1108 String8 const &algorithm) {
1109 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001110 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001111
1112 DrmSessionManager::Instance()->useSession(sessionId);
1113
1114 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1115 toHidlString(algorithm));
1116 return toStatusT(status);
1117}
1118
1119status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1120 String8 const &algorithm) {
1121 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001122 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001123
1124 DrmSessionManager::Instance()->useSession(sessionId);
1125
1126 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1127 toHidlString(algorithm));
1128 return toStatusT(status);
1129}
1130
1131status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001132 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1133 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001134 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001135 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001136
1137 DrmSessionManager::Instance()->useSession(sessionId);
1138
1139 status_t err = UNKNOWN_ERROR;
1140
1141 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1142 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1143 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1144 if (status == Status::OK) {
1145 output = toVector(hOutput);
1146 }
1147 err = toStatusT(status);
1148 }
1149 );
1150
1151 return hResult.isOk() ? err : DEAD_OBJECT;
1152}
1153
1154status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001155 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1156 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001157 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001158 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001159
1160 DrmSessionManager::Instance()->useSession(sessionId);
1161
1162 status_t err = UNKNOWN_ERROR;
1163
1164 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1165 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1166 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1167 if (status == Status::OK) {
1168 output = toVector(hOutput);
1169 }
1170 err = toStatusT(status);
1171 }
1172 );
1173
1174 return hResult.isOk() ? err : DEAD_OBJECT;
1175}
1176
1177status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001178 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1179 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001180 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001181 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001182
1183 DrmSessionManager::Instance()->useSession(sessionId);
1184
1185 status_t err = UNKNOWN_ERROR;
1186
1187 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1188 toHidlVec(keyId), toHidlVec(message),
1189 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1190 if (status == Status::OK) {
1191 signature = toVector(hSignature);
1192 }
1193 err = toStatusT(status);
1194 }
1195 );
1196
1197 return hResult.isOk() ? err : DEAD_OBJECT;
1198}
1199
1200status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001201 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1202 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001203 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001204 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001205
1206 DrmSessionManager::Instance()->useSession(sessionId);
1207
1208 status_t err = UNKNOWN_ERROR;
1209
1210 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1211 toHidlVec(message), toHidlVec(signature),
1212 [&](Status status, bool hMatch) {
1213 if (status == Status::OK) {
1214 match = hMatch;
1215 } else {
1216 match = false;
1217 }
1218 err = toStatusT(status);
1219 }
1220 );
1221
1222 return hResult.isOk() ? err : DEAD_OBJECT;
1223}
1224
1225status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001226 String8 const &algorithm, Vector<uint8_t> const &message,
1227 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001228 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001229 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001230
1231 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1232 return -EPERM;
1233 }
1234
1235 DrmSessionManager::Instance()->useSession(sessionId);
1236
1237 status_t err = UNKNOWN_ERROR;
1238
1239 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1240 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1241 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1242 if (status == Status::OK) {
1243 signature = toVector(hSignature);
1244 }
1245 err = toStatusT(status);
1246 }
1247 );
1248
1249 return hResult.isOk() ? err : DEAD_OBJECT;
1250}
1251
1252void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1253{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001254 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001255 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001256 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001257 mInitCheck = NO_INIT;
1258
Jeff Tinker70367f52017-06-16 12:41:33 -07001259 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001260 if (!mPlugin->setListener(NULL).isOk()) {
1261 mInitCheck = DEAD_OBJECT;
1262 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001263 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001264 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001265}
1266
1267void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1268{
1269 if (vec.size()) {
1270 obj.writeInt32(vec.size());
1271 obj.write(vec.data(), vec.size());
1272 } else {
1273 obj.writeInt32(0);
1274 }
1275}
1276
Adam Stoneab394d12017-12-22 12:34:20 -08001277
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001278void DrmHal::reportMetrics() const
1279{
1280 Vector<uint8_t> metrics;
1281 String8 vendor;
1282 String8 description;
1283 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1284 getPropertyStringInternal(String8("description"), description) == OK &&
1285 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1286 status_t res = android::reportDrmPluginMetrics(
1287 metrics, vendor, description);
1288 if (res != OK) {
1289 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1290 }
1291 }
1292}
1293
Jeff Tinkera53d6552017-01-20 00:31:46 -08001294} // namespace android