blob: 8c2d8f214f83e7eba9980782dce9b7f98f27e3cb [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
Robert Shih0f3a8a02019-11-14 15:43:39 -080026#include <aidl/android/media/BnResourceManagerClient.h>
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070027#include <android/hardware/drm/1.2/types.h>
Peter Kalauskasca5642c2018-11-12 12:34:42 -080028#include <android/hidl/manager/1.2/IServiceManager.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
Robert Shih0f3a8a02019-11-14 15:43:39 -0800302struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700303 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
304 : mSessionId(sessionId),
305 mDrm(drm) {}
306
Robert Shih0f3a8a02019-11-14 15:43:39 -0800307 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
308 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700309
310 const Vector<uint8_t> mSessionId;
311
Chong Zhang181e6952019-10-09 13:23:39 -0700312 virtual ~DrmSessionClient();
313
314private:
315 wp<DrmHal> mDrm;
316
317 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
318};
319
Robert Shih0f3a8a02019-11-14 15:43:39 -0800320::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
321 auto sessionId = mSessionId;
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;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800325 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800326 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800327 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700328 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700329 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800330 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700331 }
332 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800333 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700334 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800335 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700336}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800337
Robert Shih0f3a8a02019-11-14 15:43:39 -0800338::ndk::ScopedAStatus 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;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800353 return ::ndk::ScopedAStatus::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);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800484 mListener = listener;
485 return NO_ERROR;
486}
487
488Return<void> DrmHal::sendEvent(EventType hEventType,
489 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800490 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800491
492 mEventLock.lock();
493 sp<IDrmClient> listener = mListener;
494 mEventLock.unlock();
495
496 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800497 Mutex::Autolock lock(mNotifyLock);
498 DrmPlugin::EventType eventType;
499 switch(hEventType) {
500 case EventType::PROVISION_REQUIRED:
501 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
502 break;
503 case EventType::KEY_NEEDED:
504 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
505 break;
506 case EventType::KEY_EXPIRED:
507 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
508 break;
509 case EventType::VENDOR_DEFINED:
510 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
511 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700512 case EventType::SESSION_RECLAIMED:
513 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
514 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800515 default:
516 return Void();
517 }
Robert Shih61e1c762019-10-31 21:26:58 -0700518 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800519 }
520 return Void();
521}
522
523Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
524 int64_t expiryTimeInMS) {
525
526 mEventLock.lock();
527 sp<IDrmClient> listener = mListener;
528 mEventLock.unlock();
529
530 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800531 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700532 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800533 }
534 return Void();
535}
536
537Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700538 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
539 std::vector<KeyStatus> keyStatusVec;
540 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
541 keyStatusVec.push_back({keyStatus_V1_0.keyId,
542 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
543 }
544 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
545 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
546}
547
548Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700549 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800550
551 mEventLock.lock();
552 sp<IDrmClient> listener = mListener;
553 mEventLock.unlock();
554
555 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700556 std::vector<DrmKeyStatus> keyStatusList;
557 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800558 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700559 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800560 uint32_t type;
561 switch(keyStatus.type) {
562 case KeyStatusType::USABLE:
563 type = DrmPlugin::kKeyStatusType_Usable;
564 break;
565 case KeyStatusType::EXPIRED:
566 type = DrmPlugin::kKeyStatusType_Expired;
567 break;
568 case KeyStatusType::OUTPUTNOTALLOWED:
569 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
570 break;
571 case KeyStatusType::STATUSPENDING:
572 type = DrmPlugin::kKeyStatusType_StatusPending;
573 break;
Robert Shiha5033262019-05-06 14:15:12 -0700574 case KeyStatusType::USABLEINFUTURE:
575 type = DrmPlugin::kKeyStatusType_UsableInFuture;
576 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800577 case KeyStatusType::INTERNALERROR:
578 default:
579 type = DrmPlugin::kKeyStatusType_InternalError;
580 break;
581 }
Robert Shih61e1c762019-10-31 21:26:58 -0700582 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800583 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800584 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800585
586 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700587 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800588 } else {
589 // There's no listener. But we still want to count the key change
590 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700591 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800592 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700593 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800594 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800595 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800596
Jeff Tinkera53d6552017-01-20 00:31:46 -0800597 return Void();
598}
599
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800600Return<void> DrmHal::sendSessionLostState(
601 const hidl_vec<uint8_t>& sessionId) {
602
603 mEventLock.lock();
604 sp<IDrmClient> listener = mListener;
605 mEventLock.unlock();
606
607 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800608 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700609 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800610 }
611 return Void();
612}
613
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800614status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
615 const uint8_t uuid[16],
616 const String8 &mimeType,
617 DrmPlugin::SecurityLevel level,
618 bool *isSupported) {
619 *isSupported = false;
620
621 // handle default value cases
622 if (level == DrmPlugin::kSecurityLevelUnknown) {
623 if (mimeType == "") {
624 // isCryptoSchemeSupported(uuid)
625 *isSupported = true;
626 } else {
627 // isCryptoSchemeSupported(uuid, mimeType)
628 *isSupported = factory->isContentTypeSupported(mimeType.string());
629 }
630 return OK;
631 } else if (mimeType == "") {
632 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800633 }
634
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800635 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
636 if (factoryV1_2 == NULL) {
637 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800638 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800639 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
640 mimeType.string(), toHidlSecurityLevel(level));
641 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800642 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800643}
644
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800645status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
646 const String8 &mimeType,
647 DrmPlugin::SecurityLevel level,
648 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800649 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800650 *isSupported = false;
651 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
652 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
653 return matchMimeTypeAndSecurityLevel(mFactories[i],
654 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800655 }
656 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800657 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800658}
659
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800660status_t DrmHal::createPlugin(const uint8_t uuid[16],
661 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800662 Mutex::Autolock autoLock(mLock);
663
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800664 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800665 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800666 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
667 if (plugin != NULL) {
668 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800669 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700670 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800671 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800672 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800673 }
674 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800675
676 if (mPlugin == NULL) {
677 mInitCheck = ERROR_UNSUPPORTED;
678 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800679 mInitCheck = OK;
680 if (mPluginV1_2 != NULL) {
681 if (!mPluginV1_2->setListener(this).isOk()) {
682 mInitCheck = DEAD_OBJECT;
683 }
684 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700685 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800686 }
687 if (mInitCheck != OK) {
688 mPlugin.clear();
689 mPluginV1_1.clear();
690 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700691 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800692 }
693
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800694
Jeff Tinkera53d6552017-01-20 00:31:46 -0800695 return mInitCheck;
696}
697
698status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800699 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800700 return OK;
701}
702
Jeff Tinker41d279a2018-02-11 19:52:08 +0000703status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
704 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800705 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800706 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800707
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800708 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000709 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000710
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800711 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000712 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800713 } else {
714 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
715 return ERROR_DRM_CANNOT_HANDLE;
716 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000717 }
718
719 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800720 bool retry = true;
721 do {
722 hidl_vec<uint8_t> hSessionId;
723
Jeff Tinker41d279a2018-02-11 19:52:08 +0000724 Return<void> hResult;
725 if (mPluginV1_1 == NULL || !setSecurityLevel) {
726 hResult = mPlugin->openSession(
727 [&](Status status,const hidl_vec<uint8_t>& id) {
728 if (status == Status::OK) {
729 sessionId = toVector(id);
730 }
731 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800732 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000733 );
734 } else {
735 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
736 [&](Status status, const hidl_vec<uint8_t>& id) {
737 if (status == Status::OK) {
738 sessionId = toVector(id);
739 }
740 err = toStatusT(status);
741 }
742 );
743 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800744
745 if (!hResult.isOk()) {
746 err = DEAD_OBJECT;
747 }
748
749 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
750 mLock.unlock();
751 // reclaimSession may call back to closeSession, since mLock is
752 // shared between Drm instances, we should unlock here to avoid
753 // deadlock.
754 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
755 mLock.lock();
756 } else {
757 retry = false;
758 }
759 } while (retry);
760
761 if (err == OK) {
Robert Shih0f3a8a02019-11-14 15:43:39 -0800762 std::shared_ptr<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
763 DrmSessionManager::Instance()->addSession(getCallingPid(),
764 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
765 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800766 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800767 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800768
Adam Stonef0e618d2018-01-17 19:20:41 -0800769 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800770 return err;
771}
772
773status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
774 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800775 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800776
Jeff Tinker319d5f42017-07-26 15:44:33 -0700777 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
778 if (status.isOk()) {
779 if (status == Status::OK) {
780 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800781 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
782 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
783 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700784 break;
785 }
Jeff Tinker61332812017-05-15 16:53:10 -0700786 }
787 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800788 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800789 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800790 mMetrics.mCloseSessionCounter.Increment(response);
791 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800792 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800793 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700794 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800795}
796
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800797static DrmPlugin::KeyRequestType toKeyRequestType(
798 KeyRequestType keyRequestType) {
799 switch (keyRequestType) {
800 case KeyRequestType::INITIAL:
801 return DrmPlugin::kKeyRequestType_Initial;
802 break;
803 case KeyRequestType::RENEWAL:
804 return DrmPlugin::kKeyRequestType_Renewal;
805 break;
806 case KeyRequestType::RELEASE:
807 return DrmPlugin::kKeyRequestType_Release;
808 break;
809 default:
810 return DrmPlugin::kKeyRequestType_Unknown;
811 break;
812 }
813}
814
815static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
816 KeyRequestType_V1_1 keyRequestType) {
817 switch (keyRequestType) {
818 case KeyRequestType_V1_1::NONE:
819 return DrmPlugin::kKeyRequestType_None;
820 break;
821 case KeyRequestType_V1_1::UPDATE:
822 return DrmPlugin::kKeyRequestType_Update;
823 break;
824 default:
825 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
826 break;
827 }
828}
829
Jeff Tinkera53d6552017-01-20 00:31:46 -0800830status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
831 Vector<uint8_t> const &initData, String8 const &mimeType,
832 DrmPlugin::KeyType keyType, KeyedVector<String8,
833 String8> const &optionalParameters, Vector<uint8_t> &request,
834 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
835 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800836 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800837 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800838
839 DrmSessionManager::Instance()->useSession(sessionId);
840
841 KeyType hKeyType;
842 if (keyType == DrmPlugin::kKeyType_Streaming) {
843 hKeyType = KeyType::STREAMING;
844 } else if (keyType == DrmPlugin::kKeyType_Offline) {
845 hKeyType = KeyType::OFFLINE;
846 } else if (keyType == DrmPlugin::kKeyType_Release) {
847 hKeyType = KeyType::RELEASE;
848 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800849 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800850 return BAD_VALUE;
851 }
852
853 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
854
855 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800856 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800857
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800858 if (mPluginV1_2 != NULL) {
859 hResult = mPluginV1_2->getKeyRequest_1_2(
860 toHidlVec(sessionId), toHidlVec(initData),
861 toHidlString(mimeType), hKeyType, hOptionalParameters,
862 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
863 KeyRequestType_V1_1 hKeyRequestType,
864 const hidl_string& hDefaultUrl) {
865 if (status == Status_V1_2::OK) {
866 request = toVector(hRequest);
867 defaultUrl = toString8(hDefaultUrl);
868 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
869 }
870 err = toStatusT_1_2(status);
871 });
872 } else if (mPluginV1_1 != NULL) {
873 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800874 toHidlVec(sessionId), toHidlVec(initData),
875 toHidlString(mimeType), hKeyType, hOptionalParameters,
876 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800877 KeyRequestType_V1_1 hKeyRequestType,
878 const hidl_string& hDefaultUrl) {
879 if (status == Status::OK) {
880 request = toVector(hRequest);
881 defaultUrl = toString8(hDefaultUrl);
882 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800883 }
884 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800885 });
886 } else {
887 hResult = mPlugin->getKeyRequest(
888 toHidlVec(sessionId), toHidlVec(initData),
889 toHidlString(mimeType), hKeyType, hOptionalParameters,
890 [&](Status status, const hidl_vec<uint8_t>& hRequest,
891 KeyRequestType hKeyRequestType,
892 const hidl_string& hDefaultUrl) {
893 if (status == Status::OK) {
894 request = toVector(hRequest);
895 defaultUrl = toString8(hDefaultUrl);
896 *keyRequestType = toKeyRequestType(hKeyRequestType);
897 }
898 err = toStatusT(status);
899 });
900 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800901
Adam Stonef0e618d2018-01-17 19:20:41 -0800902 err = hResult.isOk() ? err : DEAD_OBJECT;
903 keyRequestTimer.SetAttribute(err);
904 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800905}
906
907status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
908 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
909 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800910 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700911 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800912
913 DrmSessionManager::Instance()->useSession(sessionId);
914
915 status_t err = UNKNOWN_ERROR;
916
917 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
918 toHidlVec(response),
919 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
920 if (status == Status::OK) {
921 keySetId = toVector(hKeySetId);
922 }
923 err = toStatusT(status);
924 }
925 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800926 err = hResult.isOk() ? err : DEAD_OBJECT;
927 keyResponseTimer.SetAttribute(err);
928 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800929}
930
931status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
932 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800933 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800934
Jeff Tinker58ad4752018-02-16 16:51:59 -0800935 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
936 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800937}
938
939status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
940 Vector<uint8_t> const &keySetId) {
941 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800942 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800943
944 DrmSessionManager::Instance()->useSession(sessionId);
945
Jeff Tinker58ad4752018-02-16 16:51:59 -0800946 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
947 toHidlVec(keySetId));
948 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800949}
950
951status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
952 KeyedVector<String8, String8> &infoMap) const {
953 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800954 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800955
956 DrmSessionManager::Instance()->useSession(sessionId);
957
958 ::KeyedVector hInfoMap;
959
960 status_t err = UNKNOWN_ERROR;
961
962 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
963 [&](Status status, const hidl_vec<KeyValue>& map) {
964 if (status == Status::OK) {
965 infoMap = toKeyedVector(map);
966 }
967 err = toStatusT(status);
968 }
969 );
970
971 return hResult.isOk() ? err : DEAD_OBJECT;
972}
973
974status_t DrmHal::getProvisionRequest(String8 const &certType,
975 String8 const &certAuthority, Vector<uint8_t> &request,
976 String8 &defaultUrl) {
977 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800978 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800979
980 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800981 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800982
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800983 if (mPluginV1_2 != NULL) {
984 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
985 toHidlString(certType), toHidlString(certAuthority),
986 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
987 const hidl_string& hDefaultUrl) {
988 if (status == Status_V1_2::OK) {
989 request = toVector(hRequest);
990 defaultUrl = toString8(hDefaultUrl);
991 }
992 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800993 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800994 );
995 } else {
996 Return<void> hResult = mPlugin->getProvisionRequest(
997 toHidlString(certType), toHidlString(certAuthority),
998 [&](Status status, const hidl_vec<uint8_t>& hRequest,
999 const hidl_string& hDefaultUrl) {
1000 if (status == Status::OK) {
1001 request = toVector(hRequest);
1002 defaultUrl = toString8(hDefaultUrl);
1003 }
1004 err = toStatusT(status);
1005 }
1006 );
1007 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001008
Adam Stonecea91ce2018-01-22 19:23:28 -08001009 err = hResult.isOk() ? err : DEAD_OBJECT;
1010 mMetrics.mGetProvisionRequestCounter.Increment(err);
1011 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001012}
1013
1014status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001015 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001016 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001017 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001018
1019 status_t err = UNKNOWN_ERROR;
1020
1021 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1022 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1023 const hidl_vec<uint8_t>& hWrappedKey) {
1024 if (status == Status::OK) {
1025 certificate = toVector(hCertificate);
1026 wrappedKey = toVector(hWrappedKey);
1027 }
1028 err = toStatusT(status);
1029 }
1030 );
1031
Adam Stonecea91ce2018-01-22 19:23:28 -08001032 err = hResult.isOk() ? err : DEAD_OBJECT;
1033 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1034 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001035}
1036
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001037status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001038 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001039 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001040
1041 status_t err = UNKNOWN_ERROR;
1042
1043 Return<void> hResult = mPlugin->getSecureStops(
1044 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1045 if (status == Status::OK) {
1046 secureStops = toSecureStops(hSecureStops);
1047 }
1048 err = toStatusT(status);
1049 }
1050 );
1051
1052 return hResult.isOk() ? err : DEAD_OBJECT;
1053}
1054
1055
Jeff Tinker15177d72018-01-25 12:57:55 -08001056status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1057 Mutex::Autolock autoLock(mLock);
1058
1059 if (mInitCheck != OK) {
1060 return mInitCheck;
1061 }
1062
1063 if (mPluginV1_1 == NULL) {
1064 return ERROR_DRM_CANNOT_HANDLE;
1065 }
1066
1067 status_t err = UNKNOWN_ERROR;
1068
1069 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1070 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1071 if (status == Status::OK) {
1072 secureStopIds = toSecureStopIds(hSecureStopIds);
1073 }
1074 err = toStatusT(status);
1075 }
1076 );
1077
1078 return hResult.isOk() ? err : DEAD_OBJECT;
1079}
1080
1081
Jeff Tinkera53d6552017-01-20 00:31:46 -08001082status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1083 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001084 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001085
1086 status_t err = UNKNOWN_ERROR;
1087
1088 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1089 [&](Status status, const SecureStop& hSecureStop) {
1090 if (status == Status::OK) {
1091 secureStop = toVector(hSecureStop.opaqueData);
1092 }
1093 err = toStatusT(status);
1094 }
1095 );
1096
1097 return hResult.isOk() ? err : DEAD_OBJECT;
1098}
1099
1100status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1101 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001102 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001103
Jeff Tinker58ad4752018-02-16 16:51:59 -08001104 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001105 if (mPluginV1_1 != NULL) {
1106 SecureStopRelease secureStopRelease;
1107 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001108 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1109 } else {
1110 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001111 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001112 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001113}
1114
Jeff Tinker15177d72018-01-25 12:57:55 -08001115status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1116 Mutex::Autolock autoLock(mLock);
1117
1118 if (mInitCheck != OK) {
1119 return mInitCheck;
1120 }
1121
1122 if (mPluginV1_1 == NULL) {
1123 return ERROR_DRM_CANNOT_HANDLE;
1124 }
1125
Jeff Tinker58ad4752018-02-16 16:51:59 -08001126 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1127 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001128}
1129
1130status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001131 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001132 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001133
Jeff Tinker58ad4752018-02-16 16:51:59 -08001134 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001135 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001136 status = mPluginV1_1->removeAllSecureStops();
1137 } else {
1138 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001139 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001140 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001141}
1142
Jeff Tinker6d998b62017-12-18 14:37:43 -08001143status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1144 DrmPlugin::HdcpLevel *max) const {
1145 Mutex::Autolock autoLock(mLock);
1146 INIT_CHECK();
1147
1148 if (connected == NULL || max == NULL) {
1149 return BAD_VALUE;
1150 }
1151 status_t err = UNKNOWN_ERROR;
1152
Jeff Tinker6d998b62017-12-18 14:37:43 -08001153 *connected = DrmPlugin::kHdcpLevelUnknown;
1154 *max = DrmPlugin::kHdcpLevelUnknown;
1155
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001156 Return<void> hResult;
1157 if (mPluginV1_2 != NULL) {
1158 hResult = mPluginV1_2->getHdcpLevels_1_2(
1159 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1160 if (status == Status_V1_2::OK) {
1161 *connected = toHdcpLevel(hConnected);
1162 *max = toHdcpLevel(hMax);
1163 }
1164 err = toStatusT_1_2(status);
1165 });
1166 } else if (mPluginV1_1 != NULL) {
1167 hResult = mPluginV1_1->getHdcpLevels(
1168 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1169 if (status == Status::OK) {
1170 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1171 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1172 }
1173 err = toStatusT(status);
1174 });
1175 } else {
1176 return ERROR_DRM_CANNOT_HANDLE;
1177 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001178
1179 return hResult.isOk() ? err : DEAD_OBJECT;
1180}
1181
1182status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1183 Mutex::Autolock autoLock(mLock);
1184 INIT_CHECK();
1185
1186 if (open == NULL || max == NULL) {
1187 return BAD_VALUE;
1188 }
1189 status_t err = UNKNOWN_ERROR;
1190
1191 *open = 0;
1192 *max = 0;
1193
1194 if (mPluginV1_1 == NULL) {
1195 return ERROR_DRM_CANNOT_HANDLE;
1196 }
1197
1198 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1199 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1200 if (status == Status::OK) {
1201 *open = hOpen;
1202 *max = hMax;
1203 }
1204 err = toStatusT(status);
1205 }
1206 );
1207
1208 return hResult.isOk() ? err : DEAD_OBJECT;
1209}
1210
1211status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1212 DrmPlugin::SecurityLevel *level) const {
1213 Mutex::Autolock autoLock(mLock);
1214 INIT_CHECK();
1215
1216 if (level == NULL) {
1217 return BAD_VALUE;
1218 }
1219 status_t err = UNKNOWN_ERROR;
1220
1221 if (mPluginV1_1 == NULL) {
1222 return ERROR_DRM_CANNOT_HANDLE;
1223 }
1224
1225 *level = DrmPlugin::kSecurityLevelUnknown;
1226
1227 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1228 [&](Status status, SecurityLevel hLevel) {
1229 if (status == Status::OK) {
1230 *level = toSecurityLevel(hLevel);
1231 }
1232 err = toStatusT(status);
1233 }
1234 );
1235
1236 return hResult.isOk() ? err : DEAD_OBJECT;
1237}
1238
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001239status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1240 Mutex::Autolock autoLock(mLock);
1241
1242 if (mInitCheck != OK) {
1243 return mInitCheck;
1244 }
1245
1246 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001247 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001248 }
1249
1250 status_t err = UNKNOWN_ERROR;
1251
1252 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1253 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1254 if (status == Status::OK) {
1255 keySetIds = toKeySetIds(hKeySetIds);
1256 }
1257 err = toStatusT(status);
1258 }
1259 );
1260
1261 return hResult.isOk() ? err : DEAD_OBJECT;
1262}
1263
1264status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1265 Mutex::Autolock autoLock(mLock);
1266
1267 if (mInitCheck != OK) {
1268 return mInitCheck;
1269 }
1270
1271 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001272 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001273 }
1274
1275 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1276 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1277}
1278
1279status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1280 DrmPlugin::OfflineLicenseState *licenseState) const {
1281 Mutex::Autolock autoLock(mLock);
1282
1283 if (mInitCheck != OK) {
1284 return mInitCheck;
1285 }
1286
1287 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001288 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001289 }
1290 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1291
1292 status_t err = UNKNOWN_ERROR;
1293
1294 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1295 [&](Status status, OfflineLicenseState hLicenseState) {
1296 if (status == Status::OK) {
1297 *licenseState = toOfflineLicenseState(hLicenseState);
1298 }
1299 err = toStatusT(status);
1300 }
1301 );
1302
1303 return hResult.isOk() ? err : DEAD_OBJECT;
1304}
1305
Jeff Tinkera53d6552017-01-20 00:31:46 -08001306status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1307 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001308 return getPropertyStringInternal(name, value);
1309}
1310
1311status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1312 // This function is internal to the class and should only be called while
1313 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001314 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001315
1316 status_t err = UNKNOWN_ERROR;
1317
1318 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1319 [&](Status status, const hidl_string& hValue) {
1320 if (status == Status::OK) {
1321 value = toString8(hValue);
1322 }
1323 err = toStatusT(status);
1324 }
1325 );
1326
1327 return hResult.isOk() ? err : DEAD_OBJECT;
1328}
1329
1330status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1331 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001332 return getPropertyByteArrayInternal(name, value);
1333}
1334
1335status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1336 // This function is internal to the class and should only be called while
1337 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001338 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001339
1340 status_t err = UNKNOWN_ERROR;
1341
1342 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1343 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1344 if (status == Status::OK) {
1345 value = toVector(hValue);
1346 }
1347 err = toStatusT(status);
1348 }
1349 );
1350
Adam Stonecea91ce2018-01-22 19:23:28 -08001351 err = hResult.isOk() ? err : DEAD_OBJECT;
1352 if (name == kPropertyDeviceUniqueId) {
1353 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1354 }
1355 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001356}
1357
1358status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1359 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001360 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001361
Jeff Tinker58ad4752018-02-16 16:51:59 -08001362 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001363 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001364 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001365}
1366
1367status_t DrmHal::setPropertyByteArray(String8 const &name,
1368 Vector<uint8_t> const &value ) const {
1369 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001370 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001371
Jeff Tinker58ad4752018-02-16 16:51:59 -08001372 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001373 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001374 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001375}
1376
Adam Stone28f27c32018-02-05 15:07:48 -08001377status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1378 if (metrics == nullptr) {
1379 return UNEXPECTED_NULL;
1380 }
1381 mMetrics.Export(metrics);
1382
1383 // Append vendor metrics if they are supported.
1384 if (mPluginV1_1 != NULL) {
1385 String8 vendor;
1386 String8 description;
1387 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1388 || vendor.isEmpty()) {
1389 ALOGE("Get vendor failed or is empty");
1390 vendor = "NONE";
1391 }
1392 if (getPropertyStringInternal(String8("description"), description) != OK
1393 || description.isEmpty()) {
1394 ALOGE("Get description failed or is empty.");
1395 description = "NONE";
1396 }
1397 vendor += ".";
1398 vendor += description;
1399
1400 hidl_vec<DrmMetricGroup> pluginMetrics;
1401 status_t err = UNKNOWN_ERROR;
1402
1403 Return<void> status = mPluginV1_1->getMetrics(
1404 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1405 if (status != Status::OK) {
1406 ALOGV("Error getting plugin metrics: %d", status);
1407 } else {
1408 PersistableBundle pluginBundle;
1409 if (MediaDrmMetrics::HidlMetricsToBundle(
1410 pluginMetrics, &pluginBundle) == OK) {
1411 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1412 }
1413 }
1414 err = toStatusT(status);
1415 });
1416 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001417 }
1418
Adam Stoneab394d12017-12-22 12:34:20 -08001419 return OK;
1420}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001421
1422status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1423 String8 const &algorithm) {
1424 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001425 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001426
1427 DrmSessionManager::Instance()->useSession(sessionId);
1428
Jeff Tinkere6412942018-04-30 17:35:16 -07001429 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001430 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001431 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001432}
1433
1434status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1435 String8 const &algorithm) {
1436 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001437 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001438
1439 DrmSessionManager::Instance()->useSession(sessionId);
1440
Jeff Tinkere6412942018-04-30 17:35:16 -07001441 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001442 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001443 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001444}
1445
1446status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001447 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1448 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001450 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001451
1452 DrmSessionManager::Instance()->useSession(sessionId);
1453
1454 status_t err = UNKNOWN_ERROR;
1455
1456 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1457 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1458 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1459 if (status == Status::OK) {
1460 output = toVector(hOutput);
1461 }
1462 err = toStatusT(status);
1463 }
1464 );
1465
1466 return hResult.isOk() ? err : DEAD_OBJECT;
1467}
1468
1469status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001470 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1471 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001472 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001473 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001474
1475 DrmSessionManager::Instance()->useSession(sessionId);
1476
1477 status_t err = UNKNOWN_ERROR;
1478
1479 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1480 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1481 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1482 if (status == Status::OK) {
1483 output = toVector(hOutput);
1484 }
1485 err = toStatusT(status);
1486 }
1487 );
1488
1489 return hResult.isOk() ? err : DEAD_OBJECT;
1490}
1491
1492status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001493 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1494 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001495 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001496 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001497
1498 DrmSessionManager::Instance()->useSession(sessionId);
1499
1500 status_t err = UNKNOWN_ERROR;
1501
1502 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1503 toHidlVec(keyId), toHidlVec(message),
1504 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1505 if (status == Status::OK) {
1506 signature = toVector(hSignature);
1507 }
1508 err = toStatusT(status);
1509 }
1510 );
1511
1512 return hResult.isOk() ? err : DEAD_OBJECT;
1513}
1514
1515status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001516 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1517 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001518 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001519 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001520
1521 DrmSessionManager::Instance()->useSession(sessionId);
1522
1523 status_t err = UNKNOWN_ERROR;
1524
1525 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1526 toHidlVec(message), toHidlVec(signature),
1527 [&](Status status, bool hMatch) {
1528 if (status == Status::OK) {
1529 match = hMatch;
1530 } else {
1531 match = false;
1532 }
1533 err = toStatusT(status);
1534 }
1535 );
1536
1537 return hResult.isOk() ? err : DEAD_OBJECT;
1538}
1539
1540status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001541 String8 const &algorithm, Vector<uint8_t> const &message,
1542 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001543 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001544 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001545
1546 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1547 return -EPERM;
1548 }
1549
1550 DrmSessionManager::Instance()->useSession(sessionId);
1551
1552 status_t err = UNKNOWN_ERROR;
1553
1554 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1555 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1556 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1557 if (status == Status::OK) {
1558 signature = toVector(hSignature);
1559 }
1560 err = toStatusT(status);
1561 }
1562 );
1563
1564 return hResult.isOk() ? err : DEAD_OBJECT;
1565}
1566
Adam Stonefb679e32018-02-07 10:25:48 -08001567void DrmHal::reportFrameworkMetrics() const
1568{
Robert Shih82ea6be2019-11-07 17:47:23 -08001569 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1570 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001571 String8 vendor;
1572 String8 description;
1573 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1574 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001575 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001576 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001577 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001578 }
1579 result = getPropertyStringInternal(String8("description"), description);
1580 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001581 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001582 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001583 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001584 }
Adam Stoneab394d12017-12-22 12:34:20 -08001585
Adam Stonefb679e32018-02-07 10:25:48 -08001586 std::string serializedMetrics;
1587 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1588 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001589 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001590 }
Adam Stone32494f52018-02-26 22:53:27 -08001591 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1592 serializedMetrics.size());
1593 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001594 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001595 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001596 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001597 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001598 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001599 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001600}
1601
1602void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001603{
Adam Stone32494f52018-02-26 22:53:27 -08001604 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001605 String8 vendor;
1606 String8 description;
1607 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1608 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001609 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1610 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1611 metricsVector.size());
1612 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001613 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001614 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001615 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001616 }
1617 }
1618}
1619
Jeff Tinkera53d6552017-01-20 00:31:46 -08001620} // namespace android