blob: 36f40cd9e8fd08fd7ebeaacb492e92c09a6931be [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
Adam Stonefb679e32018-02-07 10:25:48 -0800103std::string ToHexString(const std::string& str) {
104 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
774 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
775}
776
777status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
778 Vector<uint8_t> const &keySetId) {
779 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800780 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800781
782 DrmSessionManager::Instance()->useSession(sessionId);
783
784 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
785 toHidlVec(keySetId)));
786}
787
788status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
789 KeyedVector<String8, String8> &infoMap) const {
790 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800791 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800792
793 DrmSessionManager::Instance()->useSession(sessionId);
794
795 ::KeyedVector hInfoMap;
796
797 status_t err = UNKNOWN_ERROR;
798
799 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
800 [&](Status status, const hidl_vec<KeyValue>& map) {
801 if (status == Status::OK) {
802 infoMap = toKeyedVector(map);
803 }
804 err = toStatusT(status);
805 }
806 );
807
808 return hResult.isOk() ? err : DEAD_OBJECT;
809}
810
811status_t DrmHal::getProvisionRequest(String8 const &certType,
812 String8 const &certAuthority, Vector<uint8_t> &request,
813 String8 &defaultUrl) {
814 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800815 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800816
817 status_t err = UNKNOWN_ERROR;
818
819 Return<void> hResult = mPlugin->getProvisionRequest(
820 toHidlString(certType), toHidlString(certAuthority),
821 [&](Status status, const hidl_vec<uint8_t>& hRequest,
822 const hidl_string& hDefaultUrl) {
823 if (status == Status::OK) {
824 request = toVector(hRequest);
825 defaultUrl = toString8(hDefaultUrl);
826 }
827 err = toStatusT(status);
828 }
829 );
830
Adam Stonecea91ce2018-01-22 19:23:28 -0800831 err = hResult.isOk() ? err : DEAD_OBJECT;
832 mMetrics.mGetProvisionRequestCounter.Increment(err);
833 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800834}
835
836status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800837 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800838 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800839 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800840
841 status_t err = UNKNOWN_ERROR;
842
843 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
844 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
845 const hidl_vec<uint8_t>& hWrappedKey) {
846 if (status == Status::OK) {
847 certificate = toVector(hCertificate);
848 wrappedKey = toVector(hWrappedKey);
849 }
850 err = toStatusT(status);
851 }
852 );
853
Adam Stonecea91ce2018-01-22 19:23:28 -0800854 err = hResult.isOk() ? err : DEAD_OBJECT;
855 mMetrics.mProvideProvisionResponseCounter.Increment(err);
856 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800857}
858
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800859status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800860 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800861 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800862
863 status_t err = UNKNOWN_ERROR;
864
865 Return<void> hResult = mPlugin->getSecureStops(
866 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
867 if (status == Status::OK) {
868 secureStops = toSecureStops(hSecureStops);
869 }
870 err = toStatusT(status);
871 }
872 );
873
874 return hResult.isOk() ? err : DEAD_OBJECT;
875}
876
877
Jeff Tinker15177d72018-01-25 12:57:55 -0800878status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
879 Mutex::Autolock autoLock(mLock);
880
881 if (mInitCheck != OK) {
882 return mInitCheck;
883 }
884
885 if (mPluginV1_1 == NULL) {
886 return ERROR_DRM_CANNOT_HANDLE;
887 }
888
889 status_t err = UNKNOWN_ERROR;
890
891 Return<void> hResult = mPluginV1_1->getSecureStopIds(
892 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
893 if (status == Status::OK) {
894 secureStopIds = toSecureStopIds(hSecureStopIds);
895 }
896 err = toStatusT(status);
897 }
898 );
899
900 return hResult.isOk() ? err : DEAD_OBJECT;
901}
902
903
Jeff Tinkera53d6552017-01-20 00:31:46 -0800904status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
905 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800906 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800907
908 status_t err = UNKNOWN_ERROR;
909
910 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
911 [&](Status status, const SecureStop& hSecureStop) {
912 if (status == Status::OK) {
913 secureStop = toVector(hSecureStop.opaqueData);
914 }
915 err = toStatusT(status);
916 }
917 );
918
919 return hResult.isOk() ? err : DEAD_OBJECT;
920}
921
922status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
923 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800924 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800925
Jeff Tinker15177d72018-01-25 12:57:55 -0800926 if (mPluginV1_1 != NULL) {
927 SecureStopRelease secureStopRelease;
928 secureStopRelease.opaqueData = toHidlVec(ssRelease);
929 return toStatusT(mPluginV1_1->releaseSecureStops(secureStopRelease));
930 }
931
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
933}
934
Jeff Tinker15177d72018-01-25 12:57:55 -0800935status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
936 Mutex::Autolock autoLock(mLock);
937
938 if (mInitCheck != OK) {
939 return mInitCheck;
940 }
941
942 if (mPluginV1_1 == NULL) {
943 return ERROR_DRM_CANNOT_HANDLE;
944 }
945
946 return toStatusT(mPluginV1_1->removeSecureStop(toHidlVec(ssid)));
947}
948
949status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800950 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800951 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800952
Jeff Tinker15177d72018-01-25 12:57:55 -0800953 if (mPluginV1_1 != NULL) {
954 return toStatusT(mPluginV1_1->removeAllSecureStops());
955 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800956 return toStatusT(mPlugin->releaseAllSecureStops());
957}
958
Jeff Tinker6d998b62017-12-18 14:37:43 -0800959status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
960 DrmPlugin::HdcpLevel *max) const {
961 Mutex::Autolock autoLock(mLock);
962 INIT_CHECK();
963
964 if (connected == NULL || max == NULL) {
965 return BAD_VALUE;
966 }
967 status_t err = UNKNOWN_ERROR;
968
969 if (mPluginV1_1 == NULL) {
970 return ERROR_DRM_CANNOT_HANDLE;
971 }
972
973 *connected = DrmPlugin::kHdcpLevelUnknown;
974 *max = DrmPlugin::kHdcpLevelUnknown;
975
976 Return<void> hResult = mPluginV1_1->getHdcpLevels(
977 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
978 if (status == Status::OK) {
979 *connected = toHdcpLevel(hConnected);
980 *max = toHdcpLevel(hMax);
981 }
982 err = toStatusT(status);
983 }
984 );
985
986 return hResult.isOk() ? err : DEAD_OBJECT;
987}
988
989status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
990 Mutex::Autolock autoLock(mLock);
991 INIT_CHECK();
992
993 if (open == NULL || max == NULL) {
994 return BAD_VALUE;
995 }
996 status_t err = UNKNOWN_ERROR;
997
998 *open = 0;
999 *max = 0;
1000
1001 if (mPluginV1_1 == NULL) {
1002 return ERROR_DRM_CANNOT_HANDLE;
1003 }
1004
1005 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1006 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1007 if (status == Status::OK) {
1008 *open = hOpen;
1009 *max = hMax;
1010 }
1011 err = toStatusT(status);
1012 }
1013 );
1014
1015 return hResult.isOk() ? err : DEAD_OBJECT;
1016}
1017
1018status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1019 DrmPlugin::SecurityLevel *level) const {
1020 Mutex::Autolock autoLock(mLock);
1021 INIT_CHECK();
1022
1023 if (level == NULL) {
1024 return BAD_VALUE;
1025 }
1026 status_t err = UNKNOWN_ERROR;
1027
1028 if (mPluginV1_1 == NULL) {
1029 return ERROR_DRM_CANNOT_HANDLE;
1030 }
1031
1032 *level = DrmPlugin::kSecurityLevelUnknown;
1033
1034 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1035 [&](Status status, SecurityLevel hLevel) {
1036 if (status == Status::OK) {
1037 *level = toSecurityLevel(hLevel);
1038 }
1039 err = toStatusT(status);
1040 }
1041 );
1042
1043 return hResult.isOk() ? err : DEAD_OBJECT;
1044}
1045
Jeff Tinkera53d6552017-01-20 00:31:46 -08001046status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1047 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001048 return getPropertyStringInternal(name, value);
1049}
1050
1051status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1052 // This function is internal to the class and should only be called while
1053 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001054 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001055
1056 status_t err = UNKNOWN_ERROR;
1057
1058 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1059 [&](Status status, const hidl_string& hValue) {
1060 if (status == Status::OK) {
1061 value = toString8(hValue);
1062 }
1063 err = toStatusT(status);
1064 }
1065 );
1066
1067 return hResult.isOk() ? err : DEAD_OBJECT;
1068}
1069
1070status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1071 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001072 return getPropertyByteArrayInternal(name, value);
1073}
1074
1075status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1076 // This function is internal to the class and should only be called while
1077 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001078 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001079
1080 status_t err = UNKNOWN_ERROR;
1081
1082 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1083 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1084 if (status == Status::OK) {
1085 value = toVector(hValue);
1086 }
1087 err = toStatusT(status);
1088 }
1089 );
1090
Adam Stonecea91ce2018-01-22 19:23:28 -08001091 err = hResult.isOk() ? err : DEAD_OBJECT;
1092 if (name == kPropertyDeviceUniqueId) {
1093 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1094 }
1095 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001096}
1097
1098status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1099 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001100 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001101
Jeff Tinker6d998b62017-12-18 14:37:43 -08001102 Status status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001103 toHidlString(value));
1104 return toStatusT(status);
1105}
1106
1107status_t DrmHal::setPropertyByteArray(String8 const &name,
1108 Vector<uint8_t> const &value ) const {
1109 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001110 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001111
1112 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
1113 toHidlVec(value));
1114 return toStatusT(status);
1115}
1116
Adam Stone637b7852018-01-30 12:09:36 -08001117status_t DrmHal::getMetrics(PersistableBundle* item) {
Adam Stonef0e618d2018-01-17 19:20:41 -08001118 if (item == nullptr) {
1119 return UNEXPECTED_NULL;
1120 }
1121
1122 mMetrics.Export(item);
Adam Stoneab394d12017-12-22 12:34:20 -08001123 return OK;
1124}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001125
1126status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1127 String8 const &algorithm) {
1128 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001129 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001130
1131 DrmSessionManager::Instance()->useSession(sessionId);
1132
1133 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1134 toHidlString(algorithm));
1135 return toStatusT(status);
1136}
1137
1138status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1139 String8 const &algorithm) {
1140 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001141 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001142
1143 DrmSessionManager::Instance()->useSession(sessionId);
1144
1145 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1146 toHidlString(algorithm));
1147 return toStatusT(status);
1148}
1149
1150status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001151 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1152 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001153 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001154 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001155
1156 DrmSessionManager::Instance()->useSession(sessionId);
1157
1158 status_t err = UNKNOWN_ERROR;
1159
1160 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1161 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1162 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1163 if (status == Status::OK) {
1164 output = toVector(hOutput);
1165 }
1166 err = toStatusT(status);
1167 }
1168 );
1169
1170 return hResult.isOk() ? err : DEAD_OBJECT;
1171}
1172
1173status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001174 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1175 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001176 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001177 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001178
1179 DrmSessionManager::Instance()->useSession(sessionId);
1180
1181 status_t err = UNKNOWN_ERROR;
1182
1183 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1184 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1185 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1186 if (status == Status::OK) {
1187 output = toVector(hOutput);
1188 }
1189 err = toStatusT(status);
1190 }
1191 );
1192
1193 return hResult.isOk() ? err : DEAD_OBJECT;
1194}
1195
1196status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001197 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1198 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001199 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001200 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001201
1202 DrmSessionManager::Instance()->useSession(sessionId);
1203
1204 status_t err = UNKNOWN_ERROR;
1205
1206 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1207 toHidlVec(keyId), toHidlVec(message),
1208 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1209 if (status == Status::OK) {
1210 signature = toVector(hSignature);
1211 }
1212 err = toStatusT(status);
1213 }
1214 );
1215
1216 return hResult.isOk() ? err : DEAD_OBJECT;
1217}
1218
1219status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001220 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1221 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001222 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001223 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001224
1225 DrmSessionManager::Instance()->useSession(sessionId);
1226
1227 status_t err = UNKNOWN_ERROR;
1228
1229 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1230 toHidlVec(message), toHidlVec(signature),
1231 [&](Status status, bool hMatch) {
1232 if (status == Status::OK) {
1233 match = hMatch;
1234 } else {
1235 match = false;
1236 }
1237 err = toStatusT(status);
1238 }
1239 );
1240
1241 return hResult.isOk() ? err : DEAD_OBJECT;
1242}
1243
1244status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001245 String8 const &algorithm, Vector<uint8_t> const &message,
1246 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001247 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001248 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001249
1250 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1251 return -EPERM;
1252 }
1253
1254 DrmSessionManager::Instance()->useSession(sessionId);
1255
1256 status_t err = UNKNOWN_ERROR;
1257
1258 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1259 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1260 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1261 if (status == Status::OK) {
1262 signature = toVector(hSignature);
1263 }
1264 err = toStatusT(status);
1265 }
1266 );
1267
1268 return hResult.isOk() ? err : DEAD_OBJECT;
1269}
1270
1271void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1272{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001273 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001274}
1275
1276void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1277{
1278 if (vec.size()) {
1279 obj.writeInt32(vec.size());
1280 obj.write(vec.data(), vec.size());
1281 } else {
1282 obj.writeInt32(0);
1283 }
1284}
1285
Adam Stonefb679e32018-02-07 10:25:48 -08001286void DrmHal::reportFrameworkMetrics() const
1287{
1288 MediaAnalyticsItem item("mediadrm");
1289 item.generateSessionID();
1290 item.setPkgName(mMetrics.GetAppPackageName().c_str());
1291 String8 vendor;
1292 String8 description;
1293 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1294 if (result != OK) {
1295 ALOGE("Failed to get vendor from drm plugin. %d", result);
1296 } else {
1297 item.setCString("vendor", vendor.c_str());
1298 }
1299 result = getPropertyStringInternal(String8("description"), description);
1300 if (result != OK) {
1301 ALOGE("Failed to get description from drm plugin. %d", result);
1302 } else {
1303 item.setCString("description", description.c_str());
1304 }
Adam Stoneab394d12017-12-22 12:34:20 -08001305
Adam Stonefb679e32018-02-07 10:25:48 -08001306 std::string serializedMetrics;
1307 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1308 if (result != OK) {
1309 ALOGE("Failed to serialize Framework metrics: %d", result);
1310 }
1311 serializedMetrics = ToHexString(serializedMetrics);
1312 if (!serializedMetrics.empty()) {
1313 item.setCString("serialized_metrics", serializedMetrics.c_str());
1314 }
1315 if (!item.selfrecord()) {
1316 ALOGE("Failed to self record framework metrics.");
1317 }
1318}
1319
1320void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001321{
1322 Vector<uint8_t> metrics;
1323 String8 vendor;
1324 String8 description;
1325 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1326 getPropertyStringInternal(String8("description"), description) == OK &&
1327 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1328 status_t res = android::reportDrmPluginMetrics(
1329 metrics, vendor, description);
1330 if (res != OK) {
1331 ALOGE("Metrics were retrieved but could not be reported: %i", res);
1332 }
1333 }
1334}
1335
Jeff Tinkera53d6552017-01-20 00:31:46 -08001336} // namespace android