blob: bc207f3e48a250d15c1cf19c0020cd89a966091a [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 Tinkerc8baaba2018-10-23 11:32:36 -070026#include <android/hardware/drm/1.2/types.h>
Peter Kalauskasca5642c2018-11-12 12:34:42 -080027#include <android/hidl/manager/1.2/IServiceManager.h>
Chong Zhang181e6952019-10-09 13:23:39 -070028#include <android/media/BnResourceManagerClient.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070029#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080030#include <media/EventMetric.h>
Robert Shih82ea6be2019-11-07 17:47:23 -080031#include <media/MediaMetrics.h>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070032#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080033#include <media/drm/DrmAPI.h>
34#include <media/stagefright/foundation/ADebug.h>
35#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080036#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080037#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080039#include <mediadrm/DrmHal.h>
40#include <mediadrm/DrmSessionClientInterface.h>
41#include <mediadrm/DrmSessionManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080042
Robert Shih61e1c762019-10-31 21:26:58 -070043#include <vector>
44
Jeff Tinker6d998b62017-12-18 14:37:43 -080045using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080046using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080047using drm::V1_0::KeyType;
48using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080049using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080050using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080051using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070052using drm::V1_1::HdcpLevel;
53using drm::V1_1::SecureStopRelease;
54using drm::V1_1::SecurityLevel;
55using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070056using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080057using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080058using ::android::hardware::hidl_array;
59using ::android::hardware::hidl_string;
60using ::android::hardware::hidl_vec;
61using ::android::hardware::Return;
62using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080063using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080064using ::android::sp;
65
Jeff Tinkerb8684f32018-12-12 08:41:31 -080066typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
67typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080068typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080069
Adam Stonecea91ce2018-01-22 19:23:28 -080070namespace {
71
72// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
73// in the MediaDrm API.
74constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080075constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080076
Adam Stone32494f52018-02-26 22:53:27 -080077template<typename T>
78std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070079 // Note that the base 64 conversion only works with arrays of single-byte
80 // values. If the source is empty or is not an array of single-byte values,
81 // return empty string.
82 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080083 return "";
84 }
Adam Stone32494f52018-02-26 22:53:27 -080085
86 android::AString outputString;
87 encodeBase64(data, size, &outputString);
88 // Remove trailing equals padding if it exists.
89 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
90 outputString.erase(outputString.size() - 1, 1);
91 }
92
93 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080094}
95
Adam Stone32494f52018-02-26 22:53:27 -080096} // anonymous namespace
97
Jeff Tinkera53d6552017-01-20 00:31:46 -080098namespace android {
99
Jeff Tinker6d998b62017-12-18 14:37:43 -0800100#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
101
Jeff Tinkera53d6552017-01-20 00:31:46 -0800102static inline int getCallingPid() {
103 return IPCThreadState::self()->getCallingPid();
104}
105
106static bool checkPermission(const char* permissionString) {
107 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
108 bool ok = checkCallingPermission(String16(permissionString));
109 if (!ok) ALOGE("Request requires %s", permissionString);
110 return ok;
111}
112
113static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
114 Vector<uint8_t> vector;
115 vector.appendArray(vec.data(), vec.size());
116 return *const_cast<const Vector<uint8_t> *>(&vector);
117}
118
119static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
120 hidl_vec<uint8_t> vec;
121 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
122 return vec;
123}
124
125static String8 toString8(const hidl_string &string) {
126 return String8(string.c_str());
127}
128
129static hidl_string toHidlString(const String8& string) {
130 return hidl_string(string.string());
131}
132
Jeff Tinker6d998b62017-12-18 14:37:43 -0800133static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
134 switch(level) {
135 case SecurityLevel::SW_SECURE_CRYPTO:
136 return DrmPlugin::kSecurityLevelSwSecureCrypto;
137 case SecurityLevel::SW_SECURE_DECODE:
138 return DrmPlugin::kSecurityLevelSwSecureDecode;
139 case SecurityLevel::HW_SECURE_CRYPTO:
140 return DrmPlugin::kSecurityLevelHwSecureCrypto;
141 case SecurityLevel::HW_SECURE_DECODE:
142 return DrmPlugin::kSecurityLevelHwSecureDecode;
143 case SecurityLevel::HW_SECURE_ALL:
144 return DrmPlugin::kSecurityLevelHwSecureAll;
145 default:
146 return DrmPlugin::kSecurityLevelUnknown;
147 }
148}
149
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800150static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
151 switch(level) {
152 case DrmPlugin::kSecurityLevelSwSecureCrypto:
153 return SecurityLevel::SW_SECURE_CRYPTO;
154 case DrmPlugin::kSecurityLevelSwSecureDecode:
155 return SecurityLevel::SW_SECURE_DECODE;
156 case DrmPlugin::kSecurityLevelHwSecureCrypto:
157 return SecurityLevel::HW_SECURE_CRYPTO;
158 case DrmPlugin::kSecurityLevelHwSecureDecode:
159 return SecurityLevel::HW_SECURE_DECODE;
160 case DrmPlugin::kSecurityLevelHwSecureAll:
161 return SecurityLevel::HW_SECURE_ALL;
162 default:
163 return SecurityLevel::UNKNOWN;
164 }
165}
166
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700167static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
168 OfflineLicenseState licenseState) {
169 switch(licenseState) {
170 case OfflineLicenseState::USABLE:
171 return DrmPlugin::kOfflineLicenseStateUsable;
172 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800173 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700174 default:
175 return DrmPlugin::kOfflineLicenseStateUnknown;
176 }
177}
178
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800179static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800180 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800181 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800182 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800183 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800184 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800185 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800186 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800187 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800188 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800189 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800190 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800191 case HdcpLevel_V1_2::HDCP_V2_3:
192 return DrmPlugin::kHdcpV2_3;
193 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800194 return DrmPlugin::kHdcpNoOutput;
195 default:
196 return DrmPlugin::kHdcpLevelUnknown;
197 }
198}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800199static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
200 keyedVector) {
201 std::vector<KeyValue> stdKeyedVector;
202 for (size_t i = 0; i < keyedVector.size(); i++) {
203 KeyValue keyValue;
204 keyValue.key = toHidlString(keyedVector.keyAt(i));
205 keyValue.value = toHidlString(keyedVector.valueAt(i));
206 stdKeyedVector.push_back(keyValue);
207 }
208 return ::KeyedVector(stdKeyedVector);
209}
210
211static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
212 hKeyedVector) {
213 KeyedVector<String8, String8> keyedVector;
214 for (size_t i = 0; i < hKeyedVector.size(); i++) {
215 keyedVector.add(toString8(hKeyedVector[i].key),
216 toString8(hKeyedVector[i].value));
217 }
218 return keyedVector;
219}
220
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800221static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800222 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800223 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800224 for (size_t i = 0; i < hSecureStops.size(); i++) {
225 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
226 }
227 return secureStops;
228}
229
Jeff Tinker15177d72018-01-25 12:57:55 -0800230static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
231 hSecureStopIds) {
232 List<Vector<uint8_t>> secureStopIds;
233 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
234 secureStopIds.push_back(toVector(hSecureStopIds[i]));
235 }
236 return secureStopIds;
237}
238
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700239static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
240 hKeySetIds) {
241 List<Vector<uint8_t>> keySetIds;
242 for (size_t i = 0; i < hKeySetIds.size(); i++) {
243 keySetIds.push_back(toVector(hKeySetIds[i]));
244 }
245 return keySetIds;
246}
247
Jeff Tinkera53d6552017-01-20 00:31:46 -0800248static status_t toStatusT(Status status) {
249 switch (status) {
250 case Status::OK:
251 return OK;
252 break;
253 case Status::ERROR_DRM_NO_LICENSE:
254 return ERROR_DRM_NO_LICENSE;
255 break;
256 case Status::ERROR_DRM_LICENSE_EXPIRED:
257 return ERROR_DRM_LICENSE_EXPIRED;
258 break;
259 case Status::ERROR_DRM_SESSION_NOT_OPENED:
260 return ERROR_DRM_SESSION_NOT_OPENED;
261 break;
262 case Status::ERROR_DRM_CANNOT_HANDLE:
263 return ERROR_DRM_CANNOT_HANDLE;
264 break;
265 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800266 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800267 break;
268 case Status::BAD_VALUE:
269 return BAD_VALUE;
270 break;
271 case Status::ERROR_DRM_NOT_PROVISIONED:
272 return ERROR_DRM_NOT_PROVISIONED;
273 break;
274 case Status::ERROR_DRM_RESOURCE_BUSY:
275 return ERROR_DRM_RESOURCE_BUSY;
276 break;
277 case Status::ERROR_DRM_DEVICE_REVOKED:
278 return ERROR_DRM_DEVICE_REVOKED;
279 break;
280 case Status::ERROR_DRM_UNKNOWN:
281 default:
282 return ERROR_DRM_UNKNOWN;
283 break;
284 }
285}
286
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800287static status_t toStatusT_1_2(Status_V1_2 status) {
288 switch (status) {
289 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
290 return ERROR_DRM_RESOURCE_CONTENTION;
291 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
292 return ERROR_DRM_FRAME_TOO_LARGE;
293 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
294 return ERROR_DRM_INSUFFICIENT_SECURITY;
295 default:
296 return toStatusT(static_cast<Status>(status));
297 }
298}
299
Jeff Tinkera53d6552017-01-20 00:31:46 -0800300Mutex DrmHal::mLock;
301
Chong Zhang181e6952019-10-09 13:23:39 -0700302struct DrmHal::DrmSessionClient : public android::media::BnResourceManagerClient {
303 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
304 : mSessionId(sessionId),
305 mDrm(drm) {}
306
307 ::android::binder::Status reclaimResource(bool* _aidl_return) override;
308 ::android::binder::Status getName(::std::string* _aidl_return) override;
309
310 const Vector<uint8_t> mSessionId;
311
312protected:
313 virtual ~DrmSessionClient();
314
315private:
316 wp<DrmHal> mDrm;
317
318 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
319};
320
321::android::binder::Status DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700322 sp<DrmHal> drm = mDrm.promote();
323 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700324 *_aidl_return = true;
325 return ::android::binder::Status::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800326 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700327 status_t err = drm->closeSession(mSessionId);
328 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700329 *_aidl_return = false;
330 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700331 }
332 drm->sendEvent(EventType::SESSION_RECLAIMED,
333 toHidlVec(mSessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700334 *_aidl_return = true;
335 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700336}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800337
Chong Zhang181e6952019-10-09 13:23:39 -0700338::android::binder::Status DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700339 String8 name;
340 sp<DrmHal> drm = mDrm.promote();
341 if (drm == NULL) {
342 name.append("<deleted>");
343 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
344 || name.isEmpty()) {
345 name.append("<Get vendor failed or is empty>");
346 }
347 name.append("[");
348 for (size_t i = 0; i < mSessionId.size(); ++i) {
349 name.appendFormat("%02x", mSessionId[i]);
350 }
351 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700352 *_aidl_return = name;
353 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700354}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800355
Robert Shihc3af31b2019-09-20 21:45:01 -0700356DrmHal::DrmSessionClient::~DrmSessionClient() {
357 DrmSessionManager::Instance()->removeSession(mSessionId);
358}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800359
360DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700361 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800362 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800363}
364
Jeff Tinker61332812017-05-15 16:53:10 -0700365void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800366 Mutex::Autolock autoLock(mLock);
367 auto openSessions = mOpenSessions;
368 for (size_t i = 0; i < openSessions.size(); i++) {
369 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700370 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800371 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700372 }
373 mOpenSessions.clear();
374}
375
Jeff Tinkera53d6552017-01-20 00:31:46 -0800376DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800377}
378
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800379void DrmHal::cleanup() {
380 closeOpenSessions();
381
382 Mutex::Autolock autoLock(mLock);
383 reportPluginMetrics();
384 reportFrameworkMetrics();
385
386 setListener(NULL);
387 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800388 if (mPluginV1_2 != NULL) {
389 if (!mPluginV1_2->setListener(NULL).isOk()) {
390 mInitCheck = DEAD_OBJECT;
391 }
392 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800393 if (!mPlugin->setListener(NULL).isOk()) {
394 mInitCheck = DEAD_OBJECT;
395 }
396 }
397 mPlugin.clear();
398 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700399 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800400}
401
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800402Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
403 Vector<sp<IDrmFactory>> factories;
404
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800405 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800406
407 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800408 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800409 [&factories](const hidl_vec<hidl_string> &registered) {
410 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000411 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800412 if (factory != NULL) {
413 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000414 }
415 }
416 }
417 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800418 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000419 [&factories](const hidl_vec<hidl_string> &registered) {
420 for (const auto &instance : registered) {
421 auto factory = drm::V1_1::IDrmFactory::getService(instance);
422 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000423 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800424 }
425 }
426 }
427 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700428 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700429 [&factories](const hidl_vec<hidl_string> &registered) {
430 for (const auto &instance : registered) {
431 auto factory = drm::V1_2::IDrmFactory::getService(instance);
432 if (factory != NULL) {
433 factories.push_back(factory);
434 }
435 }
436 }
437 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800438 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800439
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800440 if (factories.size() == 0) {
441 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700442 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800443 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000444 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800445 factories.push_back(passthrough);
446 } else {
447 ALOGE("Failed to find any drm factories");
448 }
449 }
450 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800451}
452
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800453sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
454 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800455 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800456 mMetrics.SetAppPackageName(appPackageName);
Robert Shih82ea6be2019-11-07 17:47:23 -0800457 mMetrics.SetAppUid(IPCThreadState::self()->getCallingUid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800458
459 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800460 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800461 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800462 if (status != Status::OK) {
463 ALOGE("Failed to make drm plugin");
464 return;
465 }
466 plugin = hPlugin;
467 }
468 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700469
470 if (!hResult.isOk()) {
471 ALOGE("createPlugin remote call failed");
472 }
473
Jeff Tinkera53d6552017-01-20 00:31:46 -0800474 return plugin;
475}
476
477status_t DrmHal::initCheck() const {
478 return mInitCheck;
479}
480
481status_t DrmHal::setListener(const sp<IDrmClient>& listener)
482{
483 Mutex::Autolock lock(mEventLock);
484 if (mListener != NULL){
485 IInterface::asBinder(mListener)->unlinkToDeath(this);
486 }
487 if (listener != NULL) {
488 IInterface::asBinder(listener)->linkToDeath(this);
489 }
490 mListener = listener;
491 return NO_ERROR;
492}
493
494Return<void> DrmHal::sendEvent(EventType hEventType,
495 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800496 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800497
498 mEventLock.lock();
499 sp<IDrmClient> listener = mListener;
500 mEventLock.unlock();
501
502 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800503 Mutex::Autolock lock(mNotifyLock);
504 DrmPlugin::EventType eventType;
505 switch(hEventType) {
506 case EventType::PROVISION_REQUIRED:
507 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
508 break;
509 case EventType::KEY_NEEDED:
510 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
511 break;
512 case EventType::KEY_EXPIRED:
513 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
514 break;
515 case EventType::VENDOR_DEFINED:
516 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
517 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700518 case EventType::SESSION_RECLAIMED:
519 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
520 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800521 default:
522 return Void();
523 }
Robert Shih61e1c762019-10-31 21:26:58 -0700524 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800525 }
526 return Void();
527}
528
529Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
530 int64_t expiryTimeInMS) {
531
532 mEventLock.lock();
533 sp<IDrmClient> listener = mListener;
534 mEventLock.unlock();
535
536 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800537 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700538 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800539 }
540 return Void();
541}
542
543Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700544 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
545 std::vector<KeyStatus> keyStatusVec;
546 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
547 keyStatusVec.push_back({keyStatus_V1_0.keyId,
548 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
549 }
550 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
551 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
552}
553
554Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700555 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800556
557 mEventLock.lock();
558 sp<IDrmClient> listener = mListener;
559 mEventLock.unlock();
560
561 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700562 std::vector<DrmKeyStatus> keyStatusList;
563 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800564 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700565 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800566 uint32_t type;
567 switch(keyStatus.type) {
568 case KeyStatusType::USABLE:
569 type = DrmPlugin::kKeyStatusType_Usable;
570 break;
571 case KeyStatusType::EXPIRED:
572 type = DrmPlugin::kKeyStatusType_Expired;
573 break;
574 case KeyStatusType::OUTPUTNOTALLOWED:
575 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
576 break;
577 case KeyStatusType::STATUSPENDING:
578 type = DrmPlugin::kKeyStatusType_StatusPending;
579 break;
Robert Shiha5033262019-05-06 14:15:12 -0700580 case KeyStatusType::USABLEINFUTURE:
581 type = DrmPlugin::kKeyStatusType_UsableInFuture;
582 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583 case KeyStatusType::INTERNALERROR:
584 default:
585 type = DrmPlugin::kKeyStatusType_InternalError;
586 break;
587 }
Robert Shih61e1c762019-10-31 21:26:58 -0700588 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800589 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800590 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800591
592 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700593 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800594 } else {
595 // There's no listener. But we still want to count the key change
596 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700597 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800598 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700599 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800600 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800601 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800602
Jeff Tinkera53d6552017-01-20 00:31:46 -0800603 return Void();
604}
605
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800606Return<void> DrmHal::sendSessionLostState(
607 const hidl_vec<uint8_t>& sessionId) {
608
609 mEventLock.lock();
610 sp<IDrmClient> listener = mListener;
611 mEventLock.unlock();
612
613 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800614 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700615 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800616 }
617 return Void();
618}
619
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800620status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
621 const uint8_t uuid[16],
622 const String8 &mimeType,
623 DrmPlugin::SecurityLevel level,
624 bool *isSupported) {
625 *isSupported = false;
626
627 // handle default value cases
628 if (level == DrmPlugin::kSecurityLevelUnknown) {
629 if (mimeType == "") {
630 // isCryptoSchemeSupported(uuid)
631 *isSupported = true;
632 } else {
633 // isCryptoSchemeSupported(uuid, mimeType)
634 *isSupported = factory->isContentTypeSupported(mimeType.string());
635 }
636 return OK;
637 } else if (mimeType == "") {
638 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800639 }
640
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800641 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
642 if (factoryV1_2 == NULL) {
643 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800644 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800645 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
646 mimeType.string(), toHidlSecurityLevel(level));
647 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800648 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800649}
650
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800651status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
652 const String8 &mimeType,
653 DrmPlugin::SecurityLevel level,
654 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800655 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800656 *isSupported = false;
657 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
658 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
659 return matchMimeTypeAndSecurityLevel(mFactories[i],
660 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800661 }
662 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800663 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800664}
665
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800666status_t DrmHal::createPlugin(const uint8_t uuid[16],
667 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800668 Mutex::Autolock autoLock(mLock);
669
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800670 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800671 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800672 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
673 if (plugin != NULL) {
674 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800675 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700676 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800677 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800678 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800679 }
680 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800681
682 if (mPlugin == NULL) {
683 mInitCheck = ERROR_UNSUPPORTED;
684 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800685 mInitCheck = OK;
686 if (mPluginV1_2 != NULL) {
687 if (!mPluginV1_2->setListener(this).isOk()) {
688 mInitCheck = DEAD_OBJECT;
689 }
690 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700691 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800692 }
693 if (mInitCheck != OK) {
694 mPlugin.clear();
695 mPluginV1_1.clear();
696 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700697 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800698 }
699
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800700
Jeff Tinkera53d6552017-01-20 00:31:46 -0800701 return mInitCheck;
702}
703
704status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800705 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800706 return OK;
707}
708
Jeff Tinker41d279a2018-02-11 19:52:08 +0000709status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
710 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800711 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800712 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800713
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800714 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000715 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000716
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800717 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000718 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800719 } else {
720 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
721 return ERROR_DRM_CANNOT_HANDLE;
722 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000723 }
724
725 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800726 bool retry = true;
727 do {
728 hidl_vec<uint8_t> hSessionId;
729
Jeff Tinker41d279a2018-02-11 19:52:08 +0000730 Return<void> hResult;
731 if (mPluginV1_1 == NULL || !setSecurityLevel) {
732 hResult = mPlugin->openSession(
733 [&](Status status,const hidl_vec<uint8_t>& id) {
734 if (status == Status::OK) {
735 sessionId = toVector(id);
736 }
737 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800738 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000739 );
740 } else {
741 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
742 [&](Status status, const hidl_vec<uint8_t>& id) {
743 if (status == Status::OK) {
744 sessionId = toVector(id);
745 }
746 err = toStatusT(status);
747 }
748 );
749 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800750
751 if (!hResult.isOk()) {
752 err = DEAD_OBJECT;
753 }
754
755 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
756 mLock.unlock();
757 // reclaimSession may call back to closeSession, since mLock is
758 // shared between Drm instances, we should unlock here to avoid
759 // deadlock.
760 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
761 mLock.lock();
762 } else {
763 retry = false;
764 }
765 } while (retry);
766
767 if (err == OK) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700768 sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
769 DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
770 mOpenSessions.push(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800771 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800772 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800773
Adam Stonef0e618d2018-01-17 19:20:41 -0800774 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800775 return err;
776}
777
778status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
779 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800780 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800781
Jeff Tinker319d5f42017-07-26 15:44:33 -0700782 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
783 if (status.isOk()) {
784 if (status == Status::OK) {
785 DrmSessionManager::Instance()->removeSession(sessionId);
786 for (size_t i = 0; i < mOpenSessions.size(); i++) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700787 if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700788 mOpenSessions.removeAt(i);
789 break;
790 }
Jeff Tinker61332812017-05-15 16:53:10 -0700791 }
792 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800793 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800794 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800795 mMetrics.mCloseSessionCounter.Increment(response);
796 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800797 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800798 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700799 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800800}
801
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800802static DrmPlugin::KeyRequestType toKeyRequestType(
803 KeyRequestType keyRequestType) {
804 switch (keyRequestType) {
805 case KeyRequestType::INITIAL:
806 return DrmPlugin::kKeyRequestType_Initial;
807 break;
808 case KeyRequestType::RENEWAL:
809 return DrmPlugin::kKeyRequestType_Renewal;
810 break;
811 case KeyRequestType::RELEASE:
812 return DrmPlugin::kKeyRequestType_Release;
813 break;
814 default:
815 return DrmPlugin::kKeyRequestType_Unknown;
816 break;
817 }
818}
819
820static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
821 KeyRequestType_V1_1 keyRequestType) {
822 switch (keyRequestType) {
823 case KeyRequestType_V1_1::NONE:
824 return DrmPlugin::kKeyRequestType_None;
825 break;
826 case KeyRequestType_V1_1::UPDATE:
827 return DrmPlugin::kKeyRequestType_Update;
828 break;
829 default:
830 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
831 break;
832 }
833}
834
Jeff Tinkera53d6552017-01-20 00:31:46 -0800835status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
836 Vector<uint8_t> const &initData, String8 const &mimeType,
837 DrmPlugin::KeyType keyType, KeyedVector<String8,
838 String8> const &optionalParameters, Vector<uint8_t> &request,
839 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
840 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800841 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800842 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800843
844 DrmSessionManager::Instance()->useSession(sessionId);
845
846 KeyType hKeyType;
847 if (keyType == DrmPlugin::kKeyType_Streaming) {
848 hKeyType = KeyType::STREAMING;
849 } else if (keyType == DrmPlugin::kKeyType_Offline) {
850 hKeyType = KeyType::OFFLINE;
851 } else if (keyType == DrmPlugin::kKeyType_Release) {
852 hKeyType = KeyType::RELEASE;
853 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800854 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800855 return BAD_VALUE;
856 }
857
858 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
859
860 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800861 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800862
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800863 if (mPluginV1_2 != NULL) {
864 hResult = mPluginV1_2->getKeyRequest_1_2(
865 toHidlVec(sessionId), toHidlVec(initData),
866 toHidlString(mimeType), hKeyType, hOptionalParameters,
867 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
868 KeyRequestType_V1_1 hKeyRequestType,
869 const hidl_string& hDefaultUrl) {
870 if (status == Status_V1_2::OK) {
871 request = toVector(hRequest);
872 defaultUrl = toString8(hDefaultUrl);
873 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
874 }
875 err = toStatusT_1_2(status);
876 });
877 } else if (mPluginV1_1 != NULL) {
878 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800879 toHidlVec(sessionId), toHidlVec(initData),
880 toHidlString(mimeType), hKeyType, hOptionalParameters,
881 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800882 KeyRequestType_V1_1 hKeyRequestType,
883 const hidl_string& hDefaultUrl) {
884 if (status == Status::OK) {
885 request = toVector(hRequest);
886 defaultUrl = toString8(hDefaultUrl);
887 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800888 }
889 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800890 });
891 } else {
892 hResult = mPlugin->getKeyRequest(
893 toHidlVec(sessionId), toHidlVec(initData),
894 toHidlString(mimeType), hKeyType, hOptionalParameters,
895 [&](Status status, const hidl_vec<uint8_t>& hRequest,
896 KeyRequestType hKeyRequestType,
897 const hidl_string& hDefaultUrl) {
898 if (status == Status::OK) {
899 request = toVector(hRequest);
900 defaultUrl = toString8(hDefaultUrl);
901 *keyRequestType = toKeyRequestType(hKeyRequestType);
902 }
903 err = toStatusT(status);
904 });
905 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800906
Adam Stonef0e618d2018-01-17 19:20:41 -0800907 err = hResult.isOk() ? err : DEAD_OBJECT;
908 keyRequestTimer.SetAttribute(err);
909 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800910}
911
912status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
913 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
914 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800915 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700916 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800917
918 DrmSessionManager::Instance()->useSession(sessionId);
919
920 status_t err = UNKNOWN_ERROR;
921
922 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
923 toHidlVec(response),
924 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
925 if (status == Status::OK) {
926 keySetId = toVector(hKeySetId);
927 }
928 err = toStatusT(status);
929 }
930 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800931 err = hResult.isOk() ? err : DEAD_OBJECT;
932 keyResponseTimer.SetAttribute(err);
933 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800934}
935
936status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
937 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800938 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800939
Jeff Tinker58ad4752018-02-16 16:51:59 -0800940 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
941 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800942}
943
944status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
945 Vector<uint8_t> const &keySetId) {
946 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800947 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800948
949 DrmSessionManager::Instance()->useSession(sessionId);
950
Jeff Tinker58ad4752018-02-16 16:51:59 -0800951 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
952 toHidlVec(keySetId));
953 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800954}
955
956status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
957 KeyedVector<String8, String8> &infoMap) const {
958 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800959 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800960
961 DrmSessionManager::Instance()->useSession(sessionId);
962
963 ::KeyedVector hInfoMap;
964
965 status_t err = UNKNOWN_ERROR;
966
967 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
968 [&](Status status, const hidl_vec<KeyValue>& map) {
969 if (status == Status::OK) {
970 infoMap = toKeyedVector(map);
971 }
972 err = toStatusT(status);
973 }
974 );
975
976 return hResult.isOk() ? err : DEAD_OBJECT;
977}
978
979status_t DrmHal::getProvisionRequest(String8 const &certType,
980 String8 const &certAuthority, Vector<uint8_t> &request,
981 String8 &defaultUrl) {
982 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800983 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800984
985 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800986 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800987
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800988 if (mPluginV1_2 != NULL) {
989 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
990 toHidlString(certType), toHidlString(certAuthority),
991 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
992 const hidl_string& hDefaultUrl) {
993 if (status == Status_V1_2::OK) {
994 request = toVector(hRequest);
995 defaultUrl = toString8(hDefaultUrl);
996 }
997 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800998 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800999 );
1000 } else {
1001 Return<void> hResult = mPlugin->getProvisionRequest(
1002 toHidlString(certType), toHidlString(certAuthority),
1003 [&](Status status, const hidl_vec<uint8_t>& hRequest,
1004 const hidl_string& hDefaultUrl) {
1005 if (status == Status::OK) {
1006 request = toVector(hRequest);
1007 defaultUrl = toString8(hDefaultUrl);
1008 }
1009 err = toStatusT(status);
1010 }
1011 );
1012 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001013
Adam Stonecea91ce2018-01-22 19:23:28 -08001014 err = hResult.isOk() ? err : DEAD_OBJECT;
1015 mMetrics.mGetProvisionRequestCounter.Increment(err);
1016 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001017}
1018
1019status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001020 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001021 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001022 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001023
1024 status_t err = UNKNOWN_ERROR;
1025
1026 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1027 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1028 const hidl_vec<uint8_t>& hWrappedKey) {
1029 if (status == Status::OK) {
1030 certificate = toVector(hCertificate);
1031 wrappedKey = toVector(hWrappedKey);
1032 }
1033 err = toStatusT(status);
1034 }
1035 );
1036
Adam Stonecea91ce2018-01-22 19:23:28 -08001037 err = hResult.isOk() ? err : DEAD_OBJECT;
1038 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1039 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001040}
1041
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001042status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001043 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001044 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001045
1046 status_t err = UNKNOWN_ERROR;
1047
1048 Return<void> hResult = mPlugin->getSecureStops(
1049 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1050 if (status == Status::OK) {
1051 secureStops = toSecureStops(hSecureStops);
1052 }
1053 err = toStatusT(status);
1054 }
1055 );
1056
1057 return hResult.isOk() ? err : DEAD_OBJECT;
1058}
1059
1060
Jeff Tinker15177d72018-01-25 12:57:55 -08001061status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1062 Mutex::Autolock autoLock(mLock);
1063
1064 if (mInitCheck != OK) {
1065 return mInitCheck;
1066 }
1067
1068 if (mPluginV1_1 == NULL) {
1069 return ERROR_DRM_CANNOT_HANDLE;
1070 }
1071
1072 status_t err = UNKNOWN_ERROR;
1073
1074 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1075 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1076 if (status == Status::OK) {
1077 secureStopIds = toSecureStopIds(hSecureStopIds);
1078 }
1079 err = toStatusT(status);
1080 }
1081 );
1082
1083 return hResult.isOk() ? err : DEAD_OBJECT;
1084}
1085
1086
Jeff Tinkera53d6552017-01-20 00:31:46 -08001087status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1088 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001089 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001090
1091 status_t err = UNKNOWN_ERROR;
1092
1093 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1094 [&](Status status, const SecureStop& hSecureStop) {
1095 if (status == Status::OK) {
1096 secureStop = toVector(hSecureStop.opaqueData);
1097 }
1098 err = toStatusT(status);
1099 }
1100 );
1101
1102 return hResult.isOk() ? err : DEAD_OBJECT;
1103}
1104
1105status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1106 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001107 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001108
Jeff Tinker58ad4752018-02-16 16:51:59 -08001109 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001110 if (mPluginV1_1 != NULL) {
1111 SecureStopRelease secureStopRelease;
1112 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001113 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1114 } else {
1115 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001116 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001117 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001118}
1119
Jeff Tinker15177d72018-01-25 12:57:55 -08001120status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1121 Mutex::Autolock autoLock(mLock);
1122
1123 if (mInitCheck != OK) {
1124 return mInitCheck;
1125 }
1126
1127 if (mPluginV1_1 == NULL) {
1128 return ERROR_DRM_CANNOT_HANDLE;
1129 }
1130
Jeff Tinker58ad4752018-02-16 16:51:59 -08001131 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1132 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001133}
1134
1135status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001136 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001137 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001138
Jeff Tinker58ad4752018-02-16 16:51:59 -08001139 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001140 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001141 status = mPluginV1_1->removeAllSecureStops();
1142 } else {
1143 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001144 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001145 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001146}
1147
Jeff Tinker6d998b62017-12-18 14:37:43 -08001148status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1149 DrmPlugin::HdcpLevel *max) const {
1150 Mutex::Autolock autoLock(mLock);
1151 INIT_CHECK();
1152
1153 if (connected == NULL || max == NULL) {
1154 return BAD_VALUE;
1155 }
1156 status_t err = UNKNOWN_ERROR;
1157
Jeff Tinker6d998b62017-12-18 14:37:43 -08001158 *connected = DrmPlugin::kHdcpLevelUnknown;
1159 *max = DrmPlugin::kHdcpLevelUnknown;
1160
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001161 Return<void> hResult;
1162 if (mPluginV1_2 != NULL) {
1163 hResult = mPluginV1_2->getHdcpLevels_1_2(
1164 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1165 if (status == Status_V1_2::OK) {
1166 *connected = toHdcpLevel(hConnected);
1167 *max = toHdcpLevel(hMax);
1168 }
1169 err = toStatusT_1_2(status);
1170 });
1171 } else if (mPluginV1_1 != NULL) {
1172 hResult = mPluginV1_1->getHdcpLevels(
1173 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1174 if (status == Status::OK) {
1175 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1176 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1177 }
1178 err = toStatusT(status);
1179 });
1180 } else {
1181 return ERROR_DRM_CANNOT_HANDLE;
1182 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001183
1184 return hResult.isOk() ? err : DEAD_OBJECT;
1185}
1186
1187status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1188 Mutex::Autolock autoLock(mLock);
1189 INIT_CHECK();
1190
1191 if (open == NULL || max == NULL) {
1192 return BAD_VALUE;
1193 }
1194 status_t err = UNKNOWN_ERROR;
1195
1196 *open = 0;
1197 *max = 0;
1198
1199 if (mPluginV1_1 == NULL) {
1200 return ERROR_DRM_CANNOT_HANDLE;
1201 }
1202
1203 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1204 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1205 if (status == Status::OK) {
1206 *open = hOpen;
1207 *max = hMax;
1208 }
1209 err = toStatusT(status);
1210 }
1211 );
1212
1213 return hResult.isOk() ? err : DEAD_OBJECT;
1214}
1215
1216status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1217 DrmPlugin::SecurityLevel *level) const {
1218 Mutex::Autolock autoLock(mLock);
1219 INIT_CHECK();
1220
1221 if (level == NULL) {
1222 return BAD_VALUE;
1223 }
1224 status_t err = UNKNOWN_ERROR;
1225
1226 if (mPluginV1_1 == NULL) {
1227 return ERROR_DRM_CANNOT_HANDLE;
1228 }
1229
1230 *level = DrmPlugin::kSecurityLevelUnknown;
1231
1232 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1233 [&](Status status, SecurityLevel hLevel) {
1234 if (status == Status::OK) {
1235 *level = toSecurityLevel(hLevel);
1236 }
1237 err = toStatusT(status);
1238 }
1239 );
1240
1241 return hResult.isOk() ? err : DEAD_OBJECT;
1242}
1243
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001244status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1245 Mutex::Autolock autoLock(mLock);
1246
1247 if (mInitCheck != OK) {
1248 return mInitCheck;
1249 }
1250
1251 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001252 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001253 }
1254
1255 status_t err = UNKNOWN_ERROR;
1256
1257 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1258 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1259 if (status == Status::OK) {
1260 keySetIds = toKeySetIds(hKeySetIds);
1261 }
1262 err = toStatusT(status);
1263 }
1264 );
1265
1266 return hResult.isOk() ? err : DEAD_OBJECT;
1267}
1268
1269status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1270 Mutex::Autolock autoLock(mLock);
1271
1272 if (mInitCheck != OK) {
1273 return mInitCheck;
1274 }
1275
1276 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001277 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001278 }
1279
1280 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1281 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1282}
1283
1284status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1285 DrmPlugin::OfflineLicenseState *licenseState) const {
1286 Mutex::Autolock autoLock(mLock);
1287
1288 if (mInitCheck != OK) {
1289 return mInitCheck;
1290 }
1291
1292 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001293 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001294 }
1295 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1296
1297 status_t err = UNKNOWN_ERROR;
1298
1299 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1300 [&](Status status, OfflineLicenseState hLicenseState) {
1301 if (status == Status::OK) {
1302 *licenseState = toOfflineLicenseState(hLicenseState);
1303 }
1304 err = toStatusT(status);
1305 }
1306 );
1307
1308 return hResult.isOk() ? err : DEAD_OBJECT;
1309}
1310
Jeff Tinkera53d6552017-01-20 00:31:46 -08001311status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1312 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001313 return getPropertyStringInternal(name, value);
1314}
1315
1316status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1317 // This function is internal to the class and should only be called while
1318 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001319 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001320
1321 status_t err = UNKNOWN_ERROR;
1322
1323 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1324 [&](Status status, const hidl_string& hValue) {
1325 if (status == Status::OK) {
1326 value = toString8(hValue);
1327 }
1328 err = toStatusT(status);
1329 }
1330 );
1331
1332 return hResult.isOk() ? err : DEAD_OBJECT;
1333}
1334
1335status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1336 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001337 return getPropertyByteArrayInternal(name, value);
1338}
1339
1340status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1341 // This function is internal to the class and should only be called while
1342 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001343 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001344
1345 status_t err = UNKNOWN_ERROR;
1346
1347 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1348 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1349 if (status == Status::OK) {
1350 value = toVector(hValue);
1351 }
1352 err = toStatusT(status);
1353 }
1354 );
1355
Adam Stonecea91ce2018-01-22 19:23:28 -08001356 err = hResult.isOk() ? err : DEAD_OBJECT;
1357 if (name == kPropertyDeviceUniqueId) {
1358 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1359 }
1360 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001361}
1362
1363status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1364 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001365 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001366
Jeff Tinker58ad4752018-02-16 16:51:59 -08001367 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001368 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001369 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001370}
1371
1372status_t DrmHal::setPropertyByteArray(String8 const &name,
1373 Vector<uint8_t> const &value ) const {
1374 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001375 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001376
Jeff Tinker58ad4752018-02-16 16:51:59 -08001377 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001378 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001379 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001380}
1381
Adam Stone28f27c32018-02-05 15:07:48 -08001382status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1383 if (metrics == nullptr) {
1384 return UNEXPECTED_NULL;
1385 }
1386 mMetrics.Export(metrics);
1387
1388 // Append vendor metrics if they are supported.
1389 if (mPluginV1_1 != NULL) {
1390 String8 vendor;
1391 String8 description;
1392 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1393 || vendor.isEmpty()) {
1394 ALOGE("Get vendor failed or is empty");
1395 vendor = "NONE";
1396 }
1397 if (getPropertyStringInternal(String8("description"), description) != OK
1398 || description.isEmpty()) {
1399 ALOGE("Get description failed or is empty.");
1400 description = "NONE";
1401 }
1402 vendor += ".";
1403 vendor += description;
1404
1405 hidl_vec<DrmMetricGroup> pluginMetrics;
1406 status_t err = UNKNOWN_ERROR;
1407
1408 Return<void> status = mPluginV1_1->getMetrics(
1409 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1410 if (status != Status::OK) {
1411 ALOGV("Error getting plugin metrics: %d", status);
1412 } else {
1413 PersistableBundle pluginBundle;
1414 if (MediaDrmMetrics::HidlMetricsToBundle(
1415 pluginMetrics, &pluginBundle) == OK) {
1416 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1417 }
1418 }
1419 err = toStatusT(status);
1420 });
1421 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001422 }
1423
Adam Stoneab394d12017-12-22 12:34:20 -08001424 return OK;
1425}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001426
1427status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1428 String8 const &algorithm) {
1429 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001430 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001431
1432 DrmSessionManager::Instance()->useSession(sessionId);
1433
Jeff Tinkere6412942018-04-30 17:35:16 -07001434 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001435 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001436 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001437}
1438
1439status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1440 String8 const &algorithm) {
1441 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001442 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001443
1444 DrmSessionManager::Instance()->useSession(sessionId);
1445
Jeff Tinkere6412942018-04-30 17:35:16 -07001446 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001447 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001448 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449}
1450
1451status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001452 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1453 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001454 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001455 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001456
1457 DrmSessionManager::Instance()->useSession(sessionId);
1458
1459 status_t err = UNKNOWN_ERROR;
1460
1461 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1462 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1463 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1464 if (status == Status::OK) {
1465 output = toVector(hOutput);
1466 }
1467 err = toStatusT(status);
1468 }
1469 );
1470
1471 return hResult.isOk() ? err : DEAD_OBJECT;
1472}
1473
1474status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001475 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1476 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001477 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001478 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001479
1480 DrmSessionManager::Instance()->useSession(sessionId);
1481
1482 status_t err = UNKNOWN_ERROR;
1483
1484 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1485 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1486 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1487 if (status == Status::OK) {
1488 output = toVector(hOutput);
1489 }
1490 err = toStatusT(status);
1491 }
1492 );
1493
1494 return hResult.isOk() ? err : DEAD_OBJECT;
1495}
1496
1497status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001498 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1499 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001500 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001501 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001502
1503 DrmSessionManager::Instance()->useSession(sessionId);
1504
1505 status_t err = UNKNOWN_ERROR;
1506
1507 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1508 toHidlVec(keyId), toHidlVec(message),
1509 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1510 if (status == Status::OK) {
1511 signature = toVector(hSignature);
1512 }
1513 err = toStatusT(status);
1514 }
1515 );
1516
1517 return hResult.isOk() ? err : DEAD_OBJECT;
1518}
1519
1520status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001521 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1522 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001523 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001524 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001525
1526 DrmSessionManager::Instance()->useSession(sessionId);
1527
1528 status_t err = UNKNOWN_ERROR;
1529
1530 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1531 toHidlVec(message), toHidlVec(signature),
1532 [&](Status status, bool hMatch) {
1533 if (status == Status::OK) {
1534 match = hMatch;
1535 } else {
1536 match = false;
1537 }
1538 err = toStatusT(status);
1539 }
1540 );
1541
1542 return hResult.isOk() ? err : DEAD_OBJECT;
1543}
1544
1545status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001546 String8 const &algorithm, Vector<uint8_t> const &message,
1547 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001548 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001549 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001550
1551 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1552 return -EPERM;
1553 }
1554
1555 DrmSessionManager::Instance()->useSession(sessionId);
1556
1557 status_t err = UNKNOWN_ERROR;
1558
1559 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1560 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1561 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1562 if (status == Status::OK) {
1563 signature = toVector(hSignature);
1564 }
1565 err = toStatusT(status);
1566 }
1567 );
1568
1569 return hResult.isOk() ? err : DEAD_OBJECT;
1570}
1571
1572void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1573{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001574 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001575}
1576
Adam Stonefb679e32018-02-07 10:25:48 -08001577void DrmHal::reportFrameworkMetrics() const
1578{
Robert Shih82ea6be2019-11-07 17:47:23 -08001579 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1580 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001581 String8 vendor;
1582 String8 description;
1583 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1584 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001585 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001586 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001587 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001588 }
1589 result = getPropertyStringInternal(String8("description"), description);
1590 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001591 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001592 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001593 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001594 }
Adam Stoneab394d12017-12-22 12:34:20 -08001595
Adam Stonefb679e32018-02-07 10:25:48 -08001596 std::string serializedMetrics;
1597 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1598 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001599 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001600 }
Adam Stone32494f52018-02-26 22:53:27 -08001601 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1602 serializedMetrics.size());
1603 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001604 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001605 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001606 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001607 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001608 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001609 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001610}
1611
1612void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001613{
Adam Stone32494f52018-02-26 22:53:27 -08001614 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001615 String8 vendor;
1616 String8 description;
1617 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1618 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001619 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1620 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1621 metricsVector.size());
1622 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001623 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001624 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001625 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001626 }
1627 }
1628}
1629
Jeff Tinkera53d6552017-01-20 00:31:46 -08001630} // namespace android