blob: 02f74a849e1e5fd0694cca3795d9de92967e30c4 [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>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070033#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080034#include <media/drm/DrmAPI.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AString.h>
37#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/MediaErrors.h>
39
Jeff Tinker6d998b62017-12-18 14:37:43 -080040using drm::V1_0::KeyedVector;
41using drm::V1_0::KeyRequestType;
42using drm::V1_0::KeyStatusType;
43using drm::V1_0::KeyType;
44using drm::V1_0::KeyValue;
45using drm::V1_1::HdcpLevel;;
46using drm::V1_0::SecureStop;
47using 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
57namespace android {
58
Jeff Tinker6d998b62017-12-18 14:37:43 -080059#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
60
Jeff Tinkera53d6552017-01-20 00:31:46 -080061static inline int getCallingPid() {
62 return IPCThreadState::self()->getCallingPid();
63}
64
65static bool checkPermission(const char* permissionString) {
66 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
67 bool ok = checkCallingPermission(String16(permissionString));
68 if (!ok) ALOGE("Request requires %s", permissionString);
69 return ok;
70}
71
72static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
73 Vector<uint8_t> vector;
74 vector.appendArray(vec.data(), vec.size());
75 return *const_cast<const Vector<uint8_t> *>(&vector);
76}
77
78static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
79 hidl_vec<uint8_t> vec;
80 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
81 return vec;
82}
83
84static String8 toString8(const hidl_string &string) {
85 return String8(string.c_str());
86}
87
88static hidl_string toHidlString(const String8& string) {
89 return hidl_string(string.string());
90}
91
Jeff Tinker6d998b62017-12-18 14:37:43 -080092static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
93 switch(level) {
94 case SecurityLevel::SW_SECURE_CRYPTO:
95 return DrmPlugin::kSecurityLevelSwSecureCrypto;
96 case SecurityLevel::SW_SECURE_DECODE:
97 return DrmPlugin::kSecurityLevelSwSecureDecode;
98 case SecurityLevel::HW_SECURE_CRYPTO:
99 return DrmPlugin::kSecurityLevelHwSecureCrypto;
100 case SecurityLevel::HW_SECURE_DECODE:
101 return DrmPlugin::kSecurityLevelHwSecureDecode;
102 case SecurityLevel::HW_SECURE_ALL:
103 return DrmPlugin::kSecurityLevelHwSecureAll;
104 default:
105 return DrmPlugin::kSecurityLevelUnknown;
106 }
107}
108
109static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
110 switch(level) {
111 case HdcpLevel::HDCP_NONE:
112 return DrmPlugin::kHdcpNone;
113 case HdcpLevel::HDCP_V1:
114 return DrmPlugin::kHdcpV1;
115 case HdcpLevel::HDCP_V2:
116 return DrmPlugin::kHdcpV2;
117 case HdcpLevel::HDCP_V2_1:
118 return DrmPlugin::kHdcpV2_1;
119 case HdcpLevel::HDCP_V2_2:
120 return DrmPlugin::kHdcpV2_2;
121 case HdcpLevel::HDCP_NO_OUTPUT:
122 return DrmPlugin::kHdcpNoOutput;
123 default:
124 return DrmPlugin::kHdcpLevelUnknown;
125 }
126}
127
Jeff Tinkera53d6552017-01-20 00:31:46 -0800128
129static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
130 keyedVector) {
131 std::vector<KeyValue> stdKeyedVector;
132 for (size_t i = 0; i < keyedVector.size(); i++) {
133 KeyValue keyValue;
134 keyValue.key = toHidlString(keyedVector.keyAt(i));
135 keyValue.value = toHidlString(keyedVector.valueAt(i));
136 stdKeyedVector.push_back(keyValue);
137 }
138 return ::KeyedVector(stdKeyedVector);
139}
140
141static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
142 hKeyedVector) {
143 KeyedVector<String8, String8> keyedVector;
144 for (size_t i = 0; i < hKeyedVector.size(); i++) {
145 keyedVector.add(toString8(hKeyedVector[i].key),
146 toString8(hKeyedVector[i].value));
147 }
148 return keyedVector;
149}
150
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800151static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800152 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800153 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800154 for (size_t i = 0; i < hSecureStops.size(); i++) {
155 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
156 }
157 return secureStops;
158}
159
160static status_t toStatusT(Status status) {
161 switch (status) {
162 case Status::OK:
163 return OK;
164 break;
165 case Status::ERROR_DRM_NO_LICENSE:
166 return ERROR_DRM_NO_LICENSE;
167 break;
168 case Status::ERROR_DRM_LICENSE_EXPIRED:
169 return ERROR_DRM_LICENSE_EXPIRED;
170 break;
171 case Status::ERROR_DRM_SESSION_NOT_OPENED:
172 return ERROR_DRM_SESSION_NOT_OPENED;
173 break;
174 case Status::ERROR_DRM_CANNOT_HANDLE:
175 return ERROR_DRM_CANNOT_HANDLE;
176 break;
177 case Status::ERROR_DRM_INVALID_STATE:
178 return ERROR_DRM_TAMPER_DETECTED;
179 break;
180 case Status::BAD_VALUE:
181 return BAD_VALUE;
182 break;
183 case Status::ERROR_DRM_NOT_PROVISIONED:
184 return ERROR_DRM_NOT_PROVISIONED;
185 break;
186 case Status::ERROR_DRM_RESOURCE_BUSY:
187 return ERROR_DRM_RESOURCE_BUSY;
188 break;
189 case Status::ERROR_DRM_DEVICE_REVOKED:
190 return ERROR_DRM_DEVICE_REVOKED;
191 break;
192 case Status::ERROR_DRM_UNKNOWN:
193 default:
194 return ERROR_DRM_UNKNOWN;
195 break;
196 }
197}
198
199
200Mutex DrmHal::mLock;
201
202struct DrmSessionClient : public DrmSessionClientInterface {
203 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
204
205 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
206 sp<DrmHal> drm = mDrm.promote();
207 if (drm == NULL) {
208 return true;
209 }
210 status_t err = drm->closeSession(sessionId);
211 if (err != OK) {
212 return false;
213 }
214 drm->sendEvent(EventType::SESSION_RECLAIMED,
215 toHidlVec(sessionId), hidl_vec<uint8_t>());
216 return true;
217 }
218
219protected:
220 virtual ~DrmSessionClient() {}
221
222private:
223 wp<DrmHal> mDrm;
224
225 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
226};
227
228DrmHal::DrmHal()
229 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800230 mFactories(makeDrmFactories()),
231 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800232}
233
Jeff Tinker61332812017-05-15 16:53:10 -0700234void DrmHal::closeOpenSessions() {
235 if (mPlugin != NULL) {
236 for (size_t i = 0; i < mOpenSessions.size(); i++) {
237 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
238 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
239 }
240 }
241 mOpenSessions.clear();
242}
243
Jeff Tinkera53d6552017-01-20 00:31:46 -0800244DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700245 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800246 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
247}
248
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800249Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
250 Vector<sp<IDrmFactory>> factories;
251
Jeff Tinker593111f2017-05-25 16:00:21 -0700252 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800253
254 if (manager != NULL) {
255 manager->listByInterface(IDrmFactory::descriptor,
256 [&factories](const hidl_vec<hidl_string> &registered) {
257 for (const auto &instance : registered) {
258 auto factory = IDrmFactory::getService(instance);
259 if (factory != NULL) {
260 factories.push_back(factory);
261 ALOGI("makeDrmFactories: factory instance %s is %s",
262 instance.c_str(),
263 factory->isRemote() ? "Remote" : "Not Remote");
264 }
265 }
266 }
267 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800268 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800269
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800270 if (factories.size() == 0) {
271 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700272 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800273 if (passthrough != NULL) {
274 ALOGI("makeDrmFactories: using default drm instance");
275 factories.push_back(passthrough);
276 } else {
277 ALOGE("Failed to find any drm factories");
278 }
279 }
280 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800281}
282
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800283sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
284 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800285
286 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800287 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800288 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800289 if (status != Status::OK) {
290 ALOGE("Failed to make drm plugin");
291 return;
292 }
293 plugin = hPlugin;
294 }
295 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700296
297 if (!hResult.isOk()) {
298 ALOGE("createPlugin remote call failed");
299 }
300
Jeff Tinkera53d6552017-01-20 00:31:46 -0800301 return plugin;
302}
303
304status_t DrmHal::initCheck() const {
305 return mInitCheck;
306}
307
308status_t DrmHal::setListener(const sp<IDrmClient>& listener)
309{
310 Mutex::Autolock lock(mEventLock);
311 if (mListener != NULL){
312 IInterface::asBinder(mListener)->unlinkToDeath(this);
313 }
314 if (listener != NULL) {
315 IInterface::asBinder(listener)->linkToDeath(this);
316 }
317 mListener = listener;
318 return NO_ERROR;
319}
320
321Return<void> DrmHal::sendEvent(EventType hEventType,
322 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
323
324 mEventLock.lock();
325 sp<IDrmClient> listener = mListener;
326 mEventLock.unlock();
327
328 if (listener != NULL) {
329 Parcel obj;
330 writeByteArray(obj, sessionId);
331 writeByteArray(obj, data);
332
333 Mutex::Autolock lock(mNotifyLock);
334 DrmPlugin::EventType eventType;
335 switch(hEventType) {
336 case EventType::PROVISION_REQUIRED:
337 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
338 break;
339 case EventType::KEY_NEEDED:
340 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
341 break;
342 case EventType::KEY_EXPIRED:
343 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
344 break;
345 case EventType::VENDOR_DEFINED:
346 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
347 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700348 case EventType::SESSION_RECLAIMED:
349 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
350 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800351 default:
352 return Void();
353 }
354 listener->notify(eventType, 0, &obj);
355 }
356 return Void();
357}
358
359Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
360 int64_t expiryTimeInMS) {
361
362 mEventLock.lock();
363 sp<IDrmClient> listener = mListener;
364 mEventLock.unlock();
365
366 if (listener != NULL) {
367 Parcel obj;
368 writeByteArray(obj, sessionId);
369 obj.writeInt64(expiryTimeInMS);
370
371 Mutex::Autolock lock(mNotifyLock);
372 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
373 }
374 return Void();
375}
376
377Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
378 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
379
380 mEventLock.lock();
381 sp<IDrmClient> listener = mListener;
382 mEventLock.unlock();
383
384 if (listener != NULL) {
385 Parcel obj;
386 writeByteArray(obj, sessionId);
387
388 size_t nKeys = keyStatusList.size();
389 obj.writeInt32(nKeys);
390 for (size_t i = 0; i < nKeys; ++i) {
391 const KeyStatus &keyStatus = keyStatusList[i];
392 writeByteArray(obj, keyStatus.keyId);
393 uint32_t type;
394 switch(keyStatus.type) {
395 case KeyStatusType::USABLE:
396 type = DrmPlugin::kKeyStatusType_Usable;
397 break;
398 case KeyStatusType::EXPIRED:
399 type = DrmPlugin::kKeyStatusType_Expired;
400 break;
401 case KeyStatusType::OUTPUTNOTALLOWED:
402 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
403 break;
404 case KeyStatusType::STATUSPENDING:
405 type = DrmPlugin::kKeyStatusType_StatusPending;
406 break;
407 case KeyStatusType::INTERNALERROR:
408 default:
409 type = DrmPlugin::kKeyStatusType_InternalError;
410 break;
411 }
412 obj.writeInt32(type);
413 }
414 obj.writeInt32(hasNewUsableKey);
415
416 Mutex::Autolock lock(mNotifyLock);
417 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
418 }
419 return Void();
420}
421
422bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
423 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800424
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800425 for (size_t i = 0; i < mFactories.size(); i++) {
426 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
427 if (mimeType != "") {
428 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
429 return true;
430 }
431 } else {
432 return true;
433 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800434 }
435 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800436 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437}
438
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800439status_t DrmHal::createPlugin(const uint8_t uuid[16],
440 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800441 Mutex::Autolock autoLock(mLock);
442
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800443 for (size_t i = 0; i < mFactories.size(); i++) {
444 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
445 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800446 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800447 }
448 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800449
450 if (mPlugin == NULL) {
451 mInitCheck = ERROR_UNSUPPORTED;
452 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700453 if (!mPlugin->setListener(this).isOk()) {
454 mInitCheck = DEAD_OBJECT;
455 } else {
456 mInitCheck = OK;
457 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800458 }
459
460 return mInitCheck;
461}
462
463status_t DrmHal::destroyPlugin() {
464 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800465 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800466
Jeff Tinker61332812017-05-15 16:53:10 -0700467 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700468 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800469 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700470 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800471
Jeff Tinker319d5f42017-07-26 15:44:33 -0700472 if (mPlugin != NULL) {
473 if (!mPlugin->setListener(NULL).isOk()) {
474 mInitCheck = DEAD_OBJECT;
475 }
476 }
477 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800478 return OK;
479}
480
481status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
482 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800483 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800484
485 status_t err = UNKNOWN_ERROR;
486
487 bool retry = true;
488 do {
489 hidl_vec<uint8_t> hSessionId;
490
491 Return<void> hResult = mPlugin->openSession(
492 [&](Status status, const hidl_vec<uint8_t>& id) {
493 if (status == Status::OK) {
494 sessionId = toVector(id);
495 }
496 err = toStatusT(status);
497 }
498 );
499
500 if (!hResult.isOk()) {
501 err = DEAD_OBJECT;
502 }
503
504 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
505 mLock.unlock();
506 // reclaimSession may call back to closeSession, since mLock is
507 // shared between Drm instances, we should unlock here to avoid
508 // deadlock.
509 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
510 mLock.lock();
511 } else {
512 retry = false;
513 }
514 } while (retry);
515
516 if (err == OK) {
517 DrmSessionManager::Instance()->addSession(getCallingPid(),
518 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700519 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800520 }
521 return err;
522}
523
524status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
525 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800526 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800527
Jeff Tinker319d5f42017-07-26 15:44:33 -0700528 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
529 if (status.isOk()) {
530 if (status == Status::OK) {
531 DrmSessionManager::Instance()->removeSession(sessionId);
532 for (size_t i = 0; i < mOpenSessions.size(); i++) {
533 if (mOpenSessions[i] == sessionId) {
534 mOpenSessions.removeAt(i);
535 break;
536 }
Jeff Tinker61332812017-05-15 16:53:10 -0700537 }
538 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700539 reportMetrics();
540 return toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800541 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700542 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800543}
544
545status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
546 Vector<uint8_t> const &initData, String8 const &mimeType,
547 DrmPlugin::KeyType keyType, KeyedVector<String8,
548 String8> const &optionalParameters, Vector<uint8_t> &request,
549 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
550 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800551 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800552
553 DrmSessionManager::Instance()->useSession(sessionId);
554
555 KeyType hKeyType;
556 if (keyType == DrmPlugin::kKeyType_Streaming) {
557 hKeyType = KeyType::STREAMING;
558 } else if (keyType == DrmPlugin::kKeyType_Offline) {
559 hKeyType = KeyType::OFFLINE;
560 } else if (keyType == DrmPlugin::kKeyType_Release) {
561 hKeyType = KeyType::RELEASE;
562 } else {
563 return BAD_VALUE;
564 }
565
566 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
567
568 status_t err = UNKNOWN_ERROR;
569
570 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
571 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
572 [&](Status status, const hidl_vec<uint8_t>& hRequest,
573 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
574
575 if (status == Status::OK) {
576 request = toVector(hRequest);
577 defaultUrl = toString8(hDefaultUrl);
578
579 switch (hKeyRequestType) {
580 case KeyRequestType::INITIAL:
581 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
582 break;
583 case KeyRequestType::RENEWAL:
584 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
585 break;
586 case KeyRequestType::RELEASE:
587 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
588 break;
589 default:
590 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
591 break;
592 }
593 err = toStatusT(status);
594 }
595 });
596
597 return hResult.isOk() ? err : DEAD_OBJECT;
598}
599
600status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
601 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
602 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800603 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800604
605 DrmSessionManager::Instance()->useSession(sessionId);
606
607 status_t err = UNKNOWN_ERROR;
608
609 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
610 toHidlVec(response),
611 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
612 if (status == Status::OK) {
613 keySetId = toVector(hKeySetId);
614 }
615 err = toStatusT(status);
616 }
617 );
618
619 return hResult.isOk() ? err : DEAD_OBJECT;
620}
621
622status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
623 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800624 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800625
626 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
627}
628
629status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
630 Vector<uint8_t> const &keySetId) {
631 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800632 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800633
634 DrmSessionManager::Instance()->useSession(sessionId);
635
636 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
637 toHidlVec(keySetId)));
638}
639
640status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
641 KeyedVector<String8, String8> &infoMap) const {
642 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800643 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800644
645 DrmSessionManager::Instance()->useSession(sessionId);
646
647 ::KeyedVector hInfoMap;
648
649 status_t err = UNKNOWN_ERROR;
650
651 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
652 [&](Status status, const hidl_vec<KeyValue>& map) {
653 if (status == Status::OK) {
654 infoMap = toKeyedVector(map);
655 }
656 err = toStatusT(status);
657 }
658 );
659
660 return hResult.isOk() ? err : DEAD_OBJECT;
661}
662
663status_t DrmHal::getProvisionRequest(String8 const &certType,
664 String8 const &certAuthority, Vector<uint8_t> &request,
665 String8 &defaultUrl) {
666 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800667 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800668
669 status_t err = UNKNOWN_ERROR;
670
671 Return<void> hResult = mPlugin->getProvisionRequest(
672 toHidlString(certType), toHidlString(certAuthority),
673 [&](Status status, const hidl_vec<uint8_t>& hRequest,
674 const hidl_string& hDefaultUrl) {
675 if (status == Status::OK) {
676 request = toVector(hRequest);
677 defaultUrl = toString8(hDefaultUrl);
678 }
679 err = toStatusT(status);
680 }
681 );
682
683 return hResult.isOk() ? err : DEAD_OBJECT;
684}
685
686status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800687 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800688 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800689 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800690
691 status_t err = UNKNOWN_ERROR;
692
693 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
694 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
695 const hidl_vec<uint8_t>& hWrappedKey) {
696 if (status == Status::OK) {
697 certificate = toVector(hCertificate);
698 wrappedKey = toVector(hWrappedKey);
699 }
700 err = toStatusT(status);
701 }
702 );
703
704 return hResult.isOk() ? err : DEAD_OBJECT;
705}
706
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800707status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800708 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800709 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800710
711 status_t err = UNKNOWN_ERROR;
712
713 Return<void> hResult = mPlugin->getSecureStops(
714 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
715 if (status == Status::OK) {
716 secureStops = toSecureStops(hSecureStops);
717 }
718 err = toStatusT(status);
719 }
720 );
721
722 return hResult.isOk() ? err : DEAD_OBJECT;
723}
724
725
726status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
727 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800728 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800729
730 status_t err = UNKNOWN_ERROR;
731
732 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
733 [&](Status status, const SecureStop& hSecureStop) {
734 if (status == Status::OK) {
735 secureStop = toVector(hSecureStop.opaqueData);
736 }
737 err = toStatusT(status);
738 }
739 );
740
741 return hResult.isOk() ? err : DEAD_OBJECT;
742}
743
744status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
745 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800746 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800747
748 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
749}
750
751status_t DrmHal::releaseAllSecureStops() {
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->releaseAllSecureStops());
756}
757
Jeff Tinker6d998b62017-12-18 14:37:43 -0800758status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
759 DrmPlugin::HdcpLevel *max) const {
760 Mutex::Autolock autoLock(mLock);
761 INIT_CHECK();
762
763 if (connected == NULL || max == NULL) {
764 return BAD_VALUE;
765 }
766 status_t err = UNKNOWN_ERROR;
767
768 if (mPluginV1_1 == NULL) {
769 return ERROR_DRM_CANNOT_HANDLE;
770 }
771
772 *connected = DrmPlugin::kHdcpLevelUnknown;
773 *max = DrmPlugin::kHdcpLevelUnknown;
774
775 Return<void> hResult = mPluginV1_1->getHdcpLevels(
776 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
777 if (status == Status::OK) {
778 *connected = toHdcpLevel(hConnected);
779 *max = toHdcpLevel(hMax);
780 }
781 err = toStatusT(status);
782 }
783 );
784
785 return hResult.isOk() ? err : DEAD_OBJECT;
786}
787
788status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
789 Mutex::Autolock autoLock(mLock);
790 INIT_CHECK();
791
792 if (open == NULL || max == NULL) {
793 return BAD_VALUE;
794 }
795 status_t err = UNKNOWN_ERROR;
796
797 *open = 0;
798 *max = 0;
799
800 if (mPluginV1_1 == NULL) {
801 return ERROR_DRM_CANNOT_HANDLE;
802 }
803
804 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
805 [&](Status status, uint32_t hOpen, uint32_t hMax) {
806 if (status == Status::OK) {
807 *open = hOpen;
808 *max = hMax;
809 }
810 err = toStatusT(status);
811 }
812 );
813
814 return hResult.isOk() ? err : DEAD_OBJECT;
815}
816
817status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
818 DrmPlugin::SecurityLevel *level) const {
819 Mutex::Autolock autoLock(mLock);
820 INIT_CHECK();
821
822 if (level == NULL) {
823 return BAD_VALUE;
824 }
825 status_t err = UNKNOWN_ERROR;
826
827 if (mPluginV1_1 == NULL) {
828 return ERROR_DRM_CANNOT_HANDLE;
829 }
830
831 *level = DrmPlugin::kSecurityLevelUnknown;
832
833 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
834 [&](Status status, SecurityLevel hLevel) {
835 if (status == Status::OK) {
836 *level = toSecurityLevel(hLevel);
837 }
838 err = toStatusT(status);
839 }
840 );
841
842 return hResult.isOk() ? err : DEAD_OBJECT;
843}
844
845status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
846 const DrmPlugin::SecurityLevel& level) {
847 Mutex::Autolock autoLock(mLock);
848 INIT_CHECK();
849
850 if (mPluginV1_1 == NULL) {
851 return ERROR_DRM_CANNOT_HANDLE;
852 }
853
854 SecurityLevel hSecurityLevel;
855
856 switch(level) {
857 case DrmPlugin::kSecurityLevelSwSecureCrypto:
858 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
859 break;
860 case DrmPlugin::kSecurityLevelSwSecureDecode:
861 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
862 break;
863 case DrmPlugin::kSecurityLevelHwSecureCrypto:
864 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
865 break;
866 case DrmPlugin::kSecurityLevelHwSecureDecode:
867 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
868 break;
869 case DrmPlugin::kSecurityLevelHwSecureAll:
870 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
871 break;
872 default:
873 return ERROR_DRM_CANNOT_HANDLE;
874 }
875
876 Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
877 hSecurityLevel);
878 return toStatusT(status);
879}
880
Jeff Tinkera53d6552017-01-20 00:31:46 -0800881status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
882 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700883 return getPropertyStringInternal(name, value);
884}
885
886status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
887 // This function is internal to the class and should only be called while
888 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800889 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800890
891 status_t err = UNKNOWN_ERROR;
892
893 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
894 [&](Status status, const hidl_string& hValue) {
895 if (status == Status::OK) {
896 value = toString8(hValue);
897 }
898 err = toStatusT(status);
899 }
900 );
901
902 return hResult.isOk() ? err : DEAD_OBJECT;
903}
904
905status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
906 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700907 return getPropertyByteArrayInternal(name, value);
908}
909
910status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
911 // This function is internal to the class and should only be called while
912 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -0800913 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800914
915 status_t err = UNKNOWN_ERROR;
916
917 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
918 [&](Status status, const hidl_vec<uint8_t>& hValue) {
919 if (status == Status::OK) {
920 value = toVector(hValue);
921 }
922 err = toStatusT(status);
923 }
924 );
925
926 return hResult.isOk() ? err : DEAD_OBJECT;
927}
928
929status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
930 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800931 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932
Jeff Tinker6d998b62017-12-18 14:37:43 -0800933 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800934 toHidlString(value));
935 return toStatusT(status);
936}
937
938status_t DrmHal::setPropertyByteArray(String8 const &name,
939 Vector<uint8_t> const &value ) const {
940 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800941 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800942
943 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
944 toHidlVec(value));
945 return toStatusT(status);
946}
947
948
949status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
950 String8 const &algorithm) {
951 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800952 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800953
954 DrmSessionManager::Instance()->useSession(sessionId);
955
956 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
957 toHidlString(algorithm));
958 return toStatusT(status);
959}
960
961status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
962 String8 const &algorithm) {
963 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800964 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800965
966 DrmSessionManager::Instance()->useSession(sessionId);
967
968 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
969 toHidlString(algorithm));
970 return toStatusT(status);
971}
972
973status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800974 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
975 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800976 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800977 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800978
979 DrmSessionManager::Instance()->useSession(sessionId);
980
981 status_t err = UNKNOWN_ERROR;
982
983 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
984 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
985 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
986 if (status == Status::OK) {
987 output = toVector(hOutput);
988 }
989 err = toStatusT(status);
990 }
991 );
992
993 return hResult.isOk() ? err : DEAD_OBJECT;
994}
995
996status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800997 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
998 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800999 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001000 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001001
1002 DrmSessionManager::Instance()->useSession(sessionId);
1003
1004 status_t err = UNKNOWN_ERROR;
1005
1006 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1007 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1008 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1009 if (status == Status::OK) {
1010 output = toVector(hOutput);
1011 }
1012 err = toStatusT(status);
1013 }
1014 );
1015
1016 return hResult.isOk() ? err : DEAD_OBJECT;
1017}
1018
1019status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001020 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1021 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001022 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001023 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001024
1025 DrmSessionManager::Instance()->useSession(sessionId);
1026
1027 status_t err = UNKNOWN_ERROR;
1028
1029 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1030 toHidlVec(keyId), toHidlVec(message),
1031 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1032 if (status == Status::OK) {
1033 signature = toVector(hSignature);
1034 }
1035 err = toStatusT(status);
1036 }
1037 );
1038
1039 return hResult.isOk() ? err : DEAD_OBJECT;
1040}
1041
1042status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001043 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1044 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001045 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001046 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001047
1048 DrmSessionManager::Instance()->useSession(sessionId);
1049
1050 status_t err = UNKNOWN_ERROR;
1051
1052 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1053 toHidlVec(message), toHidlVec(signature),
1054 [&](Status status, bool hMatch) {
1055 if (status == Status::OK) {
1056 match = hMatch;
1057 } else {
1058 match = false;
1059 }
1060 err = toStatusT(status);
1061 }
1062 );
1063
1064 return hResult.isOk() ? err : DEAD_OBJECT;
1065}
1066
1067status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001068 String8 const &algorithm, Vector<uint8_t> const &message,
1069 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001070 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001071 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001072
1073 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1074 return -EPERM;
1075 }
1076
1077 DrmSessionManager::Instance()->useSession(sessionId);
1078
1079 status_t err = UNKNOWN_ERROR;
1080
1081 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1082 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1083 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1084 if (status == Status::OK) {
1085 signature = toVector(hSignature);
1086 }
1087 err = toStatusT(status);
1088 }
1089 );
1090
1091 return hResult.isOk() ? err : DEAD_OBJECT;
1092}
1093
1094void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1095{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001096 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001097 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001098 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001099 mInitCheck = NO_INIT;
1100
Jeff Tinker70367f52017-06-16 12:41:33 -07001101 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001102 if (!mPlugin->setListener(NULL).isOk()) {
1103 mInitCheck = DEAD_OBJECT;
1104 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001105 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001106 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001107}
1108
1109void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1110{
1111 if (vec.size()) {
1112 obj.writeInt32(vec.size());
1113 obj.write(vec.data(), vec.size());
1114 } else {
1115 obj.writeInt32(0);
1116 }
1117}
1118
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001119void DrmHal::reportMetrics() const
1120{
1121 Vector<uint8_t> metrics;
1122 String8 vendor;
1123 String8 description;
1124 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1125 getPropertyStringInternal(String8("description"), description) == OK &&
1126 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1127 status_t res = android::reportDrmPluginMetrics(
1128 metrics, vendor, description);
1129 if (res != OK) {
1130 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1131 }
1132 }
1133}
1134
Jeff Tinkera53d6552017-01-20 00:31:46 -08001135} // namespace android