blob: 6b782f034a10646a237d27b9af126b7319e98f82 [file] [log] [blame]
Jeff Tinkera53d6552017-01-20 00:31:46 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmHal"
19#include <utils/Log.h>
20
21#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080023
Jeff Tinkera53d6552017-01-20 00:31:46 -080024#include <android/hardware/drm/1.0/types.h>
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080025#include <android/hidl/manager/1.0/IServiceManager.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070026#include <hidl/ServiceManagement.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080027
28#include <media/DrmHal.h>
29#include <media/DrmSessionClientInterface.h>
30#include <media/DrmSessionManager.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080031#include <media/EventMetric.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070032#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080033#include <media/drm/DrmAPI.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AString.h>
36#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/MediaErrors.h>
38
Jeff Tinker6d998b62017-12-18 14:37:43 -080039using drm::V1_0::KeyedVector;
Jeff Tinker6d998b62017-12-18 14:37:43 -080040using drm::V1_0::KeyStatusType;
41using drm::V1_0::KeyType;
42using drm::V1_0::KeyValue;
43using drm::V1_1::HdcpLevel;;
44using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080045using drm::V1_1::SecureStopRelease;
46using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_1::SecurityLevel;
48using drm::V1_0::Status;
Jeff Tinkera53d6552017-01-20 00:31:46 -080049using ::android::hardware::hidl_array;
50using ::android::hardware::hidl_string;
51using ::android::hardware::hidl_vec;
52using ::android::hardware::Return;
53using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080054using ::android::hidl::manager::V1_0::IServiceManager;
Adam Stone637b7852018-01-30 12:09:36 -080055using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080056using ::android::sp;
57
Adam Stonecea91ce2018-01-22 19:23:28 -080058namespace {
59
60// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
61// in the MediaDrm API.
62constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
63
64}
65
Jeff Tinkera53d6552017-01-20 00:31:46 -080066namespace android {
67
Jeff Tinker6d998b62017-12-18 14:37:43 -080068#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
69
Jeff Tinkera53d6552017-01-20 00:31:46 -080070static inline int getCallingPid() {
71 return IPCThreadState::self()->getCallingPid();
72}
73
74static bool checkPermission(const char* permissionString) {
75 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
76 bool ok = checkCallingPermission(String16(permissionString));
77 if (!ok) ALOGE("Request requires %s", permissionString);
78 return ok;
79}
80
81static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
82 Vector<uint8_t> vector;
83 vector.appendArray(vec.data(), vec.size());
84 return *const_cast<const Vector<uint8_t> *>(&vector);
85}
86
87static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
88 hidl_vec<uint8_t> vec;
89 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
90 return vec;
91}
92
93static String8 toString8(const hidl_string &string) {
94 return String8(string.c_str());
95}
96
97static hidl_string toHidlString(const String8& string) {
98 return hidl_string(string.string());
99}
100
Jeff Tinker6d998b62017-12-18 14:37:43 -0800101static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
102 switch(level) {
103 case SecurityLevel::SW_SECURE_CRYPTO:
104 return DrmPlugin::kSecurityLevelSwSecureCrypto;
105 case SecurityLevel::SW_SECURE_DECODE:
106 return DrmPlugin::kSecurityLevelSwSecureDecode;
107 case SecurityLevel::HW_SECURE_CRYPTO:
108 return DrmPlugin::kSecurityLevelHwSecureCrypto;
109 case SecurityLevel::HW_SECURE_DECODE:
110 return DrmPlugin::kSecurityLevelHwSecureDecode;
111 case SecurityLevel::HW_SECURE_ALL:
112 return DrmPlugin::kSecurityLevelHwSecureAll;
113 default:
114 return DrmPlugin::kSecurityLevelUnknown;
115 }
116}
117
118static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
119 switch(level) {
120 case HdcpLevel::HDCP_NONE:
121 return DrmPlugin::kHdcpNone;
122 case HdcpLevel::HDCP_V1:
123 return DrmPlugin::kHdcpV1;
124 case HdcpLevel::HDCP_V2:
125 return DrmPlugin::kHdcpV2;
126 case HdcpLevel::HDCP_V2_1:
127 return DrmPlugin::kHdcpV2_1;
128 case HdcpLevel::HDCP_V2_2:
129 return DrmPlugin::kHdcpV2_2;
130 case HdcpLevel::HDCP_NO_OUTPUT:
131 return DrmPlugin::kHdcpNoOutput;
132 default:
133 return DrmPlugin::kHdcpLevelUnknown;
134 }
135}
136
Jeff Tinkera53d6552017-01-20 00:31:46 -0800137
138static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
139 keyedVector) {
140 std::vector<KeyValue> stdKeyedVector;
141 for (size_t i = 0; i < keyedVector.size(); i++) {
142 KeyValue keyValue;
143 keyValue.key = toHidlString(keyedVector.keyAt(i));
144 keyValue.value = toHidlString(keyedVector.valueAt(i));
145 stdKeyedVector.push_back(keyValue);
146 }
147 return ::KeyedVector(stdKeyedVector);
148}
149
150static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
151 hKeyedVector) {
152 KeyedVector<String8, String8> keyedVector;
153 for (size_t i = 0; i < hKeyedVector.size(); i++) {
154 keyedVector.add(toString8(hKeyedVector[i].key),
155 toString8(hKeyedVector[i].value));
156 }
157 return keyedVector;
158}
159
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800160static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800161 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800162 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800163 for (size_t i = 0; i < hSecureStops.size(); i++) {
164 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
165 }
166 return secureStops;
167}
168
Jeff Tinker15177d72018-01-25 12:57:55 -0800169static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
170 hSecureStopIds) {
171 List<Vector<uint8_t>> secureStopIds;
172 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
173 secureStopIds.push_back(toVector(hSecureStopIds[i]));
174 }
175 return secureStopIds;
176}
177
Jeff Tinkera53d6552017-01-20 00:31:46 -0800178static status_t toStatusT(Status status) {
179 switch (status) {
180 case Status::OK:
181 return OK;
182 break;
183 case Status::ERROR_DRM_NO_LICENSE:
184 return ERROR_DRM_NO_LICENSE;
185 break;
186 case Status::ERROR_DRM_LICENSE_EXPIRED:
187 return ERROR_DRM_LICENSE_EXPIRED;
188 break;
189 case Status::ERROR_DRM_SESSION_NOT_OPENED:
190 return ERROR_DRM_SESSION_NOT_OPENED;
191 break;
192 case Status::ERROR_DRM_CANNOT_HANDLE:
193 return ERROR_DRM_CANNOT_HANDLE;
194 break;
195 case Status::ERROR_DRM_INVALID_STATE:
196 return ERROR_DRM_TAMPER_DETECTED;
197 break;
198 case Status::BAD_VALUE:
199 return BAD_VALUE;
200 break;
201 case Status::ERROR_DRM_NOT_PROVISIONED:
202 return ERROR_DRM_NOT_PROVISIONED;
203 break;
204 case Status::ERROR_DRM_RESOURCE_BUSY:
205 return ERROR_DRM_RESOURCE_BUSY;
206 break;
207 case Status::ERROR_DRM_DEVICE_REVOKED:
208 return ERROR_DRM_DEVICE_REVOKED;
209 break;
210 case Status::ERROR_DRM_UNKNOWN:
211 default:
212 return ERROR_DRM_UNKNOWN;
213 break;
214 }
215}
216
217
218Mutex DrmHal::mLock;
219
220struct DrmSessionClient : public DrmSessionClientInterface {
221 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
222
223 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
224 sp<DrmHal> drm = mDrm.promote();
225 if (drm == NULL) {
226 return true;
227 }
228 status_t err = drm->closeSession(sessionId);
229 if (err != OK) {
230 return false;
231 }
232 drm->sendEvent(EventType::SESSION_RECLAIMED,
233 toHidlVec(sessionId), hidl_vec<uint8_t>());
234 return true;
235 }
236
237protected:
238 virtual ~DrmSessionClient() {}
239
240private:
241 wp<DrmHal> mDrm;
242
243 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
244};
245
246DrmHal::DrmHal()
247 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800248 mFactories(makeDrmFactories()),
249 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800250}
251
Jeff Tinker61332812017-05-15 16:53:10 -0700252void DrmHal::closeOpenSessions() {
253 if (mPlugin != NULL) {
Jeff Tinkerb2b66fa2018-01-30 19:19:34 +0000254 for (size_t i = 0; i < mOpenSessions.size(); i++) {
255 mPlugin->closeSession(toHidlVec(mOpenSessions[i]));
256 DrmSessionManager::Instance()->removeSession(mOpenSessions[i]);
Jeff Tinker61332812017-05-15 16:53:10 -0700257 }
258 }
259 mOpenSessions.clear();
260}
261
Jeff Tinkera53d6552017-01-20 00:31:46 -0800262DrmHal::~DrmHal() {
Jeff Tinker61332812017-05-15 16:53:10 -0700263 closeOpenSessions();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800264 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
265}
266
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800267Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
268 Vector<sp<IDrmFactory>> factories;
269
Jeff Tinker593111f2017-05-25 16:00:21 -0700270 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800271
272 if (manager != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000273 manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800274 [&factories](const hidl_vec<hidl_string> &registered) {
275 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000276 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800277 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000278 ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800279 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000280 }
281 }
282 }
283 );
284 manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
285 [&factories](const hidl_vec<hidl_string> &registered) {
286 for (const auto &instance : registered) {
287 auto factory = drm::V1_1::IDrmFactory::getService(instance);
288 if (factory != NULL) {
289 ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
290 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800291 }
292 }
293 }
294 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800295 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800296
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800297 if (factories.size() == 0) {
298 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700299 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800300 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000301 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800302 factories.push_back(passthrough);
303 } else {
304 ALOGE("Failed to find any drm factories");
305 }
306 }
307 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800308}
309
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800310sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
311 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800312
313 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800314 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800315 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800316 if (status != Status::OK) {
317 ALOGE("Failed to make drm plugin");
318 return;
319 }
320 plugin = hPlugin;
321 }
322 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700323
324 if (!hResult.isOk()) {
325 ALOGE("createPlugin remote call failed");
326 }
327
Jeff Tinkera53d6552017-01-20 00:31:46 -0800328 return plugin;
329}
330
331status_t DrmHal::initCheck() const {
332 return mInitCheck;
333}
334
335status_t DrmHal::setListener(const sp<IDrmClient>& listener)
336{
337 Mutex::Autolock lock(mEventLock);
338 if (mListener != NULL){
339 IInterface::asBinder(mListener)->unlinkToDeath(this);
340 }
341 if (listener != NULL) {
342 IInterface::asBinder(listener)->linkToDeath(this);
343 }
344 mListener = listener;
345 return NO_ERROR;
346}
347
348Return<void> DrmHal::sendEvent(EventType hEventType,
349 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800350 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800351
352 mEventLock.lock();
353 sp<IDrmClient> listener = mListener;
354 mEventLock.unlock();
355
356 if (listener != NULL) {
357 Parcel obj;
358 writeByteArray(obj, sessionId);
359 writeByteArray(obj, data);
360
361 Mutex::Autolock lock(mNotifyLock);
362 DrmPlugin::EventType eventType;
363 switch(hEventType) {
364 case EventType::PROVISION_REQUIRED:
365 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
366 break;
367 case EventType::KEY_NEEDED:
368 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
369 break;
370 case EventType::KEY_EXPIRED:
371 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
372 break;
373 case EventType::VENDOR_DEFINED:
374 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
375 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700376 case EventType::SESSION_RECLAIMED:
377 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
378 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800379 default:
380 return Void();
381 }
382 listener->notify(eventType, 0, &obj);
383 }
384 return Void();
385}
386
387Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
388 int64_t expiryTimeInMS) {
389
390 mEventLock.lock();
391 sp<IDrmClient> listener = mListener;
392 mEventLock.unlock();
393
394 if (listener != NULL) {
395 Parcel obj;
396 writeByteArray(obj, sessionId);
397 obj.writeInt64(expiryTimeInMS);
398
399 Mutex::Autolock lock(mNotifyLock);
400 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
401 }
402 return Void();
403}
404
405Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
406 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
407
408 mEventLock.lock();
409 sp<IDrmClient> listener = mListener;
410 mEventLock.unlock();
411
412 if (listener != NULL) {
413 Parcel obj;
414 writeByteArray(obj, sessionId);
415
416 size_t nKeys = keyStatusList.size();
417 obj.writeInt32(nKeys);
418 for (size_t i = 0; i < nKeys; ++i) {
419 const KeyStatus &keyStatus = keyStatusList[i];
420 writeByteArray(obj, keyStatus.keyId);
421 uint32_t type;
422 switch(keyStatus.type) {
423 case KeyStatusType::USABLE:
424 type = DrmPlugin::kKeyStatusType_Usable;
425 break;
426 case KeyStatusType::EXPIRED:
427 type = DrmPlugin::kKeyStatusType_Expired;
428 break;
429 case KeyStatusType::OUTPUTNOTALLOWED:
430 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
431 break;
432 case KeyStatusType::STATUSPENDING:
433 type = DrmPlugin::kKeyStatusType_StatusPending;
434 break;
435 case KeyStatusType::INTERNALERROR:
436 default:
437 type = DrmPlugin::kKeyStatusType_InternalError;
438 break;
439 }
440 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800441 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800442 }
443 obj.writeInt32(hasNewUsableKey);
444
445 Mutex::Autolock lock(mNotifyLock);
446 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800447 } else {
448 // There's no listener. But we still want to count the key change
449 // events.
450 size_t nKeys = keyStatusList.size();
451 for (size_t i = 0; i < nKeys; i++) {
452 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
453 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800454 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800455
Jeff Tinkera53d6552017-01-20 00:31:46 -0800456 return Void();
457}
458
459bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
460 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800461
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800462 for (size_t i = 0; i < mFactories.size(); i++) {
463 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
464 if (mimeType != "") {
465 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
466 return true;
467 }
468 } else {
469 return true;
470 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800471 }
472 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800473 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800474}
475
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800476status_t DrmHal::createPlugin(const uint8_t uuid[16],
477 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800478 Mutex::Autolock autoLock(mLock);
479
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800480 for (size_t i = 0; i < mFactories.size(); i++) {
481 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
482 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Edwin Wong5641aa22018-01-30 17:52:21 -0800483 if (mPlugin != NULL) {
484 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
485 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800486 }
487 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800488
489 if (mPlugin == NULL) {
490 mInitCheck = ERROR_UNSUPPORTED;
491 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700492 if (!mPlugin->setListener(this).isOk()) {
493 mInitCheck = DEAD_OBJECT;
494 } else {
495 mInitCheck = OK;
496 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800497 }
498
499 return mInitCheck;
500}
501
502status_t DrmHal::destroyPlugin() {
503 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800504 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800505
Jeff Tinker61332812017-05-15 16:53:10 -0700506 closeOpenSessions();
John W. Bruce33ecc4f2017-04-03 16:49:05 -0700507 reportMetrics();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800508 setListener(NULL);
Jeff Tinker70367f52017-06-16 12:41:33 -0700509 mInitCheck = NO_INIT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800510
Jeff Tinker319d5f42017-07-26 15:44:33 -0700511 if (mPlugin != NULL) {
512 if (!mPlugin->setListener(NULL).isOk()) {
513 mInitCheck = DEAD_OBJECT;
514 }
515 }
516 mPlugin.clear();
Edwin Wong5641aa22018-01-30 17:52:21 -0800517 mPluginV1_1.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800518 return OK;
519}
520
Jeff Tinker41d279a2018-02-11 19:52:08 +0000521status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
522 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800523 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800524 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800525
Jeff Tinker41d279a2018-02-11 19:52:08 +0000526 SecurityLevel hSecurityLevel;
527 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000528
Jeff Tinker41d279a2018-02-11 19:52:08 +0000529 switch(level) {
530 case DrmPlugin::kSecurityLevelSwSecureCrypto:
531 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
532 break;
533 case DrmPlugin::kSecurityLevelSwSecureDecode:
534 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
535 break;
536 case DrmPlugin::kSecurityLevelHwSecureCrypto:
537 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
538 break;
539 case DrmPlugin::kSecurityLevelHwSecureDecode:
540 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
541 break;
542 case DrmPlugin::kSecurityLevelHwSecureAll:
543 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
544 break;
545 case DrmPlugin::kSecurityLevelMax:
546 setSecurityLevel = false;
547 break;
548 default:
549 return ERROR_DRM_CANNOT_HANDLE;
550 }
551
552 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800553 bool retry = true;
554 do {
555 hidl_vec<uint8_t> hSessionId;
556
Jeff Tinker41d279a2018-02-11 19:52:08 +0000557 Return<void> hResult;
558 if (mPluginV1_1 == NULL || !setSecurityLevel) {
559 hResult = mPlugin->openSession(
560 [&](Status status,const hidl_vec<uint8_t>& id) {
561 if (status == Status::OK) {
562 sessionId = toVector(id);
563 }
564 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800565 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000566 );
567 } else {
568 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
569 [&](Status status, const hidl_vec<uint8_t>& id) {
570 if (status == Status::OK) {
571 sessionId = toVector(id);
572 }
573 err = toStatusT(status);
574 }
575 );
576 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800577
578 if (!hResult.isOk()) {
579 err = DEAD_OBJECT;
580 }
581
582 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
583 mLock.unlock();
584 // reclaimSession may call back to closeSession, since mLock is
585 // shared between Drm instances, we should unlock here to avoid
586 // deadlock.
587 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
588 mLock.lock();
589 } else {
590 retry = false;
591 }
592 } while (retry);
593
594 if (err == OK) {
595 DrmSessionManager::Instance()->addSession(getCallingPid(),
596 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700597 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800598 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800599 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800600
Adam Stonef0e618d2018-01-17 19:20:41 -0800601 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800602 return err;
603}
604
605status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
606 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800607 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800608
Jeff Tinker319d5f42017-07-26 15:44:33 -0700609 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
610 if (status.isOk()) {
611 if (status == Status::OK) {
612 DrmSessionManager::Instance()->removeSession(sessionId);
613 for (size_t i = 0; i < mOpenSessions.size(); i++) {
614 if (mOpenSessions[i] == sessionId) {
615 mOpenSessions.removeAt(i);
616 break;
617 }
Jeff Tinker61332812017-05-15 16:53:10 -0700618 }
619 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800620 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800621 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800622 mMetrics.mCloseSessionCounter.Increment(response);
Adam Stone568b3c42018-01-31 12:57:16 -0800623 reportMetrics();
Adam Stonecea91ce2018-01-22 19:23:28 -0800624 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800625 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800626 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700627 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800628}
629
630status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
631 Vector<uint8_t> const &initData, String8 const &mimeType,
632 DrmPlugin::KeyType keyType, KeyedVector<String8,
633 String8> const &optionalParameters, Vector<uint8_t> &request,
634 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
635 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800636 INIT_CHECK();
Adam Stonef0e618d2018-01-17 19:20:41 -0800637 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTiming);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800638
639 DrmSessionManager::Instance()->useSession(sessionId);
640
641 KeyType hKeyType;
642 if (keyType == DrmPlugin::kKeyType_Streaming) {
643 hKeyType = KeyType::STREAMING;
644 } else if (keyType == DrmPlugin::kKeyType_Offline) {
645 hKeyType = KeyType::OFFLINE;
646 } else if (keyType == DrmPlugin::kKeyType_Release) {
647 hKeyType = KeyType::RELEASE;
648 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800649 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800650 return BAD_VALUE;
651 }
652
653 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
654
655 status_t err = UNKNOWN_ERROR;
656
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800657 if (mPluginV1_1 != NULL) {
658 Return<void> hResult =
659 mPluginV1_1->getKeyRequest_1_1(
660 toHidlVec(sessionId), toHidlVec(initData),
661 toHidlString(mimeType), hKeyType, hOptionalParameters,
662 [&](Status status, const hidl_vec<uint8_t>& hRequest,
663 drm::V1_1::KeyRequestType hKeyRequestType,
664 const hidl_string& hDefaultUrl) {
665
666 if (status == Status::OK) {
667 request = toVector(hRequest);
668 defaultUrl = toString8(hDefaultUrl);
669
670 switch (hKeyRequestType) {
671 case drm::V1_1::KeyRequestType::INITIAL:
672 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
673 break;
674 case drm::V1_1::KeyRequestType::RENEWAL:
675 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
676 break;
677 case drm::V1_1::KeyRequestType::RELEASE:
678 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
679 break;
680 case drm::V1_1::KeyRequestType::NONE:
681 *keyRequestType = DrmPlugin::kKeyRequestType_None;
682 break;
683 case drm::V1_1::KeyRequestType::UPDATE:
684 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
685 break;
686 default:
687 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
688 break;
689 }
690 err = toStatusT(status);
691 }
692 });
693 return hResult.isOk() ? err : DEAD_OBJECT;
694 }
695
Jeff Tinkera53d6552017-01-20 00:31:46 -0800696 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
697 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
698 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800699 drm::V1_0::KeyRequestType hKeyRequestType,
700 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800701
702 if (status == Status::OK) {
703 request = toVector(hRequest);
704 defaultUrl = toString8(hDefaultUrl);
705
706 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800707 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800708 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
709 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800710 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800711 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
712 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800713 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800714 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
715 break;
716 default:
717 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
718 break;
719 }
720 err = toStatusT(status);
721 }
722 });
723
Adam Stonef0e618d2018-01-17 19:20:41 -0800724 err = hResult.isOk() ? err : DEAD_OBJECT;
725 keyRequestTimer.SetAttribute(err);
726 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800727}
728
729status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
730 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
731 Mutex::Autolock autoLock(mLock);
Adam Stonecea91ce2018-01-22 19:23:28 -0800732 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTiming);
733
Jeff Tinker6d998b62017-12-18 14:37:43 -0800734 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800735
736 DrmSessionManager::Instance()->useSession(sessionId);
737
738 status_t err = UNKNOWN_ERROR;
739
740 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
741 toHidlVec(response),
742 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
743 if (status == Status::OK) {
744 keySetId = toVector(hKeySetId);
745 }
746 err = toStatusT(status);
747 }
748 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800749 err = hResult.isOk() ? err : DEAD_OBJECT;
750 keyResponseTimer.SetAttribute(err);
751 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800752}
753
754status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
755 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800756 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800757
758 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
759}
760
761status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
762 Vector<uint8_t> const &keySetId) {
763 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800764 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800765
766 DrmSessionManager::Instance()->useSession(sessionId);
767
768 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
769 toHidlVec(keySetId)));
770}
771
772status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
773 KeyedVector<String8, String8> &infoMap) const {
774 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800775 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800776
777 DrmSessionManager::Instance()->useSession(sessionId);
778
779 ::KeyedVector hInfoMap;
780
781 status_t err = UNKNOWN_ERROR;
782
783 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
784 [&](Status status, const hidl_vec<KeyValue>& map) {
785 if (status == Status::OK) {
786 infoMap = toKeyedVector(map);
787 }
788 err = toStatusT(status);
789 }
790 );
791
792 return hResult.isOk() ? err : DEAD_OBJECT;
793}
794
795status_t DrmHal::getProvisionRequest(String8 const &certType,
796 String8 const &certAuthority, Vector<uint8_t> &request,
797 String8 &defaultUrl) {
798 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800799 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800800
801 status_t err = UNKNOWN_ERROR;
802
803 Return<void> hResult = mPlugin->getProvisionRequest(
804 toHidlString(certType), toHidlString(certAuthority),
805 [&](Status status, const hidl_vec<uint8_t>& hRequest,
806 const hidl_string& hDefaultUrl) {
807 if (status == Status::OK) {
808 request = toVector(hRequest);
809 defaultUrl = toString8(hDefaultUrl);
810 }
811 err = toStatusT(status);
812 }
813 );
814
Adam Stonecea91ce2018-01-22 19:23:28 -0800815 err = hResult.isOk() ? err : DEAD_OBJECT;
816 mMetrics.mGetProvisionRequestCounter.Increment(err);
817 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800818}
819
820status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800821 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800822 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800823 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800824
825 status_t err = UNKNOWN_ERROR;
826
827 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
828 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
829 const hidl_vec<uint8_t>& hWrappedKey) {
830 if (status == Status::OK) {
831 certificate = toVector(hCertificate);
832 wrappedKey = toVector(hWrappedKey);
833 }
834 err = toStatusT(status);
835 }
836 );
837
Adam Stonecea91ce2018-01-22 19:23:28 -0800838 err = hResult.isOk() ? err : DEAD_OBJECT;
839 mMetrics.mProvideProvisionResponseCounter.Increment(err);
840 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841}
842
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800843status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800844 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800845 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800846
847 status_t err = UNKNOWN_ERROR;
848
849 Return<void> hResult = mPlugin->getSecureStops(
850 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
851 if (status == Status::OK) {
852 secureStops = toSecureStops(hSecureStops);
853 }
854 err = toStatusT(status);
855 }
856 );
857
858 return hResult.isOk() ? err : DEAD_OBJECT;
859}
860
861
Jeff Tinker15177d72018-01-25 12:57:55 -0800862status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
863 Mutex::Autolock autoLock(mLock);
864
865 if (mInitCheck != OK) {
866 return mInitCheck;
867 }
868
869 if (mPluginV1_1 == NULL) {
870 return ERROR_DRM_CANNOT_HANDLE;
871 }
872
873 status_t err = UNKNOWN_ERROR;
874
875 Return<void> hResult = mPluginV1_1->getSecureStopIds(
876 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
877 if (status == Status::OK) {
878 secureStopIds = toSecureStopIds(hSecureStopIds);
879 }
880 err = toStatusT(status);
881 }
882 );
883
884 return hResult.isOk() ? err : DEAD_OBJECT;
885}
886
887
Jeff Tinkera53d6552017-01-20 00:31:46 -0800888status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
889 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800890 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800891
892 status_t err = UNKNOWN_ERROR;
893
894 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
895 [&](Status status, const SecureStop& hSecureStop) {
896 if (status == Status::OK) {
897 secureStop = toVector(hSecureStop.opaqueData);
898 }
899 err = toStatusT(status);
900 }
901 );
902
903 return hResult.isOk() ? err : DEAD_OBJECT;
904}
905
906status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
907 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800908 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800909
Jeff Tinker15177d72018-01-25 12:57:55 -0800910 if (mPluginV1_1 != NULL) {
911 SecureStopRelease secureStopRelease;
912 secureStopRelease.opaqueData = toHidlVec(ssRelease);
913 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
914 }
915
Jeff Tinkera53d6552017-01-20 00:31:46 -0800916 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
917}
918
Jeff Tinker15177d72018-01-25 12:57:55 -0800919status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
920 Mutex::Autolock autoLock(mLock);
921
922 if (mInitCheck != OK) {
923 return mInitCheck;
924 }
925
926 if (mPluginV1_1 == NULL) {
927 return ERROR_DRM_CANNOT_HANDLE;
928 }
929
930 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
931}
932
933status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800934 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800935 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800936
Jeff Tinker15177d72018-01-25 12:57:55 -0800937 if (mPluginV1_1 != NULL) {
938 return toStatusT(mPluginV1_1->removeAllSecureStops());
939 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800940 return toStatusT(mPlugin->releaseAllSecureStops());
941}
942
Jeff Tinker6d998b62017-12-18 14:37:43 -0800943status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
944 DrmPlugin::HdcpLevel *max) const {
945 Mutex::Autolock autoLock(mLock);
946 INIT_CHECK();
947
948 if (connected == NULL || max == NULL) {
949 return BAD_VALUE;
950 }
951 status_t err = UNKNOWN_ERROR;
952
953 if (mPluginV1_1 == NULL) {
954 return ERROR_DRM_CANNOT_HANDLE;
955 }
956
957 *connected = DrmPlugin::kHdcpLevelUnknown;
958 *max = DrmPlugin::kHdcpLevelUnknown;
959
960 Return<void> hResult = mPluginV1_1->getHdcpLevels(
961 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
962 if (status == Status::OK) {
963 *connected = toHdcpLevel(hConnected);
964 *max = toHdcpLevel(hMax);
965 }
966 err = toStatusT(status);
967 }
968 );
969
970 return hResult.isOk() ? err : DEAD_OBJECT;
971}
972
973status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
974 Mutex::Autolock autoLock(mLock);
975 INIT_CHECK();
976
977 if (open == NULL || max == NULL) {
978 return BAD_VALUE;
979 }
980 status_t err = UNKNOWN_ERROR;
981
982 *open = 0;
983 *max = 0;
984
985 if (mPluginV1_1 == NULL) {
986 return ERROR_DRM_CANNOT_HANDLE;
987 }
988
989 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
990 [&](Status status, uint32_t hOpen, uint32_t hMax) {
991 if (status == Status::OK) {
992 *open = hOpen;
993 *max = hMax;
994 }
995 err = toStatusT(status);
996 }
997 );
998
999 return hResult.isOk() ? err : DEAD_OBJECT;
1000}
1001
1002status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1003 DrmPlugin::SecurityLevel *level) const {
1004 Mutex::Autolock autoLock(mLock);
1005 INIT_CHECK();
1006
1007 if (level == NULL) {
1008 return BAD_VALUE;
1009 }
1010 status_t err = UNKNOWN_ERROR;
1011
1012 if (mPluginV1_1 == NULL) {
1013 return ERROR_DRM_CANNOT_HANDLE;
1014 }
1015
1016 *level = DrmPlugin::kSecurityLevelUnknown;
1017
1018 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1019 [&](Status status, SecurityLevel hLevel) {
1020 if (status == Status::OK) {
1021 *level = toSecurityLevel(hLevel);
1022 }
1023 err = toStatusT(status);
1024 }
1025 );
1026
1027 return hResult.isOk() ? err : DEAD_OBJECT;
1028}
1029
Jeff Tinkera53d6552017-01-20 00:31:46 -08001030status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1031 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001032 return getPropertyStringInternal(name, value);
1033}
1034
1035status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1036 // This function is internal to the class and should only be called while
1037 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001038 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001039
1040 status_t err = UNKNOWN_ERROR;
1041
1042 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1043 [&](Status status, const hidl_string& hValue) {
1044 if (status == Status::OK) {
1045 value = toString8(hValue);
1046 }
1047 err = toStatusT(status);
1048 }
1049 );
1050
1051 return hResult.isOk() ? err : DEAD_OBJECT;
1052}
1053
1054status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1055 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001056 return getPropertyByteArrayInternal(name, value);
1057}
1058
1059status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1060 // This function is internal to the class and should only be called while
1061 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001062 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001063
1064 status_t err = UNKNOWN_ERROR;
1065
1066 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1067 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1068 if (status == Status::OK) {
1069 value = toVector(hValue);
1070 }
1071 err = toStatusT(status);
1072 }
1073 );
1074
Adam Stonecea91ce2018-01-22 19:23:28 -08001075 err = hResult.isOk() ? err : DEAD_OBJECT;
1076 if (name == kPropertyDeviceUniqueId) {
1077 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1078 }
1079 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001080}
1081
1082status_t DrmHal::setPropertyString(String8 const &name, String8 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
Jeff Tinker6d998b62017-12-18 14:37:43 -08001086 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001087 toHidlString(value));
1088 return toStatusT(status);
1089}
1090
1091status_t DrmHal::setPropertyByteArray(String8 const &name,
1092 Vector<uint8_t> const &value ) const {
1093 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001094 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001095
1096 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1097 toHidlVec(value));
1098 return toStatusT(status);
1099}
1100
Adam Stone637b7852018-01-30 12:09:36 -08001101status_t DrmHal::getMetrics(PersistableBundle* item) {
Adam Stonef0e618d2018-01-17 19:20:41 -08001102 if (item == nullptr) {
1103 return UNEXPECTED_NULL;
1104 }
1105
1106 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001107 return OK;
1108}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001109
1110status_t DrmHal::setCipherAlgorithm(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->setCipherAlgorithm(toHidlVec(sessionId),
1118 toHidlString(algorithm));
1119 return toStatusT(status);
1120}
1121
1122status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1123 String8 const &algorithm) {
1124 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001125 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001126
1127 DrmSessionManager::Instance()->useSession(sessionId);
1128
1129 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1130 toHidlString(algorithm));
1131 return toStatusT(status);
1132}
1133
1134status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001135 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1136 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001137 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001138 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001139
1140 DrmSessionManager::Instance()->useSession(sessionId);
1141
1142 status_t err = UNKNOWN_ERROR;
1143
1144 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1145 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1146 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1147 if (status == Status::OK) {
1148 output = toVector(hOutput);
1149 }
1150 err = toStatusT(status);
1151 }
1152 );
1153
1154 return hResult.isOk() ? err : DEAD_OBJECT;
1155}
1156
1157status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001158 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1159 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001160 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001161 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001162
1163 DrmSessionManager::Instance()->useSession(sessionId);
1164
1165 status_t err = UNKNOWN_ERROR;
1166
1167 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1168 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1169 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1170 if (status == Status::OK) {
1171 output = toVector(hOutput);
1172 }
1173 err = toStatusT(status);
1174 }
1175 );
1176
1177 return hResult.isOk() ? err : DEAD_OBJECT;
1178}
1179
1180status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001181 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1182 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001183 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001184 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001185
1186 DrmSessionManager::Instance()->useSession(sessionId);
1187
1188 status_t err = UNKNOWN_ERROR;
1189
1190 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1191 toHidlVec(keyId), toHidlVec(message),
1192 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1193 if (status == Status::OK) {
1194 signature = toVector(hSignature);
1195 }
1196 err = toStatusT(status);
1197 }
1198 );
1199
1200 return hResult.isOk() ? err : DEAD_OBJECT;
1201}
1202
1203status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001204 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1205 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001206 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001207 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001208
1209 DrmSessionManager::Instance()->useSession(sessionId);
1210
1211 status_t err = UNKNOWN_ERROR;
1212
1213 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1214 toHidlVec(message), toHidlVec(signature),
1215 [&](Status status, bool hMatch) {
1216 if (status == Status::OK) {
1217 match = hMatch;
1218 } else {
1219 match = false;
1220 }
1221 err = toStatusT(status);
1222 }
1223 );
1224
1225 return hResult.isOk() ? err : DEAD_OBJECT;
1226}
1227
1228status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001229 String8 const &algorithm, Vector<uint8_t> const &message,
1230 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001231 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001232 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001233
1234 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1235 return -EPERM;
1236 }
1237
1238 DrmSessionManager::Instance()->useSession(sessionId);
1239
1240 status_t err = UNKNOWN_ERROR;
1241
1242 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1243 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1244 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1245 if (status == Status::OK) {
1246 signature = toVector(hSignature);
1247 }
1248 err = toStatusT(status);
1249 }
1250 );
1251
1252 return hResult.isOk() ? err : DEAD_OBJECT;
1253}
1254
1255void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1256{
Jeff Tinkera53d6552017-01-20 00:31:46 -08001257 Mutex::Autolock autoLock(mLock);
Jeff Tinker61332812017-05-15 16:53:10 -07001258 closeOpenSessions();
Jeff Tinker3e289162017-06-01 11:13:53 -07001259 setListener(NULL);
Jeff Tinker319d5f42017-07-26 15:44:33 -07001260 mInitCheck = NO_INIT;
1261
Jeff Tinker70367f52017-06-16 12:41:33 -07001262 if (mPlugin != NULL) {
Jeff Tinker319d5f42017-07-26 15:44:33 -07001263 if (!mPlugin->setListener(NULL).isOk()) {
1264 mInitCheck = DEAD_OBJECT;
1265 }
Jeff Tinker70367f52017-06-16 12:41:33 -07001266 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001267 mPlugin.clear();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001268}
1269
1270void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1271{
1272 if (vec.size()) {
1273 obj.writeInt32(vec.size());
1274 obj.write(vec.data(), vec.size());
1275 } else {
1276 obj.writeInt32(0);
1277 }
1278}
1279
Adam Stoneab394d12017-12-22 12:34:20 -08001280
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001281void DrmHal::reportMetrics() const
1282{
1283 Vector<uint8_t> metrics;
1284 String8 vendor;
1285 String8 description;
1286 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1287 getPropertyStringInternal(String8("description"), description) == OK &&
1288 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1289 status_t res = android::reportDrmPluginMetrics(
1290 metrics, vendor, description);
1291 if (res != OK) {
1292 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1293 }
1294 }
1295}
1296
Jeff Tinkera53d6552017-01-20 00:31:46 -08001297} // namespace android