blob: 07cec0168f6246a717e13848e202d372d342f2ec [file] [log] [blame]
Jeff Tinkera53d6552017-01-20 00:31:46 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmHal"
19#include <utils/Log.h>
20
21#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080023
24#include <android/hardware/drm/1.0/IDrmFactory.h>
25#include <android/hardware/drm/1.0/IDrmPlugin.h>
26#include <android/hardware/drm/1.0/types.h>
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080027#include <android/hidl/manager/1.0/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070028#include <hidl/ServiceManagement.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080029
30#include <media/DrmHal.h>
31#include <media/DrmSessionClientInterface.h>
32#include <media/DrmSessionManager.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080033#include <media/EventMetric.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070034#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080035#include <media/drm/DrmAPI.h>
36#include <media/stagefright/foundation/ADebug.h>
37#include <media/stagefright/foundation/AString.h>
38#include <media/stagefright/foundation/hexdump.h>
39#include <media/stagefright/MediaErrors.h>
40
Jeff Tinker6d998b62017-12-18 14:37:43 -080041using drm::V1_0::KeyedVector;
Jeff Tinker6d998b62017-12-18 14:37:43 -080042using drm::V1_0::KeyStatusType;
43using drm::V1_0::KeyType;
44using drm::V1_0::KeyValue;
45using drm::V1_1::HdcpLevel;;
46using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080047using drm::V1_1::SecureStopRelease;
48using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080049using drm::V1_1::SecurityLevel;
50using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080051using ::android::hardware::hidl_array;
52using ::android::hardware::hidl_string;
53using ::android::hardware::hidl_vec;
54using ::android::hardware::Return;
55using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080056using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080057using ::android::sp;
58
Adam Stonecea91ce2018-01-22 19:23:28 -080059namespace {
60
61// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
62// in the MediaDrm API.
63constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
64
65}
66
Jeff Tinkera53d6552017-01-20 00:31:46 -080067namespace android {
68
Jeff Tinker6d998b62017-12-18 14:37:43 -080069#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
70
Jeff Tinkera53d6552017-01-20 00:31:46 -080071static inline int getCallingPid() {
72 return IPCThreadState::self()->getCallingPid();
73}
74
75static bool checkPermission(const char* permissionString) {
76 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
77 bool ok = checkCallingPermission(String16(permissionString));
78 if (!ok) ALOGE("Request requires %s", permissionString);
79 return ok;
80}
81
82static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
83 Vector<uint8_t> vector;
84 vector.appendArray(vec.data(), vec.size());
85 return *const_cast<const Vector<uint8_t> *>(&vector);
86}
87
88static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
89 hidl_vec<uint8_t> vec;
90 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
91 return vec;
92}
93
94static String8 toString8(const hidl_string &string) {
95 return String8(string.c_str());
96}
97
98static hidl_string toHidlString(const String8& string) {
99 return hidl_string(string.string());
100}
101
Jeff Tinker6d998b62017-12-18 14:37:43 -0800102static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
103 switch(level) {
104 case SecurityLevel::SW_SECURE_CRYPTO:
105 return DrmPlugin::kSecurityLevelSwSecureCrypto;
106 case SecurityLevel::SW_SECURE_DECODE:
107 return DrmPlugin::kSecurityLevelSwSecureDecode;
108 case SecurityLevel::HW_SECURE_CRYPTO:
109 return DrmPlugin::kSecurityLevelHwSecureCrypto;
110 case SecurityLevel::HW_SECURE_DECODE:
111 return DrmPlugin::kSecurityLevelHwSecureDecode;
112 case SecurityLevel::HW_SECURE_ALL:
113 return DrmPlugin::kSecurityLevelHwSecureAll;
114 default:
115 return DrmPlugin::kSecurityLevelUnknown;
116 }
117}
118
119static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
120 switch(level) {
121 case HdcpLevel::HDCP_NONE:
122 return DrmPlugin::kHdcpNone;
123 case HdcpLevel::HDCP_V1:
124 return DrmPlugin::kHdcpV1;
125 case HdcpLevel::HDCP_V2:
126 return DrmPlugin::kHdcpV2;
127 case HdcpLevel::HDCP_V2_1:
128 return DrmPlugin::kHdcpV2_1;
129 case HdcpLevel::HDCP_V2_2:
130 return DrmPlugin::kHdcpV2_2;
131 case HdcpLevel::HDCP_NO_OUTPUT:
132 return DrmPlugin::kHdcpNoOutput;
133 default:
134 return DrmPlugin::kHdcpLevelUnknown;
135 }
136}
137
Jeff Tinkera53d6552017-01-20 00:31:46 -0800138
139static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
140 keyedVector) {
141 std::vector<KeyValue> stdKeyedVector;
142 for (size_t i = 0; i < keyedVector.size(); i++) {
143 KeyValue keyValue;
144 keyValue.key = toHidlString(keyedVector.keyAt(i));
145 keyValue.value = toHidlString(keyedVector.valueAt(i));
146 stdKeyedVector.push_back(keyValue);
147 }
148 return ::KeyedVector(stdKeyedVector);
149}
150
151static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
152 hKeyedVector) {
153 KeyedVector<String8, String8> keyedVector;
154 for (size_t i = 0; i < hKeyedVector.size(); i++) {
155 keyedVector.add(toString8(hKeyedVector[i].key),
156 toString8(hKeyedVector[i].value));
157 }
158 return keyedVector;
159}
160
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800161static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800162 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800163 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800164 for (size_t i = 0; i < hSecureStops.size(); i++) {
165 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
166 }
167 return secureStops;
168}
169
Jeff Tinker15177d72018-01-25 12:57:55 -0800170static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
171 hSecureStopIds) {
172 List<Vector<uint8_t>> secureStopIds;
173 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
174 secureStopIds.push_back(toVector(hSecureStopIds[i]));
175 }
176 return secureStopIds;
177}
178
Jeff Tinkera53d6552017-01-20 00:31:46 -0800179static status_t toStatusT(Status status) {
180 switch (status) {
181 case Status::OK:
182 return OK;
183 break;
184 case Status::ERROR_DRM_NO_LICENSE:
185 return ERROR_DRM_NO_LICENSE;
186 break;
187 case Status::ERROR_DRM_LICENSE_EXPIRED:
188 return ERROR_DRM_LICENSE_EXPIRED;
189 break;
190 case Status::ERROR_DRM_SESSION_NOT_OPENED:
191 return ERROR_DRM_SESSION_NOT_OPENED;
192 break;
193 case Status::ERROR_DRM_CANNOT_HANDLE:
194 return ERROR_DRM_CANNOT_HANDLE;
195 break;
196 case Status::ERROR_DRM_INVALID_STATE:
197 return ERROR_DRM_TAMPER_DETECTED;
198 break;
199 case Status::BAD_VALUE:
200 return BAD_VALUE;
201 break;
202 case Status::ERROR_DRM_NOT_PROVISIONED:
203 return ERROR_DRM_NOT_PROVISIONED;
204 break;
205 case Status::ERROR_DRM_RESOURCE_BUSY:
206 return ERROR_DRM_RESOURCE_BUSY;
207 break;
208 case Status::ERROR_DRM_DEVICE_REVOKED:
209 return ERROR_DRM_DEVICE_REVOKED;
210 break;
211 case Status::ERROR_DRM_UNKNOWN:
212 default:
213 return ERROR_DRM_UNKNOWN;
214 break;
215 }
216}
217
218
219Mutex DrmHal::mLock;
220
221struct DrmSessionClient : public DrmSessionClientInterface {
222 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
223
224 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
225 sp<DrmHal> drm = mDrm.promote();
226 if (drm == NULL) {
227 return true;
228 }
229 status_t err = drm->closeSession(sessionId);
230 if (err != OK) {
231 return false;
232 }
233 drm->sendEvent(EventType::SESSION_RECLAIMED,
234 toHidlVec(sessionId), hidl_vec<uint8_t>());
235 return true;
236 }
237
238protected:
239 virtual ~DrmSessionClient() {}
240
241private:
242 wp<DrmHal> mDrm;
243
244 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
245};
246
247DrmHal::DrmHal()
248 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800249 mFactories(makeDrmFactories()),
250 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800251}
252
Jeff Tinker61332812017-05-15 16:53:10 -0700253void DrmHal::closeOpenSessions() {
254 if (mPlugin != NULL) {
Jeff Tinkerb2b66fa2018-01-30 19:19:34 +0000255 for (size_t i = 0; i < mOpenSessions.size(); i++) {
256 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
257 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
Jeff Tinker61332812017-05-15 16:53:10 -0700258 }
259 }
260 mOpenSessions.clear();
261}
262
Jeff Tinkera53d6552017-01-20 00:31:46 -0800263DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700264 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800265 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
266}
267
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800268Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
269 Vector<sp<IDrmFactory>> factories;
270
Jeff Tinker593111f2017-05-25 16:00:21 -0700271 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800272
273 if (manager != NULL) {
274 manager->listByInterface(IDrmFactory::descriptor,
275 [&factories](const hidl_vec<hidl_string> &registered) {
276 for (const auto &instance : registered) {
277 auto factory = IDrmFactory::getService(instance);
278 if (factory != NULL) {
279 factories.push_back(factory);
280 ALOGI("makeDrmFactories: factory instance %s is %s",
281 instance.c_str(),
282 factory->isRemote() ? "Remote" : "Not Remote");
283 }
284 }
285 }
286 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800287 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800288
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800289 if (factories.size() == 0) {
290 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700291 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800292 if (passthrough != NULL) {
293 ALOGI("makeDrmFactories: using default drm instance");
294 factories.push_back(passthrough);
295 } else {
296 ALOGE("Failed to find any drm factories");
297 }
298 }
299 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800300}
301
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800302sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
303 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800304
305 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800306 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800307 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800308 if (status != Status::OK) {
309 ALOGE("Failed to make drm plugin");
310 return;
311 }
312 plugin = hPlugin;
313 }
314 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700315
316 if (!hResult.isOk()) {
317 ALOGE("createPlugin remote call failed");
318 }
319
Jeff Tinkera53d6552017-01-20 00:31:46 -0800320 return plugin;
321}
322
323status_t DrmHal::initCheck() const {
324 return mInitCheck;
325}
326
327status_t DrmHal::setListener(const sp<IDrmClient>& listener)
328{
329 Mutex::Autolock lock(mEventLock);
330 if (mListener != NULL){
331 IInterface::asBinder(mListener)->unlinkToDeath(this);
332 }
333 if (listener != NULL) {
334 IInterface::asBinder(listener)->linkToDeath(this);
335 }
336 mListener = listener;
337 return NO_ERROR;
338}
339
340Return<void> DrmHal::sendEvent(EventType hEventType,
341 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800342 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800343
344 mEventLock.lock();
345 sp<IDrmClient> listener = mListener;
346 mEventLock.unlock();
347
348 if (listener != NULL) {
349 Parcel obj;
350 writeByteArray(obj, sessionId);
351 writeByteArray(obj, data);
352
353 Mutex::Autolock lock(mNotifyLock);
354 DrmPlugin::EventType eventType;
355 switch(hEventType) {
356 case EventType::PROVISION_REQUIRED:
357 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
358 break;
359 case EventType::KEY_NEEDED:
360 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
361 break;
362 case EventType::KEY_EXPIRED:
363 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
364 break;
365 case EventType::VENDOR_DEFINED:
366 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
367 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700368 case EventType::SESSION_RECLAIMED:
369 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
370 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800371 default:
372 return Void();
373 }
374 listener->notify(eventType, 0, &obj);
375 }
376 return Void();
377}
378
379Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
380 int64_t expiryTimeInMS) {
381
382 mEventLock.lock();
383 sp<IDrmClient> listener = mListener;
384 mEventLock.unlock();
385
386 if (listener != NULL) {
387 Parcel obj;
388 writeByteArray(obj, sessionId);
389 obj.writeInt64(expiryTimeInMS);
390
391 Mutex::Autolock lock(mNotifyLock);
392 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
393 }
394 return Void();
395}
396
397Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
398 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
399
400 mEventLock.lock();
401 sp<IDrmClient> listener = mListener;
402 mEventLock.unlock();
403
404 if (listener != NULL) {
405 Parcel obj;
406 writeByteArray(obj, sessionId);
407
408 size_t nKeys = keyStatusList.size();
409 obj.writeInt32(nKeys);
410 for (size_t i = 0; i < nKeys; ++i) {
411 const KeyStatus &keyStatus = keyStatusList[i];
412 writeByteArray(obj, keyStatus.keyId);
413 uint32_t type;
414 switch(keyStatus.type) {
415 case KeyStatusType::USABLE:
416 type = DrmPlugin::kKeyStatusType_Usable;
417 break;
418 case KeyStatusType::EXPIRED:
419 type = DrmPlugin::kKeyStatusType_Expired;
420 break;
421 case KeyStatusType::OUTPUTNOTALLOWED:
422 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
423 break;
424 case KeyStatusType::STATUSPENDING:
425 type = DrmPlugin::kKeyStatusType_StatusPending;
426 break;
427 case KeyStatusType::INTERNALERROR:
428 default:
429 type = DrmPlugin::kKeyStatusType_InternalError;
430 break;
431 }
432 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800433 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800434 }
435 obj.writeInt32(hasNewUsableKey);
436
437 Mutex::Autolock lock(mNotifyLock);
438 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800439 } else {
440 // There's no listener. But we still want to count the key change
441 // events.
442 size_t nKeys = keyStatusList.size();
443 for (size_t i = 0; i < nKeys; i++) {
444 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
445 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800446 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800447
Jeff Tinkera53d6552017-01-20 00:31:46 -0800448 return Void();
449}
450
451bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
452 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800453
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800454 for (size_t i = 0; i < mFactories.size(); i++) {
455 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
456 if (mimeType != "") {
457 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
458 return true;
459 }
460 } else {
461 return true;
462 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800463 }
464 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800465 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800466}
467
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800468status_t DrmHal::createPlugin(const uint8_t uuid[16],
469 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470 Mutex::Autolock autoLock(mLock);
471
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800472 for (size_t i = 0; i < mFactories.size(); i++) {
473 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
474 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Edwin Wong5641aa22018-01-30 17:52:21 -0800475 if (mPlugin != NULL) {
476 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
477 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800478 }
479 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800480
481 if (mPlugin == NULL) {
482 mInitCheck = ERROR_UNSUPPORTED;
483 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700484 if (!mPlugin->setListener(this).isOk()) {
485 mInitCheck = DEAD_OBJECT;
486 } else {
487 mInitCheck = OK;
488 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800489 }
490
491 return mInitCheck;
492}
493
494status_t DrmHal::destroyPlugin() {
495 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800496 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800497
Jeff Tinker61332812017-05-15 16:53:10 -0700498 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700499 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800500 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700501 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800502
Jeff Tinker319d5f42017-07-26 15:44:33 -0700503 if (mPlugin != NULL) {
504 if (!mPlugin->setListener(NULL).isOk()) {
505 mInitCheck = DEAD_OBJECT;
506 }
507 }
508 mPlugin.clear();
Edwin Wong5641aa22018-01-30 17:52:21 -0800509 mPluginV1_1.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800510 return OK;
511}
512
513status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
514 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800515 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800516
517 status_t err = UNKNOWN_ERROR;
518
519 bool retry = true;
520 do {
521 hidl_vec<uint8_t> hSessionId;
522
523 Return<void> hResult = mPlugin->openSession(
524 [&](Status status, const hidl_vec<uint8_t>& id) {
525 if (status == Status::OK) {
526 sessionId = toVector(id);
527 }
528 err = toStatusT(status);
529 }
530 );
531
532 if (!hResult.isOk()) {
533 err = DEAD_OBJECT;
534 }
535
536 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
537 mLock.unlock();
538 // reclaimSession may call back to closeSession, since mLock is
539 // shared between Drm instances, we should unlock here to avoid
540 // deadlock.
541 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
542 mLock.lock();
543 } else {
544 retry = false;
545 }
546 } while (retry);
547
548 if (err == OK) {
549 DrmSessionManager::Instance()->addSession(getCallingPid(),
550 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700551 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800553
Adam Stonef0e618d2018-01-17 19:20:41 -0800554 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800555 return err;
556}
557
558status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
559 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800560 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800561
Jeff Tinker319d5f42017-07-26 15:44:33 -0700562 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
563 if (status.isOk()) {
564 if (status == Status::OK) {
565 DrmSessionManager::Instance()->removeSession(sessionId);
566 for (size_t i = 0; i < mOpenSessions.size(); i++) {
567 if (mOpenSessions[i] == sessionId) {
568 mOpenSessions.removeAt(i);
569 break;
570 }
Jeff Tinker61332812017-05-15 16:53:10 -0700571 }
572 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700573 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800574 status_t response = toStatusT(status);
575 mMetrics.mCloseSessionCounter.Increment(response);
576 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800577 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800578 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700579 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800580}
581
582status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
583 Vector<uint8_t> const &initData, String8 const &mimeType,
584 DrmPlugin::KeyType keyType, KeyedVector<String8,
585 String8> const &optionalParameters, Vector<uint8_t> &request,
586 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
587 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800588 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800589 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800590
591 DrmSessionManager::Instance()->useSession(sessionId);
592
593 KeyType hKeyType;
594 if (keyType == DrmPlugin::kKeyType_Streaming) {
595 hKeyType = KeyType::STREAMING;
596 } else if (keyType == DrmPlugin::kKeyType_Offline) {
597 hKeyType = KeyType::OFFLINE;
598 } else if (keyType == DrmPlugin::kKeyType_Release) {
599 hKeyType = KeyType::RELEASE;
600 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800601 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800602 return BAD_VALUE;
603 }
604
605 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
606
607 status_t err = UNKNOWN_ERROR;
608
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800609 if (mPluginV1_1 != NULL) {
610 Return<void> hResult =
611 mPluginV1_1->getKeyRequest_1_1(
612 toHidlVec(sessionId), toHidlVec(initData),
613 toHidlString(mimeType), hKeyType, hOptionalParameters,
614 [&](Status status, const hidl_vec<uint8_t>& hRequest,
615 drm::V1_1::KeyRequestType hKeyRequestType,
616 const hidl_string& hDefaultUrl) {
617
618 if (status == Status::OK) {
619 request = toVector(hRequest);
620 defaultUrl = toString8(hDefaultUrl);
621
622 switch (hKeyRequestType) {
623 case drm::V1_1::KeyRequestType::INITIAL:
624 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
625 break;
626 case drm::V1_1::KeyRequestType::RENEWAL:
627 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
628 break;
629 case drm::V1_1::KeyRequestType::RELEASE:
630 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
631 break;
632 case drm::V1_1::KeyRequestType::NONE:
633 *keyRequestType = DrmPlugin::kKeyRequestType_None;
634 break;
635 case drm::V1_1::KeyRequestType::UPDATE:
636 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
637 break;
638 default:
639 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
640 break;
641 }
642 err = toStatusT(status);
643 }
644 });
645 return hResult.isOk() ? err : DEAD_OBJECT;
646 }
647
Jeff Tinkera53d6552017-01-20 00:31:46 -0800648 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
649 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
650 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800651 drm::V1_0::KeyRequestType hKeyRequestType,
652 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800653
654 if (status == Status::OK) {
655 request = toVector(hRequest);
656 defaultUrl = toString8(hDefaultUrl);
657
658 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800659 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800660 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
661 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800662 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800663 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
664 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800665 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800666 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
667 break;
668 default:
669 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
670 break;
671 }
672 err = toStatusT(status);
673 }
674 });
675
Adam Stonef0e618d2018-01-17 19:20:41 -0800676 err = hResult.isOk() ? err : DEAD_OBJECT;
677 keyRequestTimer.SetAttribute(err);
678 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800679}
680
681status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
682 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
683 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800684 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
685
Jeff Tinker6d998b62017-12-18 14:37:43 -0800686 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800687
688 DrmSessionManager::Instance()->useSession(sessionId);
689
690 status_t err = UNKNOWN_ERROR;
691
692 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
693 toHidlVec(response),
694 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
695 if (status == Status::OK) {
696 keySetId = toVector(hKeySetId);
697 }
698 err = toStatusT(status);
699 }
700 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800701 err = hResult.isOk() ? err : DEAD_OBJECT;
702 keyResponseTimer.SetAttribute(err);
703 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800704}
705
706status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
707 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800708 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800709
710 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
711}
712
713status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
714 Vector<uint8_t> const &keySetId) {
715 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800716 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800717
718 DrmSessionManager::Instance()->useSession(sessionId);
719
720 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
721 toHidlVec(keySetId)));
722}
723
724status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
725 KeyedVector<String8, String8> &infoMap) const {
726 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800727 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800728
729 DrmSessionManager::Instance()->useSession(sessionId);
730
731 ::KeyedVector hInfoMap;
732
733 status_t err = UNKNOWN_ERROR;
734
735 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
736 [&](Status status, const hidl_vec<KeyValue>& map) {
737 if (status == Status::OK) {
738 infoMap = toKeyedVector(map);
739 }
740 err = toStatusT(status);
741 }
742 );
743
744 return hResult.isOk() ? err : DEAD_OBJECT;
745}
746
747status_t DrmHal::getProvisionRequest(String8 const &certType,
748 String8 const &certAuthority, Vector<uint8_t> &request,
749 String8 &defaultUrl) {
750 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800751 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800752
753 status_t err = UNKNOWN_ERROR;
754
755 Return<void> hResult = mPlugin->getProvisionRequest(
756 toHidlString(certType), toHidlString(certAuthority),
757 [&](Status status, const hidl_vec<uint8_t>& hRequest,
758 const hidl_string& hDefaultUrl) {
759 if (status == Status::OK) {
760 request = toVector(hRequest);
761 defaultUrl = toString8(hDefaultUrl);
762 }
763 err = toStatusT(status);
764 }
765 );
766
Adam Stonecea91ce2018-01-22 19:23:28 -0800767 err = hResult.isOk() ? err : DEAD_OBJECT;
768 mMetrics.mGetProvisionRequestCounter.Increment(err);
769 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800770}
771
772status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800773 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800774 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800775 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800776
777 status_t err = UNKNOWN_ERROR;
778
779 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
780 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
781 const hidl_vec<uint8_t>& hWrappedKey) {
782 if (status == Status::OK) {
783 certificate = toVector(hCertificate);
784 wrappedKey = toVector(hWrappedKey);
785 }
786 err = toStatusT(status);
787 }
788 );
789
Adam Stonecea91ce2018-01-22 19:23:28 -0800790 err = hResult.isOk() ? err : DEAD_OBJECT;
791 mMetrics.mProvideProvisionResponseCounter.Increment(err);
792 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800793}
794
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800795status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800796 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800797 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800798
799 status_t err = UNKNOWN_ERROR;
800
801 Return<void> hResult = mPlugin->getSecureStops(
802 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
803 if (status == Status::OK) {
804 secureStops = toSecureStops(hSecureStops);
805 }
806 err = toStatusT(status);
807 }
808 );
809
810 return hResult.isOk() ? err : DEAD_OBJECT;
811}
812
813
Jeff Tinker15177d72018-01-25 12:57:55 -0800814status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
815 Mutex::Autolock autoLock(mLock);
816
817 if (mInitCheck != OK) {
818 return mInitCheck;
819 }
820
821 if (mPluginV1_1 == NULL) {
822 return ERROR_DRM_CANNOT_HANDLE;
823 }
824
825 status_t err = UNKNOWN_ERROR;
826
827 Return<void> hResult = mPluginV1_1->getSecureStopIds(
828 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
829 if (status == Status::OK) {
830 secureStopIds = toSecureStopIds(hSecureStopIds);
831 }
832 err = toStatusT(status);
833 }
834 );
835
836 return hResult.isOk() ? err : DEAD_OBJECT;
837}
838
839
Jeff Tinkera53d6552017-01-20 00:31:46 -0800840status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
841 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->getSecureStop(toHidlVec(ssid),
847 [&](Status status, const SecureStop& hSecureStop) {
848 if (status == Status::OK) {
849 secureStop = toVector(hSecureStop.opaqueData);
850 }
851 err = toStatusT(status);
852 }
853 );
854
855 return hResult.isOk() ? err : DEAD_OBJECT;
856}
857
858status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
859 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800860 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800861
Jeff Tinker15177d72018-01-25 12:57:55 -0800862 if (mPluginV1_1 != NULL) {
863 SecureStopRelease secureStopRelease;
864 secureStopRelease.opaqueData = toHidlVec(ssRelease);
865 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
866 }
867
Jeff Tinkera53d6552017-01-20 00:31:46 -0800868 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
869}
870
Jeff Tinker15177d72018-01-25 12:57:55 -0800871status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
872 Mutex::Autolock autoLock(mLock);
873
874 if (mInitCheck != OK) {
875 return mInitCheck;
876 }
877
878 if (mPluginV1_1 == NULL) {
879 return ERROR_DRM_CANNOT_HANDLE;
880 }
881
882 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
883}
884
885status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800886 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800887 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800888
Jeff Tinker15177d72018-01-25 12:57:55 -0800889 if (mPluginV1_1 != NULL) {
890 return toStatusT(mPluginV1_1->removeAllSecureStops());
891 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800892 return toStatusT(mPlugin->releaseAllSecureStops());
893}
894
Jeff Tinker6d998b62017-12-18 14:37:43 -0800895status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
896 DrmPlugin::HdcpLevel *max) const {
897 Mutex::Autolock autoLock(mLock);
898 INIT_CHECK();
899
900 if (connected == NULL || max == NULL) {
901 return BAD_VALUE;
902 }
903 status_t err = UNKNOWN_ERROR;
904
905 if (mPluginV1_1 == NULL) {
906 return ERROR_DRM_CANNOT_HANDLE;
907 }
908
909 *connected = DrmPlugin::kHdcpLevelUnknown;
910 *max = DrmPlugin::kHdcpLevelUnknown;
911
912 Return<void> hResult = mPluginV1_1->getHdcpLevels(
913 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
914 if (status == Status::OK) {
915 *connected = toHdcpLevel(hConnected);
916 *max = toHdcpLevel(hMax);
917 }
918 err = toStatusT(status);
919 }
920 );
921
922 return hResult.isOk() ? err : DEAD_OBJECT;
923}
924
925status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
926 Mutex::Autolock autoLock(mLock);
927 INIT_CHECK();
928
929 if (open == NULL || max == NULL) {
930 return BAD_VALUE;
931 }
932 status_t err = UNKNOWN_ERROR;
933
934 *open = 0;
935 *max = 0;
936
937 if (mPluginV1_1 == NULL) {
938 return ERROR_DRM_CANNOT_HANDLE;
939 }
940
941 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
942 [&](Status status, uint32_t hOpen, uint32_t hMax) {
943 if (status == Status::OK) {
944 *open = hOpen;
945 *max = hMax;
946 }
947 err = toStatusT(status);
948 }
949 );
950
951 return hResult.isOk() ? err : DEAD_OBJECT;
952}
953
954status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
955 DrmPlugin::SecurityLevel *level) const {
956 Mutex::Autolock autoLock(mLock);
957 INIT_CHECK();
958
959 if (level == NULL) {
960 return BAD_VALUE;
961 }
962 status_t err = UNKNOWN_ERROR;
963
964 if (mPluginV1_1 == NULL) {
965 return ERROR_DRM_CANNOT_HANDLE;
966 }
967
968 *level = DrmPlugin::kSecurityLevelUnknown;
969
970 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
971 [&](Status status, SecurityLevel hLevel) {
972 if (status == Status::OK) {
973 *level = toSecurityLevel(hLevel);
974 }
975 err = toStatusT(status);
976 }
977 );
978
979 return hResult.isOk() ? err : DEAD_OBJECT;
980}
981
982status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
983 const DrmPlugin::SecurityLevel& level) {
984 Mutex::Autolock autoLock(mLock);
985 INIT_CHECK();
986
987 if (mPluginV1_1 == NULL) {
988 return ERROR_DRM_CANNOT_HANDLE;
989 }
990
991 SecurityLevel hSecurityLevel;
992
993 switch(level) {
994 case DrmPlugin::kSecurityLevelSwSecureCrypto:
995 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
996 break;
997 case DrmPlugin::kSecurityLevelSwSecureDecode:
998 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
999 break;
1000 case DrmPlugin::kSecurityLevelHwSecureCrypto:
1001 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
1002 break;
1003 case DrmPlugin::kSecurityLevelHwSecureDecode:
1004 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
1005 break;
1006 case DrmPlugin::kSecurityLevelHwSecureAll:
1007 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
1008 break;
1009 default:
1010 return ERROR_DRM_CANNOT_HANDLE;
1011 }
1012
1013 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
1014 hSecurityLevel);
1015 return toStatusT(status);
1016}
1017
Jeff Tinkera53d6552017-01-20 00:31:46 -08001018status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1019 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001020 return getPropertyStringInternal(name, value);
1021}
1022
1023status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1024 // This function is internal to the class and should only be called while
1025 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001026 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001027
1028 status_t err = UNKNOWN_ERROR;
1029
1030 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1031 [&](Status status, const hidl_string& hValue) {
1032 if (status == Status::OK) {
1033 value = toString8(hValue);
1034 }
1035 err = toStatusT(status);
1036 }
1037 );
1038
1039 return hResult.isOk() ? err : DEAD_OBJECT;
1040}
1041
1042status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1043 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001044 return getPropertyByteArrayInternal(name, value);
1045}
1046
1047status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1048 // This function is internal to the class and should only be called while
1049 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001050 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001051
1052 status_t err = UNKNOWN_ERROR;
1053
1054 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1055 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1056 if (status == Status::OK) {
1057 value = toVector(hValue);
1058 }
1059 err = toStatusT(status);
1060 }
1061 );
1062
Adam Stonecea91ce2018-01-22 19:23:28 -08001063 err = hResult.isOk() ? err : DEAD_OBJECT;
1064 if (name == kPropertyDeviceUniqueId) {
1065 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1066 }
1067 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001068}
1069
1070status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1071 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001072 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001073
Jeff Tinker6d998b62017-12-18 14:37:43 -08001074 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001075 toHidlString(value));
1076 return toStatusT(status);
1077}
1078
1079status_t DrmHal::setPropertyByteArray(String8 const &name,
1080 Vector<uint8_t> const &value ) const {
1081 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001082 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001083
1084 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1085 toHidlVec(value));
1086 return toStatusT(status);
1087}
1088
Adam Stonef0e618d2018-01-17 19:20:41 -08001089status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
1090 if (item == nullptr) {
1091 return UNEXPECTED_NULL;
1092 }
1093
1094 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001095 return OK;
1096}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001097
1098status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1099 String8 const &algorithm) {
1100 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001101 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001102
1103 DrmSessionManager::Instance()->useSession(sessionId);
1104
1105 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1106 toHidlString(algorithm));
1107 return toStatusT(status);
1108}
1109
1110status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1111 String8 const &algorithm) {
1112 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001113 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001114
1115 DrmSessionManager::Instance()->useSession(sessionId);
1116
1117 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1118 toHidlString(algorithm));
1119 return toStatusT(status);
1120}
1121
1122status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001123 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1124 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001125 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001126 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001127
1128 DrmSessionManager::Instance()->useSession(sessionId);
1129
1130 status_t err = UNKNOWN_ERROR;
1131
1132 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1133 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1134 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1135 if (status == Status::OK) {
1136 output = toVector(hOutput);
1137 }
1138 err = toStatusT(status);
1139 }
1140 );
1141
1142 return hResult.isOk() ? err : DEAD_OBJECT;
1143}
1144
1145status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001146 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1147 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001148 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001149 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001150
1151 DrmSessionManager::Instance()->useSession(sessionId);
1152
1153 status_t err = UNKNOWN_ERROR;
1154
1155 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1156 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1157 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1158 if (status == Status::OK) {
1159 output = toVector(hOutput);
1160 }
1161 err = toStatusT(status);
1162 }
1163 );
1164
1165 return hResult.isOk() ? err : DEAD_OBJECT;
1166}
1167
1168status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001169 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1170 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001171 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001172 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001173
1174 DrmSessionManager::Instance()->useSession(sessionId);
1175
1176 status_t err = UNKNOWN_ERROR;
1177
1178 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1179 toHidlVec(keyId), toHidlVec(message),
1180 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1181 if (status == Status::OK) {
1182 signature = toVector(hSignature);
1183 }
1184 err = toStatusT(status);
1185 }
1186 );
1187
1188 return hResult.isOk() ? err : DEAD_OBJECT;
1189}
1190
1191status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001192 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1193 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001194 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001195 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001196
1197 DrmSessionManager::Instance()->useSession(sessionId);
1198
1199 status_t err = UNKNOWN_ERROR;
1200
1201 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1202 toHidlVec(message), toHidlVec(signature),
1203 [&](Status status, bool hMatch) {
1204 if (status == Status::OK) {
1205 match = hMatch;
1206 } else {
1207 match = false;
1208 }
1209 err = toStatusT(status);
1210 }
1211 );
1212
1213 return hResult.isOk() ? err : DEAD_OBJECT;
1214}
1215
1216status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001217 String8 const &algorithm, Vector<uint8_t> const &message,
1218 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001219 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001220 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001221
1222 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1223 return -EPERM;
1224 }
1225
1226 DrmSessionManager::Instance()->useSession(sessionId);
1227
1228 status_t err = UNKNOWN_ERROR;
1229
1230 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1231 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1232 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1233 if (status == Status::OK) {
1234 signature = toVector(hSignature);
1235 }
1236 err = toStatusT(status);
1237 }
1238 );
1239
1240 return hResult.isOk() ? err : DEAD_OBJECT;
1241}
1242
1243void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1244{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001245 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001246 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001247 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001248 mInitCheck = NO_INIT;
1249
Jeff Tinker70367f52017-06-16 12:41:33 -07001250 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001251 if (!mPlugin->setListener(NULL).isOk()) {
1252 mInitCheck = DEAD_OBJECT;
1253 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001254 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001255 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001256}
1257
1258void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1259{
1260 if (vec.size()) {
1261 obj.writeInt32(vec.size());
1262 obj.write(vec.data(), vec.size());
1263 } else {
1264 obj.writeInt32(0);
1265 }
1266}
1267
Adam Stoneab394d12017-12-22 12:34:20 -08001268
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001269void DrmHal::reportMetrics() const
1270{
1271 Vector<uint8_t> metrics;
1272 String8 vendor;
1273 String8 description;
1274 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1275 getPropertyStringInternal(String8("description"), description) == OK &&
1276 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1277 status_t res = android::reportDrmPluginMetrics(
1278 metrics, vendor, description);
1279 if (res != OK) {
1280 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1281 }
1282 }
1283}
1284
Jeff Tinkera53d6552017-01-20 00:31:46 -08001285} // namespace android