blob: 3bbc34b9498af696c101cfc747260fd8148e9efc [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
Jeff Tinker56134cc2018-02-05 13:09:23 -0800513status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
514 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800515 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800516 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800517
Jeff Tinker56134cc2018-02-05 13:09:23 -0800518 SecurityLevel hSecurityLevel;
519 bool setSecurityLevel = true;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800520
Jeff Tinker56134cc2018-02-05 13:09:23 -0800521 switch(level) {
522 case DrmPlugin::kSecurityLevelSwSecureCrypto:
523 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
524 break;
525 case DrmPlugin::kSecurityLevelSwSecureDecode:
526 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
527 break;
528 case DrmPlugin::kSecurityLevelHwSecureCrypto:
529 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
530 break;
531 case DrmPlugin::kSecurityLevelHwSecureDecode:
532 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
533 break;
534 case DrmPlugin::kSecurityLevelHwSecureAll:
535 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
536 break;
537 case DrmPlugin::kSecurityLevelMax:
538 setSecurityLevel = false;
539 break;
540 default:
541 return ERROR_DRM_CANNOT_HANDLE;
542 }
543
544 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800545 bool retry = true;
546 do {
547 hidl_vec<uint8_t> hSessionId;
548
Jeff Tinker56134cc2018-02-05 13:09:23 -0800549 Return<void> hResult;
550 if (mPluginV1_1 == NULL || !setSecurityLevel) {
551 hResult = mPlugin->openSession(
552 [&](Status status,const hidl_vec<uint8_t>& id) {
553 if (status == Status::OK) {
554 sessionId = toVector(id);
555 }
556 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800557 }
Jeff Tinker56134cc2018-02-05 13:09:23 -0800558 );
559 } else {
560 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
561 [&](Status status, const hidl_vec<uint8_t>& id) {
562 if (status == Status::OK) {
563 sessionId = toVector(id);
564 }
565 err = toStatusT(status);
566 }
567 );
568 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800569
570 if (!hResult.isOk()) {
571 err = DEAD_OBJECT;
572 }
573
574 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
575 mLock.unlock();
576 // reclaimSession may call back to closeSession, since mLock is
577 // shared between Drm instances, we should unlock here to avoid
578 // deadlock.
579 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
580 mLock.lock();
581 } else {
582 retry = false;
583 }
584 } while (retry);
585
586 if (err == OK) {
587 DrmSessionManager::Instance()->addSession(getCallingPid(),
588 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700589 mOpenSessions.push(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800590 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800591
Adam Stonef0e618d2018-01-17 19:20:41 -0800592 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800593 return err;
594}
595
596status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
597 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800598 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800599
Jeff Tinker319d5f42017-07-26 15:44:33 -0700600 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
601 if (status.isOk()) {
602 if (status == Status::OK) {
603 DrmSessionManager::Instance()->removeSession(sessionId);
604 for (size_t i = 0; i < mOpenSessions.size(); i++) {
605 if (mOpenSessions[i] == sessionId) {
606 mOpenSessions.removeAt(i);
607 break;
608 }
Jeff Tinker61332812017-05-15 16:53:10 -0700609 }
610 }
Jeff Tinker319d5f42017-07-26 15:44:33 -0700611 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800612 status_t response = toStatusT(status);
613 mMetrics.mCloseSessionCounter.Increment(response);
614 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800615 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800616 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700617 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800618}
619
620status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
621 Vector<uint8_t> const &initData, String8 const &mimeType,
622 DrmPlugin::KeyType keyType, KeyedVector<String8,
623 String8> const &optionalParameters, Vector<uint8_t> &request,
624 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
625 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800626 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800627 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800628
629 DrmSessionManager::Instance()->useSession(sessionId);
630
631 KeyType hKeyType;
632 if (keyType == DrmPlugin::kKeyType_Streaming) {
633 hKeyType = KeyType::STREAMING;
634 } else if (keyType == DrmPlugin::kKeyType_Offline) {
635 hKeyType = KeyType::OFFLINE;
636 } else if (keyType == DrmPlugin::kKeyType_Release) {
637 hKeyType = KeyType::RELEASE;
638 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800639 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800640 return BAD_VALUE;
641 }
642
643 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
644
645 status_t err = UNKNOWN_ERROR;
646
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800647 if (mPluginV1_1 != NULL) {
648 Return<void> hResult =
649 mPluginV1_1->getKeyRequest_1_1(
650 toHidlVec(sessionId), toHidlVec(initData),
651 toHidlString(mimeType), hKeyType, hOptionalParameters,
652 [&](Status status, const hidl_vec<uint8_t>& hRequest,
653 drm::V1_1::KeyRequestType hKeyRequestType,
654 const hidl_string& hDefaultUrl) {
655
656 if (status == Status::OK) {
657 request = toVector(hRequest);
658 defaultUrl = toString8(hDefaultUrl);
659
660 switch (hKeyRequestType) {
661 case drm::V1_1::KeyRequestType::INITIAL:
662 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
663 break;
664 case drm::V1_1::KeyRequestType::RENEWAL:
665 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
666 break;
667 case drm::V1_1::KeyRequestType::RELEASE:
668 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
669 break;
670 case drm::V1_1::KeyRequestType::NONE:
671 *keyRequestType = DrmPlugin::kKeyRequestType_None;
672 break;
673 case drm::V1_1::KeyRequestType::UPDATE:
674 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
675 break;
676 default:
677 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
678 break;
679 }
680 err = toStatusT(status);
681 }
682 });
683 return hResult.isOk() ? err : DEAD_OBJECT;
684 }
685
Jeff Tinkera53d6552017-01-20 00:31:46 -0800686 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
687 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
688 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800689 drm::V1_0::KeyRequestType hKeyRequestType,
690 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800691
692 if (status == Status::OK) {
693 request = toVector(hRequest);
694 defaultUrl = toString8(hDefaultUrl);
695
696 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800697 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800698 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
699 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800700 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800701 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
702 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800703 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800704 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
705 break;
706 default:
707 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
708 break;
709 }
710 err = toStatusT(status);
711 }
712 });
713
Adam Stonef0e618d2018-01-17 19:20:41 -0800714 err = hResult.isOk() ? err : DEAD_OBJECT;
715 keyRequestTimer.SetAttribute(err);
716 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800717}
718
719status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
720 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
721 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800722 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
723
Jeff Tinker6d998b62017-12-18 14:37:43 -0800724 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800725
726 DrmSessionManager::Instance()->useSession(sessionId);
727
728 status_t err = UNKNOWN_ERROR;
729
730 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
731 toHidlVec(response),
732 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
733 if (status == Status::OK) {
734 keySetId = toVector(hKeySetId);
735 }
736 err = toStatusT(status);
737 }
738 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800739 err = hResult.isOk() ? err : DEAD_OBJECT;
740 keyResponseTimer.SetAttribute(err);
741 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800742}
743
744status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
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->removeKeys(toHidlVec(keySetId)));
749}
750
751status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
752 Vector<uint8_t> const &keySetId) {
753 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800754 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800755
756 DrmSessionManager::Instance()->useSession(sessionId);
757
758 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
759 toHidlVec(keySetId)));
760}
761
762status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
763 KeyedVector<String8, String8> &infoMap) const {
764 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800765 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800766
767 DrmSessionManager::Instance()->useSession(sessionId);
768
769 ::KeyedVector hInfoMap;
770
771 status_t err = UNKNOWN_ERROR;
772
773 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
774 [&](Status status, const hidl_vec<KeyValue>& map) {
775 if (status == Status::OK) {
776 infoMap = toKeyedVector(map);
777 }
778 err = toStatusT(status);
779 }
780 );
781
782 return hResult.isOk() ? err : DEAD_OBJECT;
783}
784
785status_t DrmHal::getProvisionRequest(String8 const &certType,
786 String8 const &certAuthority, Vector<uint8_t> &request,
787 String8 &defaultUrl) {
788 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800789 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800790
791 status_t err = UNKNOWN_ERROR;
792
793 Return<void> hResult = mPlugin->getProvisionRequest(
794 toHidlString(certType), toHidlString(certAuthority),
795 [&](Status status, const hidl_vec<uint8_t>& hRequest,
796 const hidl_string& hDefaultUrl) {
797 if (status == Status::OK) {
798 request = toVector(hRequest);
799 defaultUrl = toString8(hDefaultUrl);
800 }
801 err = toStatusT(status);
802 }
803 );
804
Adam Stonecea91ce2018-01-22 19:23:28 -0800805 err = hResult.isOk() ? err : DEAD_OBJECT;
806 mMetrics.mGetProvisionRequestCounter.Increment(err);
807 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800808}
809
810status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800811 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800812 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800813 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800814
815 status_t err = UNKNOWN_ERROR;
816
817 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
818 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
819 const hidl_vec<uint8_t>& hWrappedKey) {
820 if (status == Status::OK) {
821 certificate = toVector(hCertificate);
822 wrappedKey = toVector(hWrappedKey);
823 }
824 err = toStatusT(status);
825 }
826 );
827
Adam Stonecea91ce2018-01-22 19:23:28 -0800828 err = hResult.isOk() ? err : DEAD_OBJECT;
829 mMetrics.mProvideProvisionResponseCounter.Increment(err);
830 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800831}
832
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800833status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800834 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800835 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800836
837 status_t err = UNKNOWN_ERROR;
838
839 Return<void> hResult = mPlugin->getSecureStops(
840 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
841 if (status == Status::OK) {
842 secureStops = toSecureStops(hSecureStops);
843 }
844 err = toStatusT(status);
845 }
846 );
847
848 return hResult.isOk() ? err : DEAD_OBJECT;
849}
850
851
Jeff Tinker15177d72018-01-25 12:57:55 -0800852status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
853 Mutex::Autolock autoLock(mLock);
854
855 if (mInitCheck != OK) {
856 return mInitCheck;
857 }
858
859 if (mPluginV1_1 == NULL) {
860 return ERROR_DRM_CANNOT_HANDLE;
861 }
862
863 status_t err = UNKNOWN_ERROR;
864
865 Return<void> hResult = mPluginV1_1->getSecureStopIds(
866 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
867 if (status == Status::OK) {
868 secureStopIds = toSecureStopIds(hSecureStopIds);
869 }
870 err = toStatusT(status);
871 }
872 );
873
874 return hResult.isOk() ? err : DEAD_OBJECT;
875}
876
877
Jeff Tinkera53d6552017-01-20 00:31:46 -0800878status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
879 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800880 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800881
882 status_t err = UNKNOWN_ERROR;
883
884 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
885 [&](Status status, const SecureStop& hSecureStop) {
886 if (status == Status::OK) {
887 secureStop = toVector(hSecureStop.opaqueData);
888 }
889 err = toStatusT(status);
890 }
891 );
892
893 return hResult.isOk() ? err : DEAD_OBJECT;
894}
895
896status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
897 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800898 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899
Jeff Tinker15177d72018-01-25 12:57:55 -0800900 if (mPluginV1_1 != NULL) {
901 SecureStopRelease secureStopRelease;
902 secureStopRelease.opaqueData = toHidlVec(ssRelease);
903 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
904 }
905
Jeff Tinkera53d6552017-01-20 00:31:46 -0800906 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
907}
908
Jeff Tinker15177d72018-01-25 12:57:55 -0800909status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
910 Mutex::Autolock autoLock(mLock);
911
912 if (mInitCheck != OK) {
913 return mInitCheck;
914 }
915
916 if (mPluginV1_1 == NULL) {
917 return ERROR_DRM_CANNOT_HANDLE;
918 }
919
920 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
921}
922
923status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800924 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800925 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800926
Jeff Tinker15177d72018-01-25 12:57:55 -0800927 if (mPluginV1_1 != NULL) {
928 return toStatusT(mPluginV1_1->removeAllSecureStops());
929 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800930 return toStatusT(mPlugin->releaseAllSecureStops());
931}
932
Jeff Tinker6d998b62017-12-18 14:37:43 -0800933status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
934 DrmPlugin::HdcpLevel *max) const {
935 Mutex::Autolock autoLock(mLock);
936 INIT_CHECK();
937
938 if (connected == NULL || max == NULL) {
939 return BAD_VALUE;
940 }
941 status_t err = UNKNOWN_ERROR;
942
943 if (mPluginV1_1 == NULL) {
944 return ERROR_DRM_CANNOT_HANDLE;
945 }
946
947 *connected = DrmPlugin::kHdcpLevelUnknown;
948 *max = DrmPlugin::kHdcpLevelUnknown;
949
950 Return<void> hResult = mPluginV1_1->getHdcpLevels(
951 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
952 if (status == Status::OK) {
953 *connected = toHdcpLevel(hConnected);
954 *max = toHdcpLevel(hMax);
955 }
956 err = toStatusT(status);
957 }
958 );
959
960 return hResult.isOk() ? err : DEAD_OBJECT;
961}
962
963status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
964 Mutex::Autolock autoLock(mLock);
965 INIT_CHECK();
966
967 if (open == NULL || max == NULL) {
968 return BAD_VALUE;
969 }
970 status_t err = UNKNOWN_ERROR;
971
972 *open = 0;
973 *max = 0;
974
975 if (mPluginV1_1 == NULL) {
976 return ERROR_DRM_CANNOT_HANDLE;
977 }
978
979 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
980 [&](Status status, uint32_t hOpen, uint32_t hMax) {
981 if (status == Status::OK) {
982 *open = hOpen;
983 *max = hMax;
984 }
985 err = toStatusT(status);
986 }
987 );
988
989 return hResult.isOk() ? err : DEAD_OBJECT;
990}
991
992status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
993 DrmPlugin::SecurityLevel *level) const {
994 Mutex::Autolock autoLock(mLock);
995 INIT_CHECK();
996
997 if (level == NULL) {
998 return BAD_VALUE;
999 }
1000 status_t err = UNKNOWN_ERROR;
1001
1002 if (mPluginV1_1 == NULL) {
1003 return ERROR_DRM_CANNOT_HANDLE;
1004 }
1005
1006 *level = DrmPlugin::kSecurityLevelUnknown;
1007
1008 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1009 [&](Status status, SecurityLevel hLevel) {
1010 if (status == Status::OK) {
1011 *level = toSecurityLevel(hLevel);
1012 }
1013 err = toStatusT(status);
1014 }
1015 );
1016
1017 return hResult.isOk() ? err : DEAD_OBJECT;
1018}
1019
Jeff Tinkera53d6552017-01-20 00:31:46 -08001020status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1021 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001022 return getPropertyStringInternal(name, value);
1023}
1024
1025status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1026 // This function is internal to the class and should only be called while
1027 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001028 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001029
1030 status_t err = UNKNOWN_ERROR;
1031
1032 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1033 [&](Status status, const hidl_string& hValue) {
1034 if (status == Status::OK) {
1035 value = toString8(hValue);
1036 }
1037 err = toStatusT(status);
1038 }
1039 );
1040
1041 return hResult.isOk() ? err : DEAD_OBJECT;
1042}
1043
1044status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1045 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001046 return getPropertyByteArrayInternal(name, value);
1047}
1048
1049status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1050 // This function is internal to the class and should only be called while
1051 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001052 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001053
1054 status_t err = UNKNOWN_ERROR;
1055
1056 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1057 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1058 if (status == Status::OK) {
1059 value = toVector(hValue);
1060 }
1061 err = toStatusT(status);
1062 }
1063 );
1064
Adam Stonecea91ce2018-01-22 19:23:28 -08001065 err = hResult.isOk() ? err : DEAD_OBJECT;
1066 if (name == kPropertyDeviceUniqueId) {
1067 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1068 }
1069 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001070}
1071
1072status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1073 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001074 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001075
Jeff Tinker6d998b62017-12-18 14:37:43 -08001076 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001077 toHidlString(value));
1078 return toStatusT(status);
1079}
1080
1081status_t DrmHal::setPropertyByteArray(String8 const &name,
1082 Vector<uint8_t> const &value ) const {
1083 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001084 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001085
1086 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1087 toHidlVec(value));
1088 return toStatusT(status);
1089}
1090
Adam Stonef0e618d2018-01-17 19:20:41 -08001091status_t DrmHal::getMetrics(MediaAnalyticsItem* item) {
1092 if (item == nullptr) {
1093 return UNEXPECTED_NULL;
1094 }
1095
1096 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001097 return OK;
1098}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001099
1100status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1101 String8 const &algorithm) {
1102 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001103 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001104
1105 DrmSessionManager::Instance()->useSession(sessionId);
1106
1107 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1108 toHidlString(algorithm));
1109 return toStatusT(status);
1110}
1111
1112status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1113 String8 const &algorithm) {
1114 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001115 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001116
1117 DrmSessionManager::Instance()->useSession(sessionId);
1118
1119 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1120 toHidlString(algorithm));
1121 return toStatusT(status);
1122}
1123
1124status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001125 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1126 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001127 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001128 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001129
1130 DrmSessionManager::Instance()->useSession(sessionId);
1131
1132 status_t err = UNKNOWN_ERROR;
1133
1134 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1135 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1136 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1137 if (status == Status::OK) {
1138 output = toVector(hOutput);
1139 }
1140 err = toStatusT(status);
1141 }
1142 );
1143
1144 return hResult.isOk() ? err : DEAD_OBJECT;
1145}
1146
1147status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001148 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1149 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001150 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001151 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001152
1153 DrmSessionManager::Instance()->useSession(sessionId);
1154
1155 status_t err = UNKNOWN_ERROR;
1156
1157 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1158 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1159 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1160 if (status == Status::OK) {
1161 output = toVector(hOutput);
1162 }
1163 err = toStatusT(status);
1164 }
1165 );
1166
1167 return hResult.isOk() ? err : DEAD_OBJECT;
1168}
1169
1170status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001171 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1172 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001173 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001174 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001175
1176 DrmSessionManager::Instance()->useSession(sessionId);
1177
1178 status_t err = UNKNOWN_ERROR;
1179
1180 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1181 toHidlVec(keyId), toHidlVec(message),
1182 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1183 if (status == Status::OK) {
1184 signature = toVector(hSignature);
1185 }
1186 err = toStatusT(status);
1187 }
1188 );
1189
1190 return hResult.isOk() ? err : DEAD_OBJECT;
1191}
1192
1193status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001194 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1195 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001196 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001197 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001198
1199 DrmSessionManager::Instance()->useSession(sessionId);
1200
1201 status_t err = UNKNOWN_ERROR;
1202
1203 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1204 toHidlVec(message), toHidlVec(signature),
1205 [&](Status status, bool hMatch) {
1206 if (status == Status::OK) {
1207 match = hMatch;
1208 } else {
1209 match = false;
1210 }
1211 err = toStatusT(status);
1212 }
1213 );
1214
1215 return hResult.isOk() ? err : DEAD_OBJECT;
1216}
1217
1218status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001219 String8 const &algorithm, Vector<uint8_t> const &message,
1220 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001221 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001222 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001223
1224 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1225 return -EPERM;
1226 }
1227
1228 DrmSessionManager::Instance()->useSession(sessionId);
1229
1230 status_t err = UNKNOWN_ERROR;
1231
1232 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1233 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1234 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1235 if (status == Status::OK) {
1236 signature = toVector(hSignature);
1237 }
1238 err = toStatusT(status);
1239 }
1240 );
1241
1242 return hResult.isOk() ? err : DEAD_OBJECT;
1243}
1244
1245void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1246{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001247 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001248 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001249 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001250 mInitCheck = NO_INIT;
1251
Jeff Tinker70367f52017-06-16 12:41:33 -07001252 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001253 if (!mPlugin->setListener(NULL).isOk()) {
1254 mInitCheck = DEAD_OBJECT;
1255 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001256 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001257 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001258}
1259
1260void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1261{
1262 if (vec.size()) {
1263 obj.writeInt32(vec.size());
1264 obj.write(vec.data(), vec.size());
1265 } else {
1266 obj.writeInt32(0);
1267 }
1268}
1269
Adam Stoneab394d12017-12-22 12:34:20 -08001270
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001271void DrmHal::reportMetrics() const
1272{
1273 Vector<uint8_t> metrics;
1274 String8 vendor;
1275 String8 description;
1276 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1277 getPropertyStringInternal(String8("description"), description) == OK &&
1278 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1279 status_t res = android::reportDrmPluginMetrics(
1280 metrics, vendor, description);
1281 if (res != OK) {
1282 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1283 }
1284 }
1285}
1286
Jeff Tinkera53d6552017-01-20 00:31:46 -08001287} // namespace android