blob: 385c596ce88fd815dbcb8076543bda1d66dfb2d7 [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"
Adam Stonefb679e32018-02-07 10:25:48 -080019#include <iomanip>
20
Jeff Tinkera53d6552017-01-20 00:31:46 -080021#include <utils/Log.h>
22
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080025
Jeff Tinkera53d6552017-01-20 00:31:46 -080026#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;
Adam Stone637b7852018-01-30 12:09:36 -080057using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080058using ::android::sp;
59
Adam Stonecea91ce2018-01-22 19:23:28 -080060namespace {
61
62// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
63// in the MediaDrm API.
64constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
65
66}
67
Jeff Tinkera53d6552017-01-20 00:31:46 -080068namespace android {
69
Jeff Tinker6d998b62017-12-18 14:37:43 -080070#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
71
Jeff Tinkera53d6552017-01-20 00:31:46 -080072static inline int getCallingPid() {
73 return IPCThreadState::self()->getCallingPid();
74}
75
76static bool checkPermission(const char* permissionString) {
77 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
78 bool ok = checkCallingPermission(String16(permissionString));
79 if (!ok) ALOGE("Request requires %s", permissionString);
80 return ok;
81}
82
83static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
84 Vector<uint8_t> vector;
85 vector.appendArray(vec.data(), vec.size());
86 return *const_cast<const Vector<uint8_t> *>(&vector);
87}
88
89static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
90 hidl_vec<uint8_t> vec;
91 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
92 return vec;
93}
94
95static String8 toString8(const hidl_string &string) {
96 return String8(string.c_str());
97}
98
99static hidl_string toHidlString(const String8& string) {
100 return hidl_string(string.string());
101}
102
Jeff Tinker987ac702018-02-15 17:02:22 -0800103std::string toHexString(const std::string& str) {
Adam Stonefb679e32018-02-07 10:25:48 -0800104 std::ostringstream out;
105 out << std::hex << std::setfill('0');
106 for (size_t i = 0; i < str.size(); i++) {
107 out << std::setw(2) << (int)(str[i]);
108 }
109 return out.str();
110}
111
Jeff Tinker6d998b62017-12-18 14:37:43 -0800112static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
113 switch(level) {
114 case SecurityLevel::SW_SECURE_CRYPTO:
115 return DrmPlugin::kSecurityLevelSwSecureCrypto;
116 case SecurityLevel::SW_SECURE_DECODE:
117 return DrmPlugin::kSecurityLevelSwSecureDecode;
118 case SecurityLevel::HW_SECURE_CRYPTO:
119 return DrmPlugin::kSecurityLevelHwSecureCrypto;
120 case SecurityLevel::HW_SECURE_DECODE:
121 return DrmPlugin::kSecurityLevelHwSecureDecode;
122 case SecurityLevel::HW_SECURE_ALL:
123 return DrmPlugin::kSecurityLevelHwSecureAll;
124 default:
125 return DrmPlugin::kSecurityLevelUnknown;
126 }
127}
128
129static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
130 switch(level) {
131 case HdcpLevel::HDCP_NONE:
132 return DrmPlugin::kHdcpNone;
133 case HdcpLevel::HDCP_V1:
134 return DrmPlugin::kHdcpV1;
135 case HdcpLevel::HDCP_V2:
136 return DrmPlugin::kHdcpV2;
137 case HdcpLevel::HDCP_V2_1:
138 return DrmPlugin::kHdcpV2_1;
139 case HdcpLevel::HDCP_V2_2:
140 return DrmPlugin::kHdcpV2_2;
141 case HdcpLevel::HDCP_NO_OUTPUT:
142 return DrmPlugin::kHdcpNoOutput;
143 default:
144 return DrmPlugin::kHdcpLevelUnknown;
145 }
146}
147
Jeff Tinkera53d6552017-01-20 00:31:46 -0800148
149static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
150 keyedVector) {
151 std::vector<KeyValue> stdKeyedVector;
152 for (size_t i = 0; i < keyedVector.size(); i++) {
153 KeyValue keyValue;
154 keyValue.key = toHidlString(keyedVector.keyAt(i));
155 keyValue.value = toHidlString(keyedVector.valueAt(i));
156 stdKeyedVector.push_back(keyValue);
157 }
158 return ::KeyedVector(stdKeyedVector);
159}
160
161static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
162 hKeyedVector) {
163 KeyedVector<String8, String8> keyedVector;
164 for (size_t i = 0; i < hKeyedVector.size(); i++) {
165 keyedVector.add(toString8(hKeyedVector[i].key),
166 toString8(hKeyedVector[i].value));
167 }
168 return keyedVector;
169}
170
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800171static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800172 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800173 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800174 for (size_t i = 0; i < hSecureStops.size(); i++) {
175 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
176 }
177 return secureStops;
178}
179
Jeff Tinker15177d72018-01-25 12:57:55 -0800180static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
181 hSecureStopIds) {
182 List<Vector<uint8_t>> secureStopIds;
183 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
184 secureStopIds.push_back(toVector(hSecureStopIds[i]));
185 }
186 return secureStopIds;
187}
188
Jeff Tinkera53d6552017-01-20 00:31:46 -0800189static status_t toStatusT(Status status) {
190 switch (status) {
191 case Status::OK:
192 return OK;
193 break;
194 case Status::ERROR_DRM_NO_LICENSE:
195 return ERROR_DRM_NO_LICENSE;
196 break;
197 case Status::ERROR_DRM_LICENSE_EXPIRED:
198 return ERROR_DRM_LICENSE_EXPIRED;
199 break;
200 case Status::ERROR_DRM_SESSION_NOT_OPENED:
201 return ERROR_DRM_SESSION_NOT_OPENED;
202 break;
203 case Status::ERROR_DRM_CANNOT_HANDLE:
204 return ERROR_DRM_CANNOT_HANDLE;
205 break;
206 case Status::ERROR_DRM_INVALID_STATE:
207 return ERROR_DRM_TAMPER_DETECTED;
208 break;
209 case Status::BAD_VALUE:
210 return BAD_VALUE;
211 break;
212 case Status::ERROR_DRM_NOT_PROVISIONED:
213 return ERROR_DRM_NOT_PROVISIONED;
214 break;
215 case Status::ERROR_DRM_RESOURCE_BUSY:
216 return ERROR_DRM_RESOURCE_BUSY;
217 break;
218 case Status::ERROR_DRM_DEVICE_REVOKED:
219 return ERROR_DRM_DEVICE_REVOKED;
220 break;
221 case Status::ERROR_DRM_UNKNOWN:
222 default:
223 return ERROR_DRM_UNKNOWN;
224 break;
225 }
226}
227
228
229Mutex DrmHal::mLock;
230
231struct DrmSessionClient : public DrmSessionClientInterface {
232 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
233
234 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
235 sp<DrmHal> drm = mDrm.promote();
236 if (drm == NULL) {
237 return true;
238 }
239 status_t err = drm->closeSession(sessionId);
240 if (err != OK) {
241 return false;
242 }
243 drm->sendEvent(EventType::SESSION_RECLAIMED,
244 toHidlVec(sessionId), hidl_vec<uint8_t>());
245 return true;
246 }
247
248protected:
249 virtual ~DrmSessionClient() {}
250
251private:
252 wp<DrmHal> mDrm;
253
254 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
255};
256
257DrmHal::DrmHal()
258 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800259 mFactories(makeDrmFactories()),
260 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800261}
262
Jeff Tinker61332812017-05-15 16:53:10 -0700263void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800264 Mutex::Autolock autoLock(mLock);
265 auto openSessions = mOpenSessions;
266 for (size_t i = 0; i < openSessions.size(); i++) {
267 mLock.unlock();
268 closeSession(openSessions[i]);
269 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700270 }
271 mOpenSessions.clear();
272}
273
Jeff Tinkera53d6552017-01-20 00:31:46 -0800274DrmHal::~DrmHal() {
275 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
276}
277
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800278void DrmHal::cleanup() {
279 closeOpenSessions();
280
281 Mutex::Autolock autoLock(mLock);
282 reportPluginMetrics();
283 reportFrameworkMetrics();
284
285 setListener(NULL);
286 mInitCheck = NO_INIT;
287
288 if (mPlugin != NULL) {
289 if (!mPlugin->setListener(NULL).isOk()) {
290 mInitCheck = DEAD_OBJECT;
291 }
292 }
293 mPlugin.clear();
294 mPluginV1_1.clear();
295}
296
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800297Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
298 Vector<sp<IDrmFactory>> factories;
299
Jeff Tinker593111f2017-05-25 16:00:21 -0700300 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800301
302 if (manager != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000303 manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800304 [&factories](const hidl_vec<hidl_string> &registered) {
305 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000306 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800307 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000308 ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800309 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000310 }
311 }
312 }
313 );
314 manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
315 [&factories](const hidl_vec<hidl_string> &registered) {
316 for (const auto &instance : registered) {
317 auto factory = drm::V1_1::IDrmFactory::getService(instance);
318 if (factory != NULL) {
319 ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
320 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800321 }
322 }
323 }
324 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800325 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800326
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800327 if (factories.size() == 0) {
328 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700329 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800330 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000331 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800332 factories.push_back(passthrough);
333 } else {
334 ALOGE("Failed to find any drm factories");
335 }
336 }
337 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800338}
339
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800340sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
341 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stonefb679e32018-02-07 10:25:48 -0800342 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800343
344 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800345 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800346 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800347 if (status != Status::OK) {
348 ALOGE("Failed to make drm plugin");
349 return;
350 }
351 plugin = hPlugin;
352 }
353 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700354
355 if (!hResult.isOk()) {
356 ALOGE("createPlugin remote call failed");
357 }
358
Jeff Tinkera53d6552017-01-20 00:31:46 -0800359 return plugin;
360}
361
362status_t DrmHal::initCheck() const {
363 return mInitCheck;
364}
365
366status_t DrmHal::setListener(const sp<IDrmClient>& listener)
367{
368 Mutex::Autolock lock(mEventLock);
369 if (mListener != NULL){
370 IInterface::asBinder(mListener)->unlinkToDeath(this);
371 }
372 if (listener != NULL) {
373 IInterface::asBinder(listener)->linkToDeath(this);
374 }
375 mListener = listener;
376 return NO_ERROR;
377}
378
379Return<void> DrmHal::sendEvent(EventType hEventType,
380 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800381 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800382
383 mEventLock.lock();
384 sp<IDrmClient> listener = mListener;
385 mEventLock.unlock();
386
387 if (listener != NULL) {
388 Parcel obj;
389 writeByteArray(obj, sessionId);
390 writeByteArray(obj, data);
391
392 Mutex::Autolock lock(mNotifyLock);
393 DrmPlugin::EventType eventType;
394 switch(hEventType) {
395 case EventType::PROVISION_REQUIRED:
396 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
397 break;
398 case EventType::KEY_NEEDED:
399 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
400 break;
401 case EventType::KEY_EXPIRED:
402 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
403 break;
404 case EventType::VENDOR_DEFINED:
405 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
406 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700407 case EventType::SESSION_RECLAIMED:
408 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
409 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800410 default:
411 return Void();
412 }
413 listener->notify(eventType, 0, &obj);
414 }
415 return Void();
416}
417
418Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
419 int64_t expiryTimeInMS) {
420
421 mEventLock.lock();
422 sp<IDrmClient> listener = mListener;
423 mEventLock.unlock();
424
425 if (listener != NULL) {
426 Parcel obj;
427 writeByteArray(obj, sessionId);
428 obj.writeInt64(expiryTimeInMS);
429
430 Mutex::Autolock lock(mNotifyLock);
431 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
432 }
433 return Void();
434}
435
436Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
437 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
438
439 mEventLock.lock();
440 sp<IDrmClient> listener = mListener;
441 mEventLock.unlock();
442
443 if (listener != NULL) {
444 Parcel obj;
445 writeByteArray(obj, sessionId);
446
447 size_t nKeys = keyStatusList.size();
448 obj.writeInt32(nKeys);
449 for (size_t i = 0; i < nKeys; ++i) {
450 const KeyStatus &keyStatus = keyStatusList[i];
451 writeByteArray(obj, keyStatus.keyId);
452 uint32_t type;
453 switch(keyStatus.type) {
454 case KeyStatusType::USABLE:
455 type = DrmPlugin::kKeyStatusType_Usable;
456 break;
457 case KeyStatusType::EXPIRED:
458 type = DrmPlugin::kKeyStatusType_Expired;
459 break;
460 case KeyStatusType::OUTPUTNOTALLOWED:
461 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
462 break;
463 case KeyStatusType::STATUSPENDING:
464 type = DrmPlugin::kKeyStatusType_StatusPending;
465 break;
466 case KeyStatusType::INTERNALERROR:
467 default:
468 type = DrmPlugin::kKeyStatusType_InternalError;
469 break;
470 }
471 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800472 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800473 }
474 obj.writeInt32(hasNewUsableKey);
475
476 Mutex::Autolock lock(mNotifyLock);
477 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800478 } else {
479 // There's no listener. But we still want to count the key change
480 // events.
481 size_t nKeys = keyStatusList.size();
482 for (size_t i = 0; i < nKeys; i++) {
483 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
484 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800485 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800486
Jeff Tinkera53d6552017-01-20 00:31:46 -0800487 return Void();
488}
489
490bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
491 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800492
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800493 for (size_t i = 0; i < mFactories.size(); i++) {
494 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
495 if (mimeType != "") {
496 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
497 return true;
498 }
499 } else {
500 return true;
501 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800502 }
503 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800504 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800505}
506
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800507status_t DrmHal::createPlugin(const uint8_t uuid[16],
508 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800509 Mutex::Autolock autoLock(mLock);
510
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800511 for (size_t i = 0; i < mFactories.size(); i++) {
512 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
513 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Edwin Wong5641aa22018-01-30 17:52:21 -0800514 if (mPlugin != NULL) {
515 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
516 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800517 }
518 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800519
520 if (mPlugin == NULL) {
521 mInitCheck = ERROR_UNSUPPORTED;
522 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700523 if (!mPlugin->setListener(this).isOk()) {
524 mInitCheck = DEAD_OBJECT;
525 } else {
526 mInitCheck = OK;
527 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800528 }
529
530 return mInitCheck;
531}
532
533status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800534 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800535 return OK;
536}
537
Jeff Tinker41d279a2018-02-11 19:52:08 +0000538status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
539 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800540 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800541 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800542
Jeff Tinker41d279a2018-02-11 19:52:08 +0000543 SecurityLevel hSecurityLevel;
544 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000545
Jeff Tinker41d279a2018-02-11 19:52:08 +0000546 switch(level) {
547 case DrmPlugin::kSecurityLevelSwSecureCrypto:
548 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
549 break;
550 case DrmPlugin::kSecurityLevelSwSecureDecode:
551 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
552 break;
553 case DrmPlugin::kSecurityLevelHwSecureCrypto:
554 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
555 break;
556 case DrmPlugin::kSecurityLevelHwSecureDecode:
557 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
558 break;
559 case DrmPlugin::kSecurityLevelHwSecureAll:
560 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
561 break;
562 case DrmPlugin::kSecurityLevelMax:
563 setSecurityLevel = false;
564 break;
565 default:
566 return ERROR_DRM_CANNOT_HANDLE;
567 }
568
569 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800570 bool retry = true;
571 do {
572 hidl_vec<uint8_t> hSessionId;
573
Jeff Tinker41d279a2018-02-11 19:52:08 +0000574 Return<void> hResult;
575 if (mPluginV1_1 == NULL || !setSecurityLevel) {
576 hResult = mPlugin->openSession(
577 [&](Status status,const hidl_vec<uint8_t>& id) {
578 if (status == Status::OK) {
579 sessionId = toVector(id);
580 }
581 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800582 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000583 );
584 } else {
585 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
586 [&](Status status, const hidl_vec<uint8_t>& id) {
587 if (status == Status::OK) {
588 sessionId = toVector(id);
589 }
590 err = toStatusT(status);
591 }
592 );
593 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800594
595 if (!hResult.isOk()) {
596 err = DEAD_OBJECT;
597 }
598
599 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
600 mLock.unlock();
601 // reclaimSession may call back to closeSession, since mLock is
602 // shared between Drm instances, we should unlock here to avoid
603 // deadlock.
604 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
605 mLock.lock();
606 } else {
607 retry = false;
608 }
609 } while (retry);
610
611 if (err == OK) {
612 DrmSessionManager::Instance()->addSession(getCallingPid(),
613 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700614 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800615 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800616 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800617
Adam Stonef0e618d2018-01-17 19:20:41 -0800618 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800619 return err;
620}
621
622status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
623 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800624 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800625
Jeff Tinker319d5f42017-07-26 15:44:33 -0700626 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
627 if (status.isOk()) {
628 if (status == Status::OK) {
629 DrmSessionManager::Instance()->removeSession(sessionId);
630 for (size_t i = 0; i < mOpenSessions.size(); i++) {
631 if (mOpenSessions[i] == sessionId) {
632 mOpenSessions.removeAt(i);
633 break;
634 }
Jeff Tinker61332812017-05-15 16:53:10 -0700635 }
636 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800637 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800638 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800639 mMetrics.mCloseSessionCounter.Increment(response);
640 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800641 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800642 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700643 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800644}
645
646status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
647 Vector<uint8_t> const &initData, String8 const &mimeType,
648 DrmPlugin::KeyType keyType, KeyedVector<String8,
649 String8> const &optionalParameters, Vector<uint8_t> &request,
650 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
651 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800652 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800653 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800654
655 DrmSessionManager::Instance()->useSession(sessionId);
656
657 KeyType hKeyType;
658 if (keyType == DrmPlugin::kKeyType_Streaming) {
659 hKeyType = KeyType::STREAMING;
660 } else if (keyType == DrmPlugin::kKeyType_Offline) {
661 hKeyType = KeyType::OFFLINE;
662 } else if (keyType == DrmPlugin::kKeyType_Release) {
663 hKeyType = KeyType::RELEASE;
664 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800665 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800666 return BAD_VALUE;
667 }
668
669 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
670
671 status_t err = UNKNOWN_ERROR;
672
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800673 if (mPluginV1_1 != NULL) {
674 Return<void> hResult =
675 mPluginV1_1->getKeyRequest_1_1(
676 toHidlVec(sessionId), toHidlVec(initData),
677 toHidlString(mimeType), hKeyType, hOptionalParameters,
678 [&](Status status, const hidl_vec<uint8_t>& hRequest,
679 drm::V1_1::KeyRequestType hKeyRequestType,
680 const hidl_string& hDefaultUrl) {
681
682 if (status == Status::OK) {
683 request = toVector(hRequest);
684 defaultUrl = toString8(hDefaultUrl);
685
686 switch (hKeyRequestType) {
687 case drm::V1_1::KeyRequestType::INITIAL:
688 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
689 break;
690 case drm::V1_1::KeyRequestType::RENEWAL:
691 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
692 break;
693 case drm::V1_1::KeyRequestType::RELEASE:
694 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
695 break;
696 case drm::V1_1::KeyRequestType::NONE:
697 *keyRequestType = DrmPlugin::kKeyRequestType_None;
698 break;
699 case drm::V1_1::KeyRequestType::UPDATE:
700 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
701 break;
702 default:
703 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
704 break;
705 }
706 err = toStatusT(status);
707 }
708 });
709 return hResult.isOk() ? err : DEAD_OBJECT;
710 }
711
Jeff Tinkera53d6552017-01-20 00:31:46 -0800712 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
713 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
714 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800715 drm::V1_0::KeyRequestType hKeyRequestType,
716 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800717
718 if (status == Status::OK) {
719 request = toVector(hRequest);
720 defaultUrl = toString8(hDefaultUrl);
721
722 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800723 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800724 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
725 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800726 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800727 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
728 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800729 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800730 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
731 break;
732 default:
733 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
734 break;
735 }
736 err = toStatusT(status);
737 }
738 });
739
Adam Stonef0e618d2018-01-17 19:20:41 -0800740 err = hResult.isOk() ? err : DEAD_OBJECT;
741 keyRequestTimer.SetAttribute(err);
742 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800743}
744
745status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
746 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
747 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800748 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800749
Jeff Tinker6d998b62017-12-18 14:37:43 -0800750 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800751
752 DrmSessionManager::Instance()->useSession(sessionId);
753
754 status_t err = UNKNOWN_ERROR;
755
756 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
757 toHidlVec(response),
758 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
759 if (status == Status::OK) {
760 keySetId = toVector(hKeySetId);
761 }
762 err = toStatusT(status);
763 }
764 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800765 err = hResult.isOk() ? err : DEAD_OBJECT;
766 keyResponseTimer.SetAttribute(err);
767 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800768}
769
770status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
771 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800772 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773
Jeff Tinker58ad4752018-02-16 16:51:59 -0800774 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
775 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800776}
777
778status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
779 Vector<uint8_t> const &keySetId) {
780 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800781 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800782
783 DrmSessionManager::Instance()->useSession(sessionId);
784
Jeff Tinker58ad4752018-02-16 16:51:59 -0800785 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
786 toHidlVec(keySetId));
787 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800788}
789
790status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
791 KeyedVector<String8, String8> &infoMap) const {
792 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800793 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800794
795 DrmSessionManager::Instance()->useSession(sessionId);
796
797 ::KeyedVector hInfoMap;
798
799 status_t err = UNKNOWN_ERROR;
800
801 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
802 [&](Status status, const hidl_vec<KeyValue>& map) {
803 if (status == Status::OK) {
804 infoMap = toKeyedVector(map);
805 }
806 err = toStatusT(status);
807 }
808 );
809
810 return hResult.isOk() ? err : DEAD_OBJECT;
811}
812
813status_t DrmHal::getProvisionRequest(String8 const &certType,
814 String8 const &certAuthority, Vector<uint8_t> &request,
815 String8 &defaultUrl) {
816 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800817 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800818
819 status_t err = UNKNOWN_ERROR;
820
821 Return<void> hResult = mPlugin->getProvisionRequest(
822 toHidlString(certType), toHidlString(certAuthority),
823 [&](Status status, const hidl_vec<uint8_t>& hRequest,
824 const hidl_string& hDefaultUrl) {
825 if (status == Status::OK) {
826 request = toVector(hRequest);
827 defaultUrl = toString8(hDefaultUrl);
828 }
829 err = toStatusT(status);
830 }
831 );
832
Adam Stonecea91ce2018-01-22 19:23:28 -0800833 err = hResult.isOk() ? err : DEAD_OBJECT;
834 mMetrics.mGetProvisionRequestCounter.Increment(err);
835 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800836}
837
838status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800839 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800840 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800841 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800842
843 status_t err = UNKNOWN_ERROR;
844
845 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
846 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
847 const hidl_vec<uint8_t>& hWrappedKey) {
848 if (status == Status::OK) {
849 certificate = toVector(hCertificate);
850 wrappedKey = toVector(hWrappedKey);
851 }
852 err = toStatusT(status);
853 }
854 );
855
Adam Stonecea91ce2018-01-22 19:23:28 -0800856 err = hResult.isOk() ? err : DEAD_OBJECT;
857 mMetrics.mProvideProvisionResponseCounter.Increment(err);
858 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800859}
860
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800861status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800862 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800863 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800864
865 status_t err = UNKNOWN_ERROR;
866
867 Return<void> hResult = mPlugin->getSecureStops(
868 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
869 if (status == Status::OK) {
870 secureStops = toSecureStops(hSecureStops);
871 }
872 err = toStatusT(status);
873 }
874 );
875
876 return hResult.isOk() ? err : DEAD_OBJECT;
877}
878
879
Jeff Tinker15177d72018-01-25 12:57:55 -0800880status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
881 Mutex::Autolock autoLock(mLock);
882
883 if (mInitCheck != OK) {
884 return mInitCheck;
885 }
886
887 if (mPluginV1_1 == NULL) {
888 return ERROR_DRM_CANNOT_HANDLE;
889 }
890
891 status_t err = UNKNOWN_ERROR;
892
893 Return<void> hResult = mPluginV1_1->getSecureStopIds(
894 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
895 if (status == Status::OK) {
896 secureStopIds = toSecureStopIds(hSecureStopIds);
897 }
898 err = toStatusT(status);
899 }
900 );
901
902 return hResult.isOk() ? err : DEAD_OBJECT;
903}
904
905
Jeff Tinkera53d6552017-01-20 00:31:46 -0800906status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
907 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800908 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800909
910 status_t err = UNKNOWN_ERROR;
911
912 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
913 [&](Status status, const SecureStop& hSecureStop) {
914 if (status == Status::OK) {
915 secureStop = toVector(hSecureStop.opaqueData);
916 }
917 err = toStatusT(status);
918 }
919 );
920
921 return hResult.isOk() ? err : DEAD_OBJECT;
922}
923
924status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
925 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800926 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800927
Jeff Tinker58ad4752018-02-16 16:51:59 -0800928 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -0800929 if (mPluginV1_1 != NULL) {
930 SecureStopRelease secureStopRelease;
931 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -0800932 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
933 } else {
934 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -0800935 }
Jeff Tinker58ad4752018-02-16 16:51:59 -0800936 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937}
938
Jeff Tinker15177d72018-01-25 12:57:55 -0800939status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
940 Mutex::Autolock autoLock(mLock);
941
942 if (mInitCheck != OK) {
943 return mInitCheck;
944 }
945
946 if (mPluginV1_1 == NULL) {
947 return ERROR_DRM_CANNOT_HANDLE;
948 }
949
Jeff Tinker58ad4752018-02-16 16:51:59 -0800950 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
951 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -0800952}
953
954status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800955 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800956 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800957
Jeff Tinker58ad4752018-02-16 16:51:59 -0800958 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -0800959 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -0800960 status = mPluginV1_1->removeAllSecureStops();
961 } else {
962 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -0800963 }
Jeff Tinker58ad4752018-02-16 16:51:59 -0800964 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800965}
966
Jeff Tinker6d998b62017-12-18 14:37:43 -0800967status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
968 DrmPlugin::HdcpLevel *max) const {
969 Mutex::Autolock autoLock(mLock);
970 INIT_CHECK();
971
972 if (connected == NULL || max == NULL) {
973 return BAD_VALUE;
974 }
975 status_t err = UNKNOWN_ERROR;
976
977 if (mPluginV1_1 == NULL) {
978 return ERROR_DRM_CANNOT_HANDLE;
979 }
980
981 *connected = DrmPlugin::kHdcpLevelUnknown;
982 *max = DrmPlugin::kHdcpLevelUnknown;
983
984 Return<void> hResult = mPluginV1_1->getHdcpLevels(
985 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
986 if (status == Status::OK) {
987 *connected = toHdcpLevel(hConnected);
988 *max = toHdcpLevel(hMax);
989 }
990 err = toStatusT(status);
991 }
992 );
993
994 return hResult.isOk() ? err : DEAD_OBJECT;
995}
996
997status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
998 Mutex::Autolock autoLock(mLock);
999 INIT_CHECK();
1000
1001 if (open == NULL || max == NULL) {
1002 return BAD_VALUE;
1003 }
1004 status_t err = UNKNOWN_ERROR;
1005
1006 *open = 0;
1007 *max = 0;
1008
1009 if (mPluginV1_1 == NULL) {
1010 return ERROR_DRM_CANNOT_HANDLE;
1011 }
1012
1013 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1014 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1015 if (status == Status::OK) {
1016 *open = hOpen;
1017 *max = hMax;
1018 }
1019 err = toStatusT(status);
1020 }
1021 );
1022
1023 return hResult.isOk() ? err : DEAD_OBJECT;
1024}
1025
1026status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1027 DrmPlugin::SecurityLevel *level) const {
1028 Mutex::Autolock autoLock(mLock);
1029 INIT_CHECK();
1030
1031 if (level == NULL) {
1032 return BAD_VALUE;
1033 }
1034 status_t err = UNKNOWN_ERROR;
1035
1036 if (mPluginV1_1 == NULL) {
1037 return ERROR_DRM_CANNOT_HANDLE;
1038 }
1039
1040 *level = DrmPlugin::kSecurityLevelUnknown;
1041
1042 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1043 [&](Status status, SecurityLevel hLevel) {
1044 if (status == Status::OK) {
1045 *level = toSecurityLevel(hLevel);
1046 }
1047 err = toStatusT(status);
1048 }
1049 );
1050
1051 return hResult.isOk() ? err : DEAD_OBJECT;
1052}
1053
Jeff Tinkera53d6552017-01-20 00:31:46 -08001054status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1055 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001056 return getPropertyStringInternal(name, value);
1057}
1058
1059status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &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->getPropertyString(toHidlString(name),
1067 [&](Status status, const hidl_string& hValue) {
1068 if (status == Status::OK) {
1069 value = toString8(hValue);
1070 }
1071 err = toStatusT(status);
1072 }
1073 );
1074
1075 return hResult.isOk() ? err : DEAD_OBJECT;
1076}
1077
1078status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1079 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001080 return getPropertyByteArrayInternal(name, value);
1081}
1082
1083status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1084 // This function is internal to the class and should only be called while
1085 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001086 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001087
1088 status_t err = UNKNOWN_ERROR;
1089
1090 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1091 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1092 if (status == Status::OK) {
1093 value = toVector(hValue);
1094 }
1095 err = toStatusT(status);
1096 }
1097 );
1098
Adam Stonecea91ce2018-01-22 19:23:28 -08001099 err = hResult.isOk() ? err : DEAD_OBJECT;
1100 if (name == kPropertyDeviceUniqueId) {
1101 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1102 }
1103 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001104}
1105
1106status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1107 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001108 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001109
Jeff Tinker58ad4752018-02-16 16:51:59 -08001110 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001111 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001112 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001113}
1114
1115status_t DrmHal::setPropertyByteArray(String8 const &name,
1116 Vector<uint8_t> const &value ) const {
1117 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001118 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001119
Jeff Tinker58ad4752018-02-16 16:51:59 -08001120 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001121 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001122 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001123}
1124
Adam Stone637b7852018-01-30 12:09:36 -08001125status_t DrmHal::getMetrics(PersistableBundle* item) {
Adam Stonef0e618d2018-01-17 19:20:41 -08001126 if (item == nullptr) {
1127 return UNEXPECTED_NULL;
1128 }
1129
1130 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001131 return OK;
1132}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001133
1134status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1135 String8 const &algorithm) {
1136 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001137 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001138
1139 DrmSessionManager::Instance()->useSession(sessionId);
1140
1141 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1142 toHidlString(algorithm));
1143 return toStatusT(status);
1144}
1145
1146status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1147 String8 const &algorithm) {
1148 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001149 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001150
1151 DrmSessionManager::Instance()->useSession(sessionId);
1152
1153 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1154 toHidlString(algorithm));
1155 return toStatusT(status);
1156}
1157
1158status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001159 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1160 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001161 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001162 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001163
1164 DrmSessionManager::Instance()->useSession(sessionId);
1165
1166 status_t err = UNKNOWN_ERROR;
1167
1168 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1169 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1170 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1171 if (status == Status::OK) {
1172 output = toVector(hOutput);
1173 }
1174 err = toStatusT(status);
1175 }
1176 );
1177
1178 return hResult.isOk() ? err : DEAD_OBJECT;
1179}
1180
1181status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001182 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1183 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001184 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001185 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001186
1187 DrmSessionManager::Instance()->useSession(sessionId);
1188
1189 status_t err = UNKNOWN_ERROR;
1190
1191 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1192 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1193 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1194 if (status == Status::OK) {
1195 output = toVector(hOutput);
1196 }
1197 err = toStatusT(status);
1198 }
1199 );
1200
1201 return hResult.isOk() ? err : DEAD_OBJECT;
1202}
1203
1204status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001205 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1206 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001207 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001208 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001209
1210 DrmSessionManager::Instance()->useSession(sessionId);
1211
1212 status_t err = UNKNOWN_ERROR;
1213
1214 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1215 toHidlVec(keyId), toHidlVec(message),
1216 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1217 if (status == Status::OK) {
1218 signature = toVector(hSignature);
1219 }
1220 err = toStatusT(status);
1221 }
1222 );
1223
1224 return hResult.isOk() ? err : DEAD_OBJECT;
1225}
1226
1227status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001228 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1229 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001230 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001231 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001232
1233 DrmSessionManager::Instance()->useSession(sessionId);
1234
1235 status_t err = UNKNOWN_ERROR;
1236
1237 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1238 toHidlVec(message), toHidlVec(signature),
1239 [&](Status status, bool hMatch) {
1240 if (status == Status::OK) {
1241 match = hMatch;
1242 } else {
1243 match = false;
1244 }
1245 err = toStatusT(status);
1246 }
1247 );
1248
1249 return hResult.isOk() ? err : DEAD_OBJECT;
1250}
1251
1252status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001253 String8 const &algorithm, Vector<uint8_t> const &message,
1254 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001255 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001256 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001257
1258 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1259 return -EPERM;
1260 }
1261
1262 DrmSessionManager::Instance()->useSession(sessionId);
1263
1264 status_t err = UNKNOWN_ERROR;
1265
1266 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1267 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1268 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1269 if (status == Status::OK) {
1270 signature = toVector(hSignature);
1271 }
1272 err = toStatusT(status);
1273 }
1274 );
1275
1276 return hResult.isOk() ? err : DEAD_OBJECT;
1277}
1278
1279void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1280{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001281 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001282}
1283
1284void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1285{
1286 if (vec.size()) {
1287 obj.writeInt32(vec.size());
1288 obj.write(vec.data(), vec.size());
1289 } else {
1290 obj.writeInt32(0);
1291 }
1292}
1293
Adam Stonefb679e32018-02-07 10:25:48 -08001294void DrmHal::reportFrameworkMetrics() const
1295{
1296 MediaAnalyticsItem item("mediadrm");
1297 item.generateSessionID();
1298 item.setPkgName(mMetrics.GetAppPackageName().c_str());
1299 String8 vendor;
1300 String8 description;
1301 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1302 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001303 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001304 } else {
1305 item.setCString("vendor", vendor.c_str());
1306 }
1307 result = getPropertyStringInternal(String8("description"), description);
1308 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001309 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001310 } else {
1311 item.setCString("description", description.c_str());
1312 }
Adam Stoneab394d12017-12-22 12:34:20 -08001313
Adam Stonefb679e32018-02-07 10:25:48 -08001314 std::string serializedMetrics;
1315 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1316 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001317 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001318 }
Jeff Tinker987ac702018-02-15 17:02:22 -08001319 serializedMetrics = toHexString(serializedMetrics);
Adam Stonefb679e32018-02-07 10:25:48 -08001320 if (!serializedMetrics.empty()) {
1321 item.setCString("serialized_metrics", serializedMetrics.c_str());
1322 }
1323 if (!item.selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001324 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001325 }
1326}
1327
1328void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001329{
1330 Vector<uint8_t> metrics;
1331 String8 vendor;
1332 String8 description;
1333 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1334 getPropertyStringInternal(String8("description"), description) == OK &&
1335 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1336 status_t res = android::reportDrmPluginMetrics(
1337 metrics, vendor, description);
1338 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001339 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001340 }
1341 }
1342}
1343
Jeff Tinkera53d6552017-01-20 00:31:46 -08001344} // namespace android