blob: 5d971888af4114a56cc809e4e857e18372382ff4 [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
Adam Stonef0e618d2018-01-17 19:20:41 -080030#include <media/EventMetric.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070031#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080032#include <media/drm/DrmAPI.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AString.h>
35#include <media/stagefright/foundation/hexdump.h>
36#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080037#include <mediadrm/DrmHal.h>
38#include <mediadrm/DrmSessionClientInterface.h>
39#include <mediadrm/DrmSessionManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080040
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;
Adam Stone28f27c32018-02-05 15:07:48 -080051using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080052using ::android::hardware::hidl_array;
53using ::android::hardware::hidl_string;
54using ::android::hardware::hidl_vec;
55using ::android::hardware::Return;
56using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080057using ::android::hidl::manager::V1_0::IServiceManager;
Adam Stone637b7852018-01-30 12:09:36 -080058using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080059using ::android::sp;
60
Adam Stonecea91ce2018-01-22 19:23:28 -080061namespace {
62
63// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
64// in the MediaDrm API.
65constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
66
67}
68
Jeff Tinkera53d6552017-01-20 00:31:46 -080069namespace android {
70
Jeff Tinker6d998b62017-12-18 14:37:43 -080071#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
72
Jeff Tinkera53d6552017-01-20 00:31:46 -080073static inline int getCallingPid() {
74 return IPCThreadState::self()->getCallingPid();
75}
76
77static bool checkPermission(const char* permissionString) {
78 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
79 bool ok = checkCallingPermission(String16(permissionString));
80 if (!ok) ALOGE("Request requires %s", permissionString);
81 return ok;
82}
83
84static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
85 Vector<uint8_t> vector;
86 vector.appendArray(vec.data(), vec.size());
87 return *const_cast<const Vector<uint8_t> *>(&vector);
88}
89
90static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
91 hidl_vec<uint8_t> vec;
92 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
93 return vec;
94}
95
96static String8 toString8(const hidl_string &string) {
97 return String8(string.c_str());
98}
99
100static hidl_string toHidlString(const String8& string) {
101 return hidl_string(string.string());
102}
103
Jeff Tinker987ac702018-02-15 17:02:22 -0800104std::string toHexString(const std::string& str) {
Adam Stonefb679e32018-02-07 10:25:48 -0800105 std::ostringstream out;
106 out << std::hex << std::setfill('0');
107 for (size_t i = 0; i < str.size(); i++) {
108 out << std::setw(2) << (int)(str[i]);
109 }
110 return out.str();
111}
112
Jeff Tinker6d998b62017-12-18 14:37:43 -0800113static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
114 switch(level) {
115 case SecurityLevel::SW_SECURE_CRYPTO:
116 return DrmPlugin::kSecurityLevelSwSecureCrypto;
117 case SecurityLevel::SW_SECURE_DECODE:
118 return DrmPlugin::kSecurityLevelSwSecureDecode;
119 case SecurityLevel::HW_SECURE_CRYPTO:
120 return DrmPlugin::kSecurityLevelHwSecureCrypto;
121 case SecurityLevel::HW_SECURE_DECODE:
122 return DrmPlugin::kSecurityLevelHwSecureDecode;
123 case SecurityLevel::HW_SECURE_ALL:
124 return DrmPlugin::kSecurityLevelHwSecureAll;
125 default:
126 return DrmPlugin::kSecurityLevelUnknown;
127 }
128}
129
130static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
131 switch(level) {
132 case HdcpLevel::HDCP_NONE:
133 return DrmPlugin::kHdcpNone;
134 case HdcpLevel::HDCP_V1:
135 return DrmPlugin::kHdcpV1;
136 case HdcpLevel::HDCP_V2:
137 return DrmPlugin::kHdcpV2;
138 case HdcpLevel::HDCP_V2_1:
139 return DrmPlugin::kHdcpV2_1;
140 case HdcpLevel::HDCP_V2_2:
141 return DrmPlugin::kHdcpV2_2;
142 case HdcpLevel::HDCP_NO_OUTPUT:
143 return DrmPlugin::kHdcpNoOutput;
144 default:
145 return DrmPlugin::kHdcpLevelUnknown;
146 }
147}
148
Jeff Tinkera53d6552017-01-20 00:31:46 -0800149
150static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
151 keyedVector) {
152 std::vector<KeyValue> stdKeyedVector;
153 for (size_t i = 0; i < keyedVector.size(); i++) {
154 KeyValue keyValue;
155 keyValue.key = toHidlString(keyedVector.keyAt(i));
156 keyValue.value = toHidlString(keyedVector.valueAt(i));
157 stdKeyedVector.push_back(keyValue);
158 }
159 return ::KeyedVector(stdKeyedVector);
160}
161
162static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
163 hKeyedVector) {
164 KeyedVector<String8, String8> keyedVector;
165 for (size_t i = 0; i < hKeyedVector.size(); i++) {
166 keyedVector.add(toString8(hKeyedVector[i].key),
167 toString8(hKeyedVector[i].value));
168 }
169 return keyedVector;
170}
171
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800172static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800173 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800174 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800175 for (size_t i = 0; i < hSecureStops.size(); i++) {
176 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
177 }
178 return secureStops;
179}
180
Jeff Tinker15177d72018-01-25 12:57:55 -0800181static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
182 hSecureStopIds) {
183 List<Vector<uint8_t>> secureStopIds;
184 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
185 secureStopIds.push_back(toVector(hSecureStopIds[i]));
186 }
187 return secureStopIds;
188}
189
Jeff Tinkera53d6552017-01-20 00:31:46 -0800190static status_t toStatusT(Status status) {
191 switch (status) {
192 case Status::OK:
193 return OK;
194 break;
195 case Status::ERROR_DRM_NO_LICENSE:
196 return ERROR_DRM_NO_LICENSE;
197 break;
198 case Status::ERROR_DRM_LICENSE_EXPIRED:
199 return ERROR_DRM_LICENSE_EXPIRED;
200 break;
201 case Status::ERROR_DRM_SESSION_NOT_OPENED:
202 return ERROR_DRM_SESSION_NOT_OPENED;
203 break;
204 case Status::ERROR_DRM_CANNOT_HANDLE:
205 return ERROR_DRM_CANNOT_HANDLE;
206 break;
207 case Status::ERROR_DRM_INVALID_STATE:
208 return ERROR_DRM_TAMPER_DETECTED;
209 break;
210 case Status::BAD_VALUE:
211 return BAD_VALUE;
212 break;
213 case Status::ERROR_DRM_NOT_PROVISIONED:
214 return ERROR_DRM_NOT_PROVISIONED;
215 break;
216 case Status::ERROR_DRM_RESOURCE_BUSY:
217 return ERROR_DRM_RESOURCE_BUSY;
218 break;
219 case Status::ERROR_DRM_DEVICE_REVOKED:
220 return ERROR_DRM_DEVICE_REVOKED;
221 break;
222 case Status::ERROR_DRM_UNKNOWN:
223 default:
224 return ERROR_DRM_UNKNOWN;
225 break;
226 }
227}
228
229
230Mutex DrmHal::mLock;
231
232struct DrmSessionClient : public DrmSessionClientInterface {
233 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
234
235 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
236 sp<DrmHal> drm = mDrm.promote();
237 if (drm == NULL) {
238 return true;
239 }
240 status_t err = drm->closeSession(sessionId);
241 if (err != OK) {
242 return false;
243 }
244 drm->sendEvent(EventType::SESSION_RECLAIMED,
245 toHidlVec(sessionId), hidl_vec<uint8_t>());
246 return true;
247 }
248
249protected:
250 virtual ~DrmSessionClient() {}
251
252private:
253 wp<DrmHal> mDrm;
254
255 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
256};
257
258DrmHal::DrmHal()
259 : mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800260 mFactories(makeDrmFactories()),
261 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800262}
263
Jeff Tinker61332812017-05-15 16:53:10 -0700264void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800265 Mutex::Autolock autoLock(mLock);
266 auto openSessions = mOpenSessions;
267 for (size_t i = 0; i < openSessions.size(); i++) {
268 mLock.unlock();
269 closeSession(openSessions[i]);
270 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700271 }
272 mOpenSessions.clear();
273}
274
Jeff Tinkera53d6552017-01-20 00:31:46 -0800275DrmHal::~DrmHal() {
276 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
277}
278
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800279void DrmHal::cleanup() {
280 closeOpenSessions();
281
282 Mutex::Autolock autoLock(mLock);
283 reportPluginMetrics();
284 reportFrameworkMetrics();
285
286 setListener(NULL);
287 mInitCheck = NO_INIT;
288
289 if (mPlugin != NULL) {
290 if (!mPlugin->setListener(NULL).isOk()) {
291 mInitCheck = DEAD_OBJECT;
292 }
293 }
294 mPlugin.clear();
295 mPluginV1_1.clear();
296}
297
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800298Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
299 Vector<sp<IDrmFactory>> factories;
300
Jeff Tinker593111f2017-05-25 16:00:21 -0700301 auto manager = hardware::defaultServiceManager();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800302
303 if (manager != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000304 manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800305 [&factories](const hidl_vec<hidl_string> &registered) {
306 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000307 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800308 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000309 ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800310 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000311 }
312 }
313 }
314 );
315 manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
316 [&factories](const hidl_vec<hidl_string> &registered) {
317 for (const auto &instance : registered) {
318 auto factory = drm::V1_1::IDrmFactory::getService(instance);
319 if (factory != NULL) {
320 ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
321 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800322 }
323 }
324 }
325 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800326 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800327
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800328 if (factories.size() == 0) {
329 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700330 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800331 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000332 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800333 factories.push_back(passthrough);
334 } else {
335 ALOGE("Failed to find any drm factories");
336 }
337 }
338 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800339}
340
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800341sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
342 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stonefb679e32018-02-07 10:25:48 -0800343 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800344
345 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800346 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800347 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800348 if (status != Status::OK) {
349 ALOGE("Failed to make drm plugin");
350 return;
351 }
352 plugin = hPlugin;
353 }
354 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700355
356 if (!hResult.isOk()) {
357 ALOGE("createPlugin remote call failed");
358 }
359
Jeff Tinkera53d6552017-01-20 00:31:46 -0800360 return plugin;
361}
362
363status_t DrmHal::initCheck() const {
364 return mInitCheck;
365}
366
367status_t DrmHal::setListener(const sp<IDrmClient>& listener)
368{
369 Mutex::Autolock lock(mEventLock);
370 if (mListener != NULL){
371 IInterface::asBinder(mListener)->unlinkToDeath(this);
372 }
373 if (listener != NULL) {
374 IInterface::asBinder(listener)->linkToDeath(this);
375 }
376 mListener = listener;
377 return NO_ERROR;
378}
379
380Return<void> DrmHal::sendEvent(EventType hEventType,
381 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800382 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800383
384 mEventLock.lock();
385 sp<IDrmClient> listener = mListener;
386 mEventLock.unlock();
387
388 if (listener != NULL) {
389 Parcel obj;
390 writeByteArray(obj, sessionId);
391 writeByteArray(obj, data);
392
393 Mutex::Autolock lock(mNotifyLock);
394 DrmPlugin::EventType eventType;
395 switch(hEventType) {
396 case EventType::PROVISION_REQUIRED:
397 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
398 break;
399 case EventType::KEY_NEEDED:
400 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
401 break;
402 case EventType::KEY_EXPIRED:
403 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
404 break;
405 case EventType::VENDOR_DEFINED:
406 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
407 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700408 case EventType::SESSION_RECLAIMED:
409 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
410 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800411 default:
412 return Void();
413 }
414 listener->notify(eventType, 0, &obj);
415 }
416 return Void();
417}
418
419Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
420 int64_t expiryTimeInMS) {
421
422 mEventLock.lock();
423 sp<IDrmClient> listener = mListener;
424 mEventLock.unlock();
425
426 if (listener != NULL) {
427 Parcel obj;
428 writeByteArray(obj, sessionId);
429 obj.writeInt64(expiryTimeInMS);
430
431 Mutex::Autolock lock(mNotifyLock);
432 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
433 }
434 return Void();
435}
436
437Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
438 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
439
440 mEventLock.lock();
441 sp<IDrmClient> listener = mListener;
442 mEventLock.unlock();
443
444 if (listener != NULL) {
445 Parcel obj;
446 writeByteArray(obj, sessionId);
447
448 size_t nKeys = keyStatusList.size();
449 obj.writeInt32(nKeys);
450 for (size_t i = 0; i < nKeys; ++i) {
451 const KeyStatus &keyStatus = keyStatusList[i];
452 writeByteArray(obj, keyStatus.keyId);
453 uint32_t type;
454 switch(keyStatus.type) {
455 case KeyStatusType::USABLE:
456 type = DrmPlugin::kKeyStatusType_Usable;
457 break;
458 case KeyStatusType::EXPIRED:
459 type = DrmPlugin::kKeyStatusType_Expired;
460 break;
461 case KeyStatusType::OUTPUTNOTALLOWED:
462 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
463 break;
464 case KeyStatusType::STATUSPENDING:
465 type = DrmPlugin::kKeyStatusType_StatusPending;
466 break;
467 case KeyStatusType::INTERNALERROR:
468 default:
469 type = DrmPlugin::kKeyStatusType_InternalError;
470 break;
471 }
472 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800473 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800474 }
475 obj.writeInt32(hasNewUsableKey);
476
477 Mutex::Autolock lock(mNotifyLock);
478 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800479 } else {
480 // There's no listener. But we still want to count the key change
481 // events.
482 size_t nKeys = keyStatusList.size();
483 for (size_t i = 0; i < nKeys; i++) {
484 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
485 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800486 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800487
Jeff Tinkera53d6552017-01-20 00:31:46 -0800488 return Void();
489}
490
491bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
492 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800493
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800494 for (size_t i = 0; i < mFactories.size(); i++) {
495 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
496 if (mimeType != "") {
497 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
498 return true;
499 }
500 } else {
501 return true;
502 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800503 }
504 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800505 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800506}
507
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800508status_t DrmHal::createPlugin(const uint8_t uuid[16],
509 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800510 Mutex::Autolock autoLock(mLock);
511
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800512 for (size_t i = 0; i < mFactories.size(); i++) {
513 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
514 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
Edwin Wong5641aa22018-01-30 17:52:21 -0800515 if (mPlugin != NULL) {
516 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
517 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800518 }
519 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800520
521 if (mPlugin == NULL) {
522 mInitCheck = ERROR_UNSUPPORTED;
523 } else {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700524 if (!mPlugin->setListener(this).isOk()) {
525 mInitCheck = DEAD_OBJECT;
526 } else {
527 mInitCheck = OK;
528 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800529 }
530
531 return mInitCheck;
532}
533
534status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800535 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800536 return OK;
537}
538
Jeff Tinker41d279a2018-02-11 19:52:08 +0000539status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
540 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800541 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800542 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800543
Jeff Tinker41d279a2018-02-11 19:52:08 +0000544 SecurityLevel hSecurityLevel;
545 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000546
Jeff Tinker41d279a2018-02-11 19:52:08 +0000547 switch(level) {
548 case DrmPlugin::kSecurityLevelSwSecureCrypto:
549 hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
550 break;
551 case DrmPlugin::kSecurityLevelSwSecureDecode:
552 hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
553 break;
554 case DrmPlugin::kSecurityLevelHwSecureCrypto:
555 hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
556 break;
557 case DrmPlugin::kSecurityLevelHwSecureDecode:
558 hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
559 break;
560 case DrmPlugin::kSecurityLevelHwSecureAll:
561 hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
562 break;
563 case DrmPlugin::kSecurityLevelMax:
564 setSecurityLevel = false;
565 break;
566 default:
567 return ERROR_DRM_CANNOT_HANDLE;
568 }
569
570 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800571 bool retry = true;
572 do {
573 hidl_vec<uint8_t> hSessionId;
574
Jeff Tinker41d279a2018-02-11 19:52:08 +0000575 Return<void> hResult;
576 if (mPluginV1_1 == NULL || !setSecurityLevel) {
577 hResult = mPlugin->openSession(
578 [&](Status status,const hidl_vec<uint8_t>& id) {
579 if (status == Status::OK) {
580 sessionId = toVector(id);
581 }
582 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000584 );
585 } else {
586 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
587 [&](Status status, const hidl_vec<uint8_t>& id) {
588 if (status == Status::OK) {
589 sessionId = toVector(id);
590 }
591 err = toStatusT(status);
592 }
593 );
594 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800595
596 if (!hResult.isOk()) {
597 err = DEAD_OBJECT;
598 }
599
600 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
601 mLock.unlock();
602 // reclaimSession may call back to closeSession, since mLock is
603 // shared between Drm instances, we should unlock here to avoid
604 // deadlock.
605 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
606 mLock.lock();
607 } else {
608 retry = false;
609 }
610 } while (retry);
611
612 if (err == OK) {
613 DrmSessionManager::Instance()->addSession(getCallingPid(),
614 mDrmSessionClient, sessionId);
Jeff Tinker61332812017-05-15 16:53:10 -0700615 mOpenSessions.push(sessionId);
Adam Stone568b3c42018-01-31 12:57:16 -0800616 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800617 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800618
Adam Stonef0e618d2018-01-17 19:20:41 -0800619 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800620 return err;
621}
622
623status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
624 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800625 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800626
Jeff Tinker319d5f42017-07-26 15:44:33 -0700627 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
628 if (status.isOk()) {
629 if (status == Status::OK) {
630 DrmSessionManager::Instance()->removeSession(sessionId);
631 for (size_t i = 0; i < mOpenSessions.size(); i++) {
632 if (mOpenSessions[i] == sessionId) {
633 mOpenSessions.removeAt(i);
634 break;
635 }
Jeff Tinker61332812017-05-15 16:53:10 -0700636 }
637 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800638 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800639 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800640 mMetrics.mCloseSessionCounter.Increment(response);
641 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800642 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800643 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700644 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800645}
646
647status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
648 Vector<uint8_t> const &initData, String8 const &mimeType,
649 DrmPlugin::KeyType keyType, KeyedVector<String8,
650 String8> const &optionalParameters, Vector<uint8_t> &request,
651 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
652 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800653 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800654 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800655
656 DrmSessionManager::Instance()->useSession(sessionId);
657
658 KeyType hKeyType;
659 if (keyType == DrmPlugin::kKeyType_Streaming) {
660 hKeyType = KeyType::STREAMING;
661 } else if (keyType == DrmPlugin::kKeyType_Offline) {
662 hKeyType = KeyType::OFFLINE;
663 } else if (keyType == DrmPlugin::kKeyType_Release) {
664 hKeyType = KeyType::RELEASE;
665 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800666 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800667 return BAD_VALUE;
668 }
669
670 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
671
672 status_t err = UNKNOWN_ERROR;
673
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800674 if (mPluginV1_1 != NULL) {
675 Return<void> hResult =
676 mPluginV1_1->getKeyRequest_1_1(
677 toHidlVec(sessionId), toHidlVec(initData),
678 toHidlString(mimeType), hKeyType, hOptionalParameters,
679 [&](Status status, const hidl_vec<uint8_t>& hRequest,
680 drm::V1_1::KeyRequestType hKeyRequestType,
681 const hidl_string& hDefaultUrl) {
682
683 if (status == Status::OK) {
684 request = toVector(hRequest);
685 defaultUrl = toString8(hDefaultUrl);
686
687 switch (hKeyRequestType) {
688 case drm::V1_1::KeyRequestType::INITIAL:
689 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
690 break;
691 case drm::V1_1::KeyRequestType::RENEWAL:
692 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
693 break;
694 case drm::V1_1::KeyRequestType::RELEASE:
695 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
696 break;
697 case drm::V1_1::KeyRequestType::NONE:
698 *keyRequestType = DrmPlugin::kKeyRequestType_None;
699 break;
700 case drm::V1_1::KeyRequestType::UPDATE:
701 *keyRequestType = DrmPlugin::kKeyRequestType_Update;
702 break;
703 default:
704 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
705 break;
706 }
707 err = toStatusT(status);
708 }
709 });
710 return hResult.isOk() ? err : DEAD_OBJECT;
711 }
712
Jeff Tinkera53d6552017-01-20 00:31:46 -0800713 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
714 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
715 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800716 drm::V1_0::KeyRequestType hKeyRequestType,
717 const hidl_string& hDefaultUrl) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800718
719 if (status == Status::OK) {
720 request = toVector(hRequest);
721 defaultUrl = toString8(hDefaultUrl);
722
723 switch (hKeyRequestType) {
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800724 case drm::V1_0::KeyRequestType::INITIAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800725 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
726 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800727 case drm::V1_0::KeyRequestType::RENEWAL:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800728 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
729 break;
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800730 case drm::V1_0::KeyRequestType::RELEASE:
Jeff Tinkera53d6552017-01-20 00:31:46 -0800731 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
732 break;
733 default:
734 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
735 break;
736 }
737 err = toStatusT(status);
738 }
739 });
740
Adam Stonef0e618d2018-01-17 19:20:41 -0800741 err = hResult.isOk() ? err : DEAD_OBJECT;
742 keyRequestTimer.SetAttribute(err);
743 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800744}
745
746status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
747 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
748 Mutex::Autolock autoLock(mLock);
Adam Stonefb679e32018-02-07 10:25:48 -0800749 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800750
Jeff Tinker6d998b62017-12-18 14:37:43 -0800751 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800752
753 DrmSessionManager::Instance()->useSession(sessionId);
754
755 status_t err = UNKNOWN_ERROR;
756
757 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
758 toHidlVec(response),
759 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
760 if (status == Status::OK) {
761 keySetId = toVector(hKeySetId);
762 }
763 err = toStatusT(status);
764 }
765 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800766 err = hResult.isOk() ? err : DEAD_OBJECT;
767 keyResponseTimer.SetAttribute(err);
768 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800769}
770
771status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
772 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800773 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800774
Jeff Tinker58ad4752018-02-16 16:51:59 -0800775 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
776 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800777}
778
779status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
780 Vector<uint8_t> const &keySetId) {
781 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800782 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800783
784 DrmSessionManager::Instance()->useSession(sessionId);
785
Jeff Tinker58ad4752018-02-16 16:51:59 -0800786 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
787 toHidlVec(keySetId));
788 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800789}
790
791status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
792 KeyedVector<String8, String8> &infoMap) const {
793 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800794 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800795
796 DrmSessionManager::Instance()->useSession(sessionId);
797
798 ::KeyedVector hInfoMap;
799
800 status_t err = UNKNOWN_ERROR;
801
802 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
803 [&](Status status, const hidl_vec<KeyValue>& map) {
804 if (status == Status::OK) {
805 infoMap = toKeyedVector(map);
806 }
807 err = toStatusT(status);
808 }
809 );
810
811 return hResult.isOk() ? err : DEAD_OBJECT;
812}
813
814status_t DrmHal::getProvisionRequest(String8 const &certType,
815 String8 const &certAuthority, Vector<uint8_t> &request,
816 String8 &defaultUrl) {
817 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800818 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800819
820 status_t err = UNKNOWN_ERROR;
821
822 Return<void> hResult = mPlugin->getProvisionRequest(
823 toHidlString(certType), toHidlString(certAuthority),
824 [&](Status status, const hidl_vec<uint8_t>& hRequest,
825 const hidl_string& hDefaultUrl) {
826 if (status == Status::OK) {
827 request = toVector(hRequest);
828 defaultUrl = toString8(hDefaultUrl);
829 }
830 err = toStatusT(status);
831 }
832 );
833
Adam Stonecea91ce2018-01-22 19:23:28 -0800834 err = hResult.isOk() ? err : DEAD_OBJECT;
835 mMetrics.mGetProvisionRequestCounter.Increment(err);
836 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800837}
838
839status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800840 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800842 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800843
844 status_t err = UNKNOWN_ERROR;
845
846 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
847 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
848 const hidl_vec<uint8_t>& hWrappedKey) {
849 if (status == Status::OK) {
850 certificate = toVector(hCertificate);
851 wrappedKey = toVector(hWrappedKey);
852 }
853 err = toStatusT(status);
854 }
855 );
856
Adam Stonecea91ce2018-01-22 19:23:28 -0800857 err = hResult.isOk() ? err : DEAD_OBJECT;
858 mMetrics.mProvideProvisionResponseCounter.Increment(err);
859 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800860}
861
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800862status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800863 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800864 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800865
866 status_t err = UNKNOWN_ERROR;
867
868 Return<void> hResult = mPlugin->getSecureStops(
869 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
870 if (status == Status::OK) {
871 secureStops = toSecureStops(hSecureStops);
872 }
873 err = toStatusT(status);
874 }
875 );
876
877 return hResult.isOk() ? err : DEAD_OBJECT;
878}
879
880
Jeff Tinker15177d72018-01-25 12:57:55 -0800881status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
882 Mutex::Autolock autoLock(mLock);
883
884 if (mInitCheck != OK) {
885 return mInitCheck;
886 }
887
888 if (mPluginV1_1 == NULL) {
889 return ERROR_DRM_CANNOT_HANDLE;
890 }
891
892 status_t err = UNKNOWN_ERROR;
893
894 Return<void> hResult = mPluginV1_1->getSecureStopIds(
895 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
896 if (status == Status::OK) {
897 secureStopIds = toSecureStopIds(hSecureStopIds);
898 }
899 err = toStatusT(status);
900 }
901 );
902
903 return hResult.isOk() ? err : DEAD_OBJECT;
904}
905
906
Jeff Tinkera53d6552017-01-20 00:31:46 -0800907status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
908 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800909 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800910
911 status_t err = UNKNOWN_ERROR;
912
913 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
914 [&](Status status, const SecureStop& hSecureStop) {
915 if (status == Status::OK) {
916 secureStop = toVector(hSecureStop.opaqueData);
917 }
918 err = toStatusT(status);
919 }
920 );
921
922 return hResult.isOk() ? err : DEAD_OBJECT;
923}
924
925status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
926 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800927 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800928
Jeff Tinker58ad4752018-02-16 16:51:59 -0800929 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -0800930 if (mPluginV1_1 != NULL) {
931 SecureStopRelease secureStopRelease;
932 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -0800933 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
934 } else {
935 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -0800936 }
Jeff Tinker58ad4752018-02-16 16:51:59 -0800937 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800938}
939
Jeff Tinker15177d72018-01-25 12:57:55 -0800940status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
941 Mutex::Autolock autoLock(mLock);
942
943 if (mInitCheck != OK) {
944 return mInitCheck;
945 }
946
947 if (mPluginV1_1 == NULL) {
948 return ERROR_DRM_CANNOT_HANDLE;
949 }
950
Jeff Tinker58ad4752018-02-16 16:51:59 -0800951 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
952 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -0800953}
954
955status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800956 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800957 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800958
Jeff Tinker58ad4752018-02-16 16:51:59 -0800959 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -0800960 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -0800961 status = mPluginV1_1->removeAllSecureStops();
962 } else {
963 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -0800964 }
Jeff Tinker58ad4752018-02-16 16:51:59 -0800965 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800966}
967
Jeff Tinker6d998b62017-12-18 14:37:43 -0800968status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
969 DrmPlugin::HdcpLevel *max) const {
970 Mutex::Autolock autoLock(mLock);
971 INIT_CHECK();
972
973 if (connected == NULL || max == NULL) {
974 return BAD_VALUE;
975 }
976 status_t err = UNKNOWN_ERROR;
977
978 if (mPluginV1_1 == NULL) {
979 return ERROR_DRM_CANNOT_HANDLE;
980 }
981
982 *connected = DrmPlugin::kHdcpLevelUnknown;
983 *max = DrmPlugin::kHdcpLevelUnknown;
984
985 Return<void> hResult = mPluginV1_1->getHdcpLevels(
986 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
987 if (status == Status::OK) {
988 *connected = toHdcpLevel(hConnected);
989 *max = toHdcpLevel(hMax);
990 }
991 err = toStatusT(status);
992 }
993 );
994
995 return hResult.isOk() ? err : DEAD_OBJECT;
996}
997
998status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
999 Mutex::Autolock autoLock(mLock);
1000 INIT_CHECK();
1001
1002 if (open == NULL || max == NULL) {
1003 return BAD_VALUE;
1004 }
1005 status_t err = UNKNOWN_ERROR;
1006
1007 *open = 0;
1008 *max = 0;
1009
1010 if (mPluginV1_1 == NULL) {
1011 return ERROR_DRM_CANNOT_HANDLE;
1012 }
1013
1014 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1015 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1016 if (status == Status::OK) {
1017 *open = hOpen;
1018 *max = hMax;
1019 }
1020 err = toStatusT(status);
1021 }
1022 );
1023
1024 return hResult.isOk() ? err : DEAD_OBJECT;
1025}
1026
1027status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1028 DrmPlugin::SecurityLevel *level) const {
1029 Mutex::Autolock autoLock(mLock);
1030 INIT_CHECK();
1031
1032 if (level == NULL) {
1033 return BAD_VALUE;
1034 }
1035 status_t err = UNKNOWN_ERROR;
1036
1037 if (mPluginV1_1 == NULL) {
1038 return ERROR_DRM_CANNOT_HANDLE;
1039 }
1040
1041 *level = DrmPlugin::kSecurityLevelUnknown;
1042
1043 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1044 [&](Status status, SecurityLevel hLevel) {
1045 if (status == Status::OK) {
1046 *level = toSecurityLevel(hLevel);
1047 }
1048 err = toStatusT(status);
1049 }
1050 );
1051
1052 return hResult.isOk() ? err : DEAD_OBJECT;
1053}
1054
Jeff Tinkera53d6552017-01-20 00:31:46 -08001055status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1056 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001057 return getPropertyStringInternal(name, value);
1058}
1059
1060status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1061 // This function is internal to the class and should only be called while
1062 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001063 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001064
1065 status_t err = UNKNOWN_ERROR;
1066
1067 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1068 [&](Status status, const hidl_string& hValue) {
1069 if (status == Status::OK) {
1070 value = toString8(hValue);
1071 }
1072 err = toStatusT(status);
1073 }
1074 );
1075
1076 return hResult.isOk() ? err : DEAD_OBJECT;
1077}
1078
1079status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1080 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001081 return getPropertyByteArrayInternal(name, value);
1082}
1083
1084status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1085 // This function is internal to the class and should only be called while
1086 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001087 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001088
1089 status_t err = UNKNOWN_ERROR;
1090
1091 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1092 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1093 if (status == Status::OK) {
1094 value = toVector(hValue);
1095 }
1096 err = toStatusT(status);
1097 }
1098 );
1099
Adam Stonecea91ce2018-01-22 19:23:28 -08001100 err = hResult.isOk() ? err : DEAD_OBJECT;
1101 if (name == kPropertyDeviceUniqueId) {
1102 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1103 }
1104 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001105}
1106
1107status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1108 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001109 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001110
Jeff Tinker58ad4752018-02-16 16:51:59 -08001111 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001112 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001113 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001114}
1115
1116status_t DrmHal::setPropertyByteArray(String8 const &name,
1117 Vector<uint8_t> const &value ) const {
1118 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001119 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001120
Jeff Tinker58ad4752018-02-16 16:51:59 -08001121 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001122 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001123 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001124}
1125
Adam Stone28f27c32018-02-05 15:07:48 -08001126status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1127 if (metrics == nullptr) {
1128 return UNEXPECTED_NULL;
1129 }
1130 mMetrics.Export(metrics);
1131
1132 // Append vendor metrics if they are supported.
1133 if (mPluginV1_1 != NULL) {
1134 String8 vendor;
1135 String8 description;
1136 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1137 || vendor.isEmpty()) {
1138 ALOGE("Get vendor failed or is empty");
1139 vendor = "NONE";
1140 }
1141 if (getPropertyStringInternal(String8("description"), description) != OK
1142 || description.isEmpty()) {
1143 ALOGE("Get description failed or is empty.");
1144 description = "NONE";
1145 }
1146 vendor += ".";
1147 vendor += description;
1148
1149 hidl_vec<DrmMetricGroup> pluginMetrics;
1150 status_t err = UNKNOWN_ERROR;
1151
1152 Return<void> status = mPluginV1_1->getMetrics(
1153 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1154 if (status != Status::OK) {
1155 ALOGV("Error getting plugin metrics: %d", status);
1156 } else {
1157 PersistableBundle pluginBundle;
1158 if (MediaDrmMetrics::HidlMetricsToBundle(
1159 pluginMetrics, &pluginBundle) == OK) {
1160 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1161 }
1162 }
1163 err = toStatusT(status);
1164 });
1165 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001166 }
1167
Adam Stoneab394d12017-12-22 12:34:20 -08001168 return OK;
1169}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001170
1171status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1172 String8 const &algorithm) {
1173 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001174 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001175
1176 DrmSessionManager::Instance()->useSession(sessionId);
1177
1178 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
1179 toHidlString(algorithm));
1180 return toStatusT(status);
1181}
1182
1183status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1184 String8 const &algorithm) {
1185 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001186 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001187
1188 DrmSessionManager::Instance()->useSession(sessionId);
1189
1190 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
1191 toHidlString(algorithm));
1192 return toStatusT(status);
1193}
1194
1195status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001196 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1197 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001198 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001199 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001200
1201 DrmSessionManager::Instance()->useSession(sessionId);
1202
1203 status_t err = UNKNOWN_ERROR;
1204
1205 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1206 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1207 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1208 if (status == Status::OK) {
1209 output = toVector(hOutput);
1210 }
1211 err = toStatusT(status);
1212 }
1213 );
1214
1215 return hResult.isOk() ? err : DEAD_OBJECT;
1216}
1217
1218status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001219 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1220 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001221 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001222 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001223
1224 DrmSessionManager::Instance()->useSession(sessionId);
1225
1226 status_t err = UNKNOWN_ERROR;
1227
1228 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1229 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1230 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1231 if (status == Status::OK) {
1232 output = toVector(hOutput);
1233 }
1234 err = toStatusT(status);
1235 }
1236 );
1237
1238 return hResult.isOk() ? err : DEAD_OBJECT;
1239}
1240
1241status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001242 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1243 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001244 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001245 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001246
1247 DrmSessionManager::Instance()->useSession(sessionId);
1248
1249 status_t err = UNKNOWN_ERROR;
1250
1251 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1252 toHidlVec(keyId), toHidlVec(message),
1253 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1254 if (status == Status::OK) {
1255 signature = toVector(hSignature);
1256 }
1257 err = toStatusT(status);
1258 }
1259 );
1260
1261 return hResult.isOk() ? err : DEAD_OBJECT;
1262}
1263
1264status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001265 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1266 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001267 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001268 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001269
1270 DrmSessionManager::Instance()->useSession(sessionId);
1271
1272 status_t err = UNKNOWN_ERROR;
1273
1274 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1275 toHidlVec(message), toHidlVec(signature),
1276 [&](Status status, bool hMatch) {
1277 if (status == Status::OK) {
1278 match = hMatch;
1279 } else {
1280 match = false;
1281 }
1282 err = toStatusT(status);
1283 }
1284 );
1285
1286 return hResult.isOk() ? err : DEAD_OBJECT;
1287}
1288
1289status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001290 String8 const &algorithm, Vector<uint8_t> const &message,
1291 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001292 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001293 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001294
1295 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1296 return -EPERM;
1297 }
1298
1299 DrmSessionManager::Instance()->useSession(sessionId);
1300
1301 status_t err = UNKNOWN_ERROR;
1302
1303 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1304 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1305 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1306 if (status == Status::OK) {
1307 signature = toVector(hSignature);
1308 }
1309 err = toStatusT(status);
1310 }
1311 );
1312
1313 return hResult.isOk() ? err : DEAD_OBJECT;
1314}
1315
1316void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1317{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001318 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001319}
1320
1321void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1322{
1323 if (vec.size()) {
1324 obj.writeInt32(vec.size());
1325 obj.write(vec.data(), vec.size());
1326 } else {
1327 obj.writeInt32(0);
1328 }
1329}
1330
Adam Stonefb679e32018-02-07 10:25:48 -08001331void DrmHal::reportFrameworkMetrics() const
1332{
1333 MediaAnalyticsItem item("mediadrm");
1334 item.generateSessionID();
1335 item.setPkgName(mMetrics.GetAppPackageName().c_str());
1336 String8 vendor;
1337 String8 description;
1338 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1339 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001340 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001341 } else {
1342 item.setCString("vendor", vendor.c_str());
1343 }
1344 result = getPropertyStringInternal(String8("description"), description);
1345 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001346 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001347 } else {
1348 item.setCString("description", description.c_str());
1349 }
Adam Stoneab394d12017-12-22 12:34:20 -08001350
Adam Stonefb679e32018-02-07 10:25:48 -08001351 std::string serializedMetrics;
1352 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1353 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001354 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001355 }
Jeff Tinker987ac702018-02-15 17:02:22 -08001356 serializedMetrics = toHexString(serializedMetrics);
Adam Stonefb679e32018-02-07 10:25:48 -08001357 if (!serializedMetrics.empty()) {
1358 item.setCString("serialized_metrics", serializedMetrics.c_str());
1359 }
1360 if (!item.selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001361 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001362 }
1363}
1364
1365void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001366{
1367 Vector<uint8_t> metrics;
1368 String8 vendor;
1369 String8 description;
1370 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1371 getPropertyStringInternal(String8("description"), description) == OK &&
1372 getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
1373 status_t res = android::reportDrmPluginMetrics(
1374 metrics, vendor, description);
1375 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001376 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001377 }
1378 }
1379}
1380
Jeff Tinkera53d6552017-01-20 00:31:46 -08001381} // namespace android