blob: 2dc94fee4c9c6c9ad09ab656d88fda0994c252dc [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>
John W. Bruce33ecc4f2017-04-03 16:49:05 -070031#include <media/PluginMetricsReporting.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080032#include <media/drm/DrmAPI.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AString.h>
Adam Stone32494f52018-02-26 22:53:27 -080035#include <media/stagefright/foundation/base64.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080036#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/MediaErrors.h>
Jeff Tinker7d2c6e82018-02-16 16:14:59 -080038#include <mediadrm/DrmHal.h>
39#include <mediadrm/DrmSessionClientInterface.h>
40#include <mediadrm/DrmSessionManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080041
Robert Shih61e1c762019-10-31 21:26:58 -070042#include <vector>
43
Jeff Tinker6d998b62017-12-18 14:37:43 -080044using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080045using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::KeyType;
47using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080049using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080050using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070051using drm::V1_1::HdcpLevel;
52using drm::V1_1::SecureStopRelease;
53using drm::V1_1::SecurityLevel;
54using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070055using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080056using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080057using ::android::hardware::hidl_array;
58using ::android::hardware::hidl_string;
59using ::android::hardware::hidl_vec;
60using ::android::hardware::Return;
61using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080062using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080063using ::android::sp;
64
Jeff Tinkerb8684f32018-12-12 08:41:31 -080065typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
66typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080067typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080068
Adam Stonecea91ce2018-01-22 19:23:28 -080069namespace {
70
71// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
72// in the MediaDrm API.
73constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080074constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080075
Adam Stone32494f52018-02-26 22:53:27 -080076template<typename T>
77std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070078 // Note that the base 64 conversion only works with arrays of single-byte
79 // values. If the source is empty or is not an array of single-byte values,
80 // return empty string.
81 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080082 return "";
83 }
Adam Stone32494f52018-02-26 22:53:27 -080084
85 android::AString outputString;
86 encodeBase64(data, size, &outputString);
87 // Remove trailing equals padding if it exists.
88 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
89 outputString.erase(outputString.size() - 1, 1);
90 }
91
92 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080093}
94
Adam Stone32494f52018-02-26 22:53:27 -080095} // anonymous namespace
96
Jeff Tinkera53d6552017-01-20 00:31:46 -080097namespace android {
98
Jeff Tinker6d998b62017-12-18 14:37:43 -080099#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
100
Jeff Tinkera53d6552017-01-20 00:31:46 -0800101static inline int getCallingPid() {
102 return IPCThreadState::self()->getCallingPid();
103}
104
105static bool checkPermission(const char* permissionString) {
106 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
107 bool ok = checkCallingPermission(String16(permissionString));
108 if (!ok) ALOGE("Request requires %s", permissionString);
109 return ok;
110}
111
112static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
113 Vector<uint8_t> vector;
114 vector.appendArray(vec.data(), vec.size());
115 return *const_cast<const Vector<uint8_t> *>(&vector);
116}
117
118static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
119 hidl_vec<uint8_t> vec;
120 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
121 return vec;
122}
123
124static String8 toString8(const hidl_string &string) {
125 return String8(string.c_str());
126}
127
128static hidl_string toHidlString(const String8& string) {
129 return hidl_string(string.string());
130}
131
Jeff Tinker6d998b62017-12-18 14:37:43 -0800132static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
133 switch(level) {
134 case SecurityLevel::SW_SECURE_CRYPTO:
135 return DrmPlugin::kSecurityLevelSwSecureCrypto;
136 case SecurityLevel::SW_SECURE_DECODE:
137 return DrmPlugin::kSecurityLevelSwSecureDecode;
138 case SecurityLevel::HW_SECURE_CRYPTO:
139 return DrmPlugin::kSecurityLevelHwSecureCrypto;
140 case SecurityLevel::HW_SECURE_DECODE:
141 return DrmPlugin::kSecurityLevelHwSecureDecode;
142 case SecurityLevel::HW_SECURE_ALL:
143 return DrmPlugin::kSecurityLevelHwSecureAll;
144 default:
145 return DrmPlugin::kSecurityLevelUnknown;
146 }
147}
148
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800149static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
150 switch(level) {
151 case DrmPlugin::kSecurityLevelSwSecureCrypto:
152 return SecurityLevel::SW_SECURE_CRYPTO;
153 case DrmPlugin::kSecurityLevelSwSecureDecode:
154 return SecurityLevel::SW_SECURE_DECODE;
155 case DrmPlugin::kSecurityLevelHwSecureCrypto:
156 return SecurityLevel::HW_SECURE_CRYPTO;
157 case DrmPlugin::kSecurityLevelHwSecureDecode:
158 return SecurityLevel::HW_SECURE_DECODE;
159 case DrmPlugin::kSecurityLevelHwSecureAll:
160 return SecurityLevel::HW_SECURE_ALL;
161 default:
162 return SecurityLevel::UNKNOWN;
163 }
164}
165
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700166static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
167 OfflineLicenseState licenseState) {
168 switch(licenseState) {
169 case OfflineLicenseState::USABLE:
170 return DrmPlugin::kOfflineLicenseStateUsable;
171 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800172 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700173 default:
174 return DrmPlugin::kOfflineLicenseStateUnknown;
175 }
176}
177
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800178static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800179 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800180 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800181 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800182 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800183 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800184 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800185 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800186 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800187 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800188 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800189 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800190 case HdcpLevel_V1_2::HDCP_V2_3:
191 return DrmPlugin::kHdcpV2_3;
192 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800193 return DrmPlugin::kHdcpNoOutput;
194 default:
195 return DrmPlugin::kHdcpLevelUnknown;
196 }
197}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800198static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
199 keyedVector) {
200 std::vector<KeyValue> stdKeyedVector;
201 for (size_t i = 0; i < keyedVector.size(); i++) {
202 KeyValue keyValue;
203 keyValue.key = toHidlString(keyedVector.keyAt(i));
204 keyValue.value = toHidlString(keyedVector.valueAt(i));
205 stdKeyedVector.push_back(keyValue);
206 }
207 return ::KeyedVector(stdKeyedVector);
208}
209
210static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
211 hKeyedVector) {
212 KeyedVector<String8, String8> keyedVector;
213 for (size_t i = 0; i < hKeyedVector.size(); i++) {
214 keyedVector.add(toString8(hKeyedVector[i].key),
215 toString8(hKeyedVector[i].value));
216 }
217 return keyedVector;
218}
219
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800220static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800221 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800222 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800223 for (size_t i = 0; i < hSecureStops.size(); i++) {
224 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
225 }
226 return secureStops;
227}
228
Jeff Tinker15177d72018-01-25 12:57:55 -0800229static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
230 hSecureStopIds) {
231 List<Vector<uint8_t>> secureStopIds;
232 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
233 secureStopIds.push_back(toVector(hSecureStopIds[i]));
234 }
235 return secureStopIds;
236}
237
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700238static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
239 hKeySetIds) {
240 List<Vector<uint8_t>> keySetIds;
241 for (size_t i = 0; i < hKeySetIds.size(); i++) {
242 keySetIds.push_back(toVector(hKeySetIds[i]));
243 }
244 return keySetIds;
245}
246
Jeff Tinkera53d6552017-01-20 00:31:46 -0800247static status_t toStatusT(Status status) {
248 switch (status) {
249 case Status::OK:
250 return OK;
251 break;
252 case Status::ERROR_DRM_NO_LICENSE:
253 return ERROR_DRM_NO_LICENSE;
254 break;
255 case Status::ERROR_DRM_LICENSE_EXPIRED:
256 return ERROR_DRM_LICENSE_EXPIRED;
257 break;
258 case Status::ERROR_DRM_SESSION_NOT_OPENED:
259 return ERROR_DRM_SESSION_NOT_OPENED;
260 break;
261 case Status::ERROR_DRM_CANNOT_HANDLE:
262 return ERROR_DRM_CANNOT_HANDLE;
263 break;
264 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800265 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800266 break;
267 case Status::BAD_VALUE:
268 return BAD_VALUE;
269 break;
270 case Status::ERROR_DRM_NOT_PROVISIONED:
271 return ERROR_DRM_NOT_PROVISIONED;
272 break;
273 case Status::ERROR_DRM_RESOURCE_BUSY:
274 return ERROR_DRM_RESOURCE_BUSY;
275 break;
276 case Status::ERROR_DRM_DEVICE_REVOKED:
277 return ERROR_DRM_DEVICE_REVOKED;
278 break;
279 case Status::ERROR_DRM_UNKNOWN:
280 default:
281 return ERROR_DRM_UNKNOWN;
282 break;
283 }
284}
285
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800286static status_t toStatusT_1_2(Status_V1_2 status) {
287 switch (status) {
288 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
289 return ERROR_DRM_RESOURCE_CONTENTION;
290 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
291 return ERROR_DRM_FRAME_TOO_LARGE;
292 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
293 return ERROR_DRM_INSUFFICIENT_SECURITY;
294 default:
295 return toStatusT(static_cast<Status>(status));
296 }
297}
298
Jeff Tinkera53d6552017-01-20 00:31:46 -0800299Mutex DrmHal::mLock;
300
Robert Shih0f3a8a02019-11-14 15:43:39 -0800301struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700302 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
303 : mSessionId(sessionId),
304 mDrm(drm) {}
305
Robert Shih0f3a8a02019-11-14 15:43:39 -0800306 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
307 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700308
309 const Vector<uint8_t> mSessionId;
310
Chong Zhang181e6952019-10-09 13:23:39 -0700311 virtual ~DrmSessionClient();
312
313private:
314 wp<DrmHal> mDrm;
315
316 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
317};
318
Robert Shih0f3a8a02019-11-14 15:43:39 -0800319::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
320 auto sessionId = mSessionId;
Robert Shihc3af31b2019-09-20 21:45:01 -0700321 sp<DrmHal> drm = mDrm.promote();
322 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700323 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800324 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800325 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800326 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700327 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700328 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800329 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700330 }
331 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800332 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700333 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800334 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700335}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800336
Robert Shih0f3a8a02019-11-14 15:43:39 -0800337::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700338 String8 name;
339 sp<DrmHal> drm = mDrm.promote();
340 if (drm == NULL) {
341 name.append("<deleted>");
342 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
343 || name.isEmpty()) {
344 name.append("<Get vendor failed or is empty>");
345 }
346 name.append("[");
347 for (size_t i = 0; i < mSessionId.size(); ++i) {
348 name.appendFormat("%02x", mSessionId[i]);
349 }
350 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700351 *_aidl_return = name;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800352 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700353}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800354
Robert Shihc3af31b2019-09-20 21:45:01 -0700355DrmHal::DrmSessionClient::~DrmSessionClient() {
356 DrmSessionManager::Instance()->removeSession(mSessionId);
357}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800358
359DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700360 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800361 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800362}
363
Jeff Tinker61332812017-05-15 16:53:10 -0700364void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800365 Mutex::Autolock autoLock(mLock);
366 auto openSessions = mOpenSessions;
367 for (size_t i = 0; i < openSessions.size(); i++) {
368 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700369 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800370 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700371 }
372 mOpenSessions.clear();
373}
374
Jeff Tinkera53d6552017-01-20 00:31:46 -0800375DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800376}
377
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800378void DrmHal::cleanup() {
379 closeOpenSessions();
380
381 Mutex::Autolock autoLock(mLock);
382 reportPluginMetrics();
383 reportFrameworkMetrics();
384
385 setListener(NULL);
386 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800387 if (mPluginV1_2 != NULL) {
388 if (!mPluginV1_2->setListener(NULL).isOk()) {
389 mInitCheck = DEAD_OBJECT;
390 }
391 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800392 if (!mPlugin->setListener(NULL).isOk()) {
393 mInitCheck = DEAD_OBJECT;
394 }
395 }
396 mPlugin.clear();
397 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700398 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800399}
400
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800401Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
402 Vector<sp<IDrmFactory>> factories;
403
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800404 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800405
406 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800407 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800408 [&factories](const hidl_vec<hidl_string> &registered) {
409 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000410 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800411 if (factory != NULL) {
412 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000413 }
414 }
415 }
416 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800417 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000418 [&factories](const hidl_vec<hidl_string> &registered) {
419 for (const auto &instance : registered) {
420 auto factory = drm::V1_1::IDrmFactory::getService(instance);
421 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000422 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800423 }
424 }
425 }
426 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700427 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700428 [&factories](const hidl_vec<hidl_string> &registered) {
429 for (const auto &instance : registered) {
430 auto factory = drm::V1_2::IDrmFactory::getService(instance);
431 if (factory != NULL) {
432 factories.push_back(factory);
433 }
434 }
435 }
436 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800438
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800439 if (factories.size() == 0) {
440 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700441 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800442 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000443 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800444 factories.push_back(passthrough);
445 } else {
446 ALOGE("Failed to find any drm factories");
447 }
448 }
449 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800450}
451
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800452sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
453 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800454 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800455 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800456
457 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800458 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800459 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800460 if (status != Status::OK) {
461 ALOGE("Failed to make drm plugin");
462 return;
463 }
464 plugin = hPlugin;
465 }
466 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700467
468 if (!hResult.isOk()) {
469 ALOGE("createPlugin remote call failed");
470 }
471
Jeff Tinkera53d6552017-01-20 00:31:46 -0800472 return plugin;
473}
474
475status_t DrmHal::initCheck() const {
476 return mInitCheck;
477}
478
479status_t DrmHal::setListener(const sp<IDrmClient>& listener)
480{
481 Mutex::Autolock lock(mEventLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800482 mListener = listener;
483 return NO_ERROR;
484}
485
486Return<void> DrmHal::sendEvent(EventType hEventType,
487 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800488 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800489
490 mEventLock.lock();
491 sp<IDrmClient> listener = mListener;
492 mEventLock.unlock();
493
494 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800495 Mutex::Autolock lock(mNotifyLock);
496 DrmPlugin::EventType eventType;
497 switch(hEventType) {
498 case EventType::PROVISION_REQUIRED:
499 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
500 break;
501 case EventType::KEY_NEEDED:
502 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
503 break;
504 case EventType::KEY_EXPIRED:
505 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
506 break;
507 case EventType::VENDOR_DEFINED:
508 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
509 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700510 case EventType::SESSION_RECLAIMED:
511 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
512 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800513 default:
514 return Void();
515 }
Robert Shih61e1c762019-10-31 21:26:58 -0700516 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800517 }
518 return Void();
519}
520
521Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
522 int64_t expiryTimeInMS) {
523
524 mEventLock.lock();
525 sp<IDrmClient> listener = mListener;
526 mEventLock.unlock();
527
528 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800529 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700530 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800531 }
532 return Void();
533}
534
535Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700536 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
537 std::vector<KeyStatus> keyStatusVec;
538 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
539 keyStatusVec.push_back({keyStatus_V1_0.keyId,
540 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
541 }
542 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
543 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
544}
545
546Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700547 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800548
549 mEventLock.lock();
550 sp<IDrmClient> listener = mListener;
551 mEventLock.unlock();
552
553 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700554 std::vector<DrmKeyStatus> keyStatusList;
555 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800556 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700557 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800558 uint32_t type;
559 switch(keyStatus.type) {
560 case KeyStatusType::USABLE:
561 type = DrmPlugin::kKeyStatusType_Usable;
562 break;
563 case KeyStatusType::EXPIRED:
564 type = DrmPlugin::kKeyStatusType_Expired;
565 break;
566 case KeyStatusType::OUTPUTNOTALLOWED:
567 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
568 break;
569 case KeyStatusType::STATUSPENDING:
570 type = DrmPlugin::kKeyStatusType_StatusPending;
571 break;
Robert Shiha5033262019-05-06 14:15:12 -0700572 case KeyStatusType::USABLEINFUTURE:
573 type = DrmPlugin::kKeyStatusType_UsableInFuture;
574 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800575 case KeyStatusType::INTERNALERROR:
576 default:
577 type = DrmPlugin::kKeyStatusType_InternalError;
578 break;
579 }
Robert Shih61e1c762019-10-31 21:26:58 -0700580 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800581 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800582 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800583
584 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700585 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800586 } else {
587 // There's no listener. But we still want to count the key change
588 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700589 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800590 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700591 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800592 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800593 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800594
Jeff Tinkera53d6552017-01-20 00:31:46 -0800595 return Void();
596}
597
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800598Return<void> DrmHal::sendSessionLostState(
599 const hidl_vec<uint8_t>& sessionId) {
600
601 mEventLock.lock();
602 sp<IDrmClient> listener = mListener;
603 mEventLock.unlock();
604
605 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800606 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700607 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800608 }
609 return Void();
610}
611
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800612status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
613 const uint8_t uuid[16],
614 const String8 &mimeType,
615 DrmPlugin::SecurityLevel level,
616 bool *isSupported) {
617 *isSupported = false;
618
619 // handle default value cases
620 if (level == DrmPlugin::kSecurityLevelUnknown) {
621 if (mimeType == "") {
622 // isCryptoSchemeSupported(uuid)
623 *isSupported = true;
624 } else {
625 // isCryptoSchemeSupported(uuid, mimeType)
626 *isSupported = factory->isContentTypeSupported(mimeType.string());
627 }
628 return OK;
629 } else if (mimeType == "") {
630 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800631 }
632
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800633 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
634 if (factoryV1_2 == NULL) {
635 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800636 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800637 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
638 mimeType.string(), toHidlSecurityLevel(level));
639 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800640 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800641}
642
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800643status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
644 const String8 &mimeType,
645 DrmPlugin::SecurityLevel level,
646 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800647 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800648 *isSupported = false;
649 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
650 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
651 return matchMimeTypeAndSecurityLevel(mFactories[i],
652 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800653 }
654 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800655 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800656}
657
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800658status_t DrmHal::createPlugin(const uint8_t uuid[16],
659 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800660 Mutex::Autolock autoLock(mLock);
661
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800662 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800663 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800664 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
665 if (plugin != NULL) {
666 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800667 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700668 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800669 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800670 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800671 }
672 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800673
674 if (mPlugin == NULL) {
675 mInitCheck = ERROR_UNSUPPORTED;
676 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800677 mInitCheck = OK;
678 if (mPluginV1_2 != NULL) {
679 if (!mPluginV1_2->setListener(this).isOk()) {
680 mInitCheck = DEAD_OBJECT;
681 }
682 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700683 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800684 }
685 if (mInitCheck != OK) {
686 mPlugin.clear();
687 mPluginV1_1.clear();
688 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700689 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800690 }
691
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800692
Jeff Tinkera53d6552017-01-20 00:31:46 -0800693 return mInitCheck;
694}
695
696status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800697 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800698 return OK;
699}
700
Jeff Tinker41d279a2018-02-11 19:52:08 +0000701status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
702 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800703 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800704 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800705
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800706 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000707 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000708
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800709 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000710 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800711 } else {
712 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
713 return ERROR_DRM_CANNOT_HANDLE;
714 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000715 }
716
717 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800718 bool retry = true;
719 do {
720 hidl_vec<uint8_t> hSessionId;
721
Jeff Tinker41d279a2018-02-11 19:52:08 +0000722 Return<void> hResult;
723 if (mPluginV1_1 == NULL || !setSecurityLevel) {
724 hResult = mPlugin->openSession(
725 [&](Status status,const hidl_vec<uint8_t>& id) {
726 if (status == Status::OK) {
727 sessionId = toVector(id);
728 }
729 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800730 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000731 );
732 } else {
733 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
734 [&](Status status, const hidl_vec<uint8_t>& id) {
735 if (status == Status::OK) {
736 sessionId = toVector(id);
737 }
738 err = toStatusT(status);
739 }
740 );
741 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800742
743 if (!hResult.isOk()) {
744 err = DEAD_OBJECT;
745 }
746
747 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
748 mLock.unlock();
749 // reclaimSession may call back to closeSession, since mLock is
750 // shared between Drm instances, we should unlock here to avoid
751 // deadlock.
752 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
753 mLock.lock();
754 } else {
755 retry = false;
756 }
757 } while (retry);
758
759 if (err == OK) {
Robert Shih0f3a8a02019-11-14 15:43:39 -0800760 std::shared_ptr<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
761 DrmSessionManager::Instance()->addSession(getCallingPid(),
762 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
763 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800764 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800765 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800766
Adam Stonef0e618d2018-01-17 19:20:41 -0800767 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800768 return err;
769}
770
771status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
772 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800773 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800774
Jeff Tinker319d5f42017-07-26 15:44:33 -0700775 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
776 if (status.isOk()) {
777 if (status == Status::OK) {
778 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800779 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
780 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
781 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700782 break;
783 }
Jeff Tinker61332812017-05-15 16:53:10 -0700784 }
785 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800786 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800787 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800788 mMetrics.mCloseSessionCounter.Increment(response);
789 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800790 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800791 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700792 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800793}
794
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800795static DrmPlugin::KeyRequestType toKeyRequestType(
796 KeyRequestType keyRequestType) {
797 switch (keyRequestType) {
798 case KeyRequestType::INITIAL:
799 return DrmPlugin::kKeyRequestType_Initial;
800 break;
801 case KeyRequestType::RENEWAL:
802 return DrmPlugin::kKeyRequestType_Renewal;
803 break;
804 case KeyRequestType::RELEASE:
805 return DrmPlugin::kKeyRequestType_Release;
806 break;
807 default:
808 return DrmPlugin::kKeyRequestType_Unknown;
809 break;
810 }
811}
812
813static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
814 KeyRequestType_V1_1 keyRequestType) {
815 switch (keyRequestType) {
816 case KeyRequestType_V1_1::NONE:
817 return DrmPlugin::kKeyRequestType_None;
818 break;
819 case KeyRequestType_V1_1::UPDATE:
820 return DrmPlugin::kKeyRequestType_Update;
821 break;
822 default:
823 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
824 break;
825 }
826}
827
Jeff Tinkera53d6552017-01-20 00:31:46 -0800828status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
829 Vector<uint8_t> const &initData, String8 const &mimeType,
830 DrmPlugin::KeyType keyType, KeyedVector<String8,
831 String8> const &optionalParameters, Vector<uint8_t> &request,
832 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
833 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800834 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800835 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800836
837 DrmSessionManager::Instance()->useSession(sessionId);
838
839 KeyType hKeyType;
840 if (keyType == DrmPlugin::kKeyType_Streaming) {
841 hKeyType = KeyType::STREAMING;
842 } else if (keyType == DrmPlugin::kKeyType_Offline) {
843 hKeyType = KeyType::OFFLINE;
844 } else if (keyType == DrmPlugin::kKeyType_Release) {
845 hKeyType = KeyType::RELEASE;
846 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800847 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800848 return BAD_VALUE;
849 }
850
851 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
852
853 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800854 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800855
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800856 if (mPluginV1_2 != NULL) {
857 hResult = mPluginV1_2->getKeyRequest_1_2(
858 toHidlVec(sessionId), toHidlVec(initData),
859 toHidlString(mimeType), hKeyType, hOptionalParameters,
860 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
861 KeyRequestType_V1_1 hKeyRequestType,
862 const hidl_string& hDefaultUrl) {
863 if (status == Status_V1_2::OK) {
864 request = toVector(hRequest);
865 defaultUrl = toString8(hDefaultUrl);
866 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
867 }
868 err = toStatusT_1_2(status);
869 });
870 } else if (mPluginV1_1 != NULL) {
871 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800872 toHidlVec(sessionId), toHidlVec(initData),
873 toHidlString(mimeType), hKeyType, hOptionalParameters,
874 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800875 KeyRequestType_V1_1 hKeyRequestType,
876 const hidl_string& hDefaultUrl) {
877 if (status == Status::OK) {
878 request = toVector(hRequest);
879 defaultUrl = toString8(hDefaultUrl);
880 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800881 }
882 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800883 });
884 } else {
885 hResult = mPlugin->getKeyRequest(
886 toHidlVec(sessionId), toHidlVec(initData),
887 toHidlString(mimeType), hKeyType, hOptionalParameters,
888 [&](Status status, const hidl_vec<uint8_t>& hRequest,
889 KeyRequestType hKeyRequestType,
890 const hidl_string& hDefaultUrl) {
891 if (status == Status::OK) {
892 request = toVector(hRequest);
893 defaultUrl = toString8(hDefaultUrl);
894 *keyRequestType = toKeyRequestType(hKeyRequestType);
895 }
896 err = toStatusT(status);
897 });
898 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899
Adam Stonef0e618d2018-01-17 19:20:41 -0800900 err = hResult.isOk() ? err : DEAD_OBJECT;
901 keyRequestTimer.SetAttribute(err);
902 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800903}
904
905status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
906 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
907 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800908 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700909 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800910
911 DrmSessionManager::Instance()->useSession(sessionId);
912
913 status_t err = UNKNOWN_ERROR;
914
915 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
916 toHidlVec(response),
917 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
918 if (status == Status::OK) {
919 keySetId = toVector(hKeySetId);
920 }
921 err = toStatusT(status);
922 }
923 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800924 err = hResult.isOk() ? err : DEAD_OBJECT;
925 keyResponseTimer.SetAttribute(err);
926 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800927}
928
929status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
930 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800931 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800932
Jeff Tinker58ad4752018-02-16 16:51:59 -0800933 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
934 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800935}
936
937status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
938 Vector<uint8_t> const &keySetId) {
939 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800940 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800941
942 DrmSessionManager::Instance()->useSession(sessionId);
943
Jeff Tinker58ad4752018-02-16 16:51:59 -0800944 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
945 toHidlVec(keySetId));
946 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800947}
948
949status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
950 KeyedVector<String8, String8> &infoMap) const {
951 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800952 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800953
954 DrmSessionManager::Instance()->useSession(sessionId);
955
956 ::KeyedVector hInfoMap;
957
958 status_t err = UNKNOWN_ERROR;
959
960 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
961 [&](Status status, const hidl_vec<KeyValue>& map) {
962 if (status == Status::OK) {
963 infoMap = toKeyedVector(map);
964 }
965 err = toStatusT(status);
966 }
967 );
968
969 return hResult.isOk() ? err : DEAD_OBJECT;
970}
971
972status_t DrmHal::getProvisionRequest(String8 const &certType,
973 String8 const &certAuthority, Vector<uint8_t> &request,
974 String8 &defaultUrl) {
975 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800976 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800977
978 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800979 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800980
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800981 if (mPluginV1_2 != NULL) {
982 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
983 toHidlString(certType), toHidlString(certAuthority),
984 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
985 const hidl_string& hDefaultUrl) {
986 if (status == Status_V1_2::OK) {
987 request = toVector(hRequest);
988 defaultUrl = toString8(hDefaultUrl);
989 }
990 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800991 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800992 );
993 } else {
994 Return<void> hResult = mPlugin->getProvisionRequest(
995 toHidlString(certType), toHidlString(certAuthority),
996 [&](Status status, const hidl_vec<uint8_t>& hRequest,
997 const hidl_string& hDefaultUrl) {
998 if (status == Status::OK) {
999 request = toVector(hRequest);
1000 defaultUrl = toString8(hDefaultUrl);
1001 }
1002 err = toStatusT(status);
1003 }
1004 );
1005 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001006
Adam Stonecea91ce2018-01-22 19:23:28 -08001007 err = hResult.isOk() ? err : DEAD_OBJECT;
1008 mMetrics.mGetProvisionRequestCounter.Increment(err);
1009 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001010}
1011
1012status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001013 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001014 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001015 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001016
1017 status_t err = UNKNOWN_ERROR;
1018
1019 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1020 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1021 const hidl_vec<uint8_t>& hWrappedKey) {
1022 if (status == Status::OK) {
1023 certificate = toVector(hCertificate);
1024 wrappedKey = toVector(hWrappedKey);
1025 }
1026 err = toStatusT(status);
1027 }
1028 );
1029
Adam Stonecea91ce2018-01-22 19:23:28 -08001030 err = hResult.isOk() ? err : DEAD_OBJECT;
1031 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1032 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001033}
1034
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001035status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001036 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001037 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001038
1039 status_t err = UNKNOWN_ERROR;
1040
1041 Return<void> hResult = mPlugin->getSecureStops(
1042 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1043 if (status == Status::OK) {
1044 secureStops = toSecureStops(hSecureStops);
1045 }
1046 err = toStatusT(status);
1047 }
1048 );
1049
1050 return hResult.isOk() ? err : DEAD_OBJECT;
1051}
1052
1053
Jeff Tinker15177d72018-01-25 12:57:55 -08001054status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1055 Mutex::Autolock autoLock(mLock);
1056
1057 if (mInitCheck != OK) {
1058 return mInitCheck;
1059 }
1060
1061 if (mPluginV1_1 == NULL) {
1062 return ERROR_DRM_CANNOT_HANDLE;
1063 }
1064
1065 status_t err = UNKNOWN_ERROR;
1066
1067 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1068 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1069 if (status == Status::OK) {
1070 secureStopIds = toSecureStopIds(hSecureStopIds);
1071 }
1072 err = toStatusT(status);
1073 }
1074 );
1075
1076 return hResult.isOk() ? err : DEAD_OBJECT;
1077}
1078
1079
Jeff Tinkera53d6552017-01-20 00:31:46 -08001080status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1081 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001082 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001083
1084 status_t err = UNKNOWN_ERROR;
1085
1086 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1087 [&](Status status, const SecureStop& hSecureStop) {
1088 if (status == Status::OK) {
1089 secureStop = toVector(hSecureStop.opaqueData);
1090 }
1091 err = toStatusT(status);
1092 }
1093 );
1094
1095 return hResult.isOk() ? err : DEAD_OBJECT;
1096}
1097
1098status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1099 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001100 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001101
Jeff Tinker58ad4752018-02-16 16:51:59 -08001102 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001103 if (mPluginV1_1 != NULL) {
1104 SecureStopRelease secureStopRelease;
1105 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001106 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1107 } else {
1108 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001109 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001110 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001111}
1112
Jeff Tinker15177d72018-01-25 12:57:55 -08001113status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1114 Mutex::Autolock autoLock(mLock);
1115
1116 if (mInitCheck != OK) {
1117 return mInitCheck;
1118 }
1119
1120 if (mPluginV1_1 == NULL) {
1121 return ERROR_DRM_CANNOT_HANDLE;
1122 }
1123
Jeff Tinker58ad4752018-02-16 16:51:59 -08001124 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1125 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001126}
1127
1128status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001129 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001130 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001131
Jeff Tinker58ad4752018-02-16 16:51:59 -08001132 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001133 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001134 status = mPluginV1_1->removeAllSecureStops();
1135 } else {
1136 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001137 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001138 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001139}
1140
Jeff Tinker6d998b62017-12-18 14:37:43 -08001141status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1142 DrmPlugin::HdcpLevel *max) const {
1143 Mutex::Autolock autoLock(mLock);
1144 INIT_CHECK();
1145
1146 if (connected == NULL || max == NULL) {
1147 return BAD_VALUE;
1148 }
1149 status_t err = UNKNOWN_ERROR;
1150
Jeff Tinker6d998b62017-12-18 14:37:43 -08001151 *connected = DrmPlugin::kHdcpLevelUnknown;
1152 *max = DrmPlugin::kHdcpLevelUnknown;
1153
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001154 Return<void> hResult;
1155 if (mPluginV1_2 != NULL) {
1156 hResult = mPluginV1_2->getHdcpLevels_1_2(
1157 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1158 if (status == Status_V1_2::OK) {
1159 *connected = toHdcpLevel(hConnected);
1160 *max = toHdcpLevel(hMax);
1161 }
1162 err = toStatusT_1_2(status);
1163 });
1164 } else if (mPluginV1_1 != NULL) {
1165 hResult = mPluginV1_1->getHdcpLevels(
1166 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1167 if (status == Status::OK) {
1168 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1169 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1170 }
1171 err = toStatusT(status);
1172 });
1173 } else {
1174 return ERROR_DRM_CANNOT_HANDLE;
1175 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001176
1177 return hResult.isOk() ? err : DEAD_OBJECT;
1178}
1179
1180status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1181 Mutex::Autolock autoLock(mLock);
1182 INIT_CHECK();
1183
1184 if (open == NULL || max == NULL) {
1185 return BAD_VALUE;
1186 }
1187 status_t err = UNKNOWN_ERROR;
1188
1189 *open = 0;
1190 *max = 0;
1191
1192 if (mPluginV1_1 == NULL) {
1193 return ERROR_DRM_CANNOT_HANDLE;
1194 }
1195
1196 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1197 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1198 if (status == Status::OK) {
1199 *open = hOpen;
1200 *max = hMax;
1201 }
1202 err = toStatusT(status);
1203 }
1204 );
1205
1206 return hResult.isOk() ? err : DEAD_OBJECT;
1207}
1208
1209status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1210 DrmPlugin::SecurityLevel *level) const {
1211 Mutex::Autolock autoLock(mLock);
1212 INIT_CHECK();
1213
1214 if (level == NULL) {
1215 return BAD_VALUE;
1216 }
1217 status_t err = UNKNOWN_ERROR;
1218
1219 if (mPluginV1_1 == NULL) {
1220 return ERROR_DRM_CANNOT_HANDLE;
1221 }
1222
1223 *level = DrmPlugin::kSecurityLevelUnknown;
1224
1225 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1226 [&](Status status, SecurityLevel hLevel) {
1227 if (status == Status::OK) {
1228 *level = toSecurityLevel(hLevel);
1229 }
1230 err = toStatusT(status);
1231 }
1232 );
1233
1234 return hResult.isOk() ? err : DEAD_OBJECT;
1235}
1236
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001237status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1238 Mutex::Autolock autoLock(mLock);
1239
1240 if (mInitCheck != OK) {
1241 return mInitCheck;
1242 }
1243
1244 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001245 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001246 }
1247
1248 status_t err = UNKNOWN_ERROR;
1249
1250 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1251 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1252 if (status == Status::OK) {
1253 keySetIds = toKeySetIds(hKeySetIds);
1254 }
1255 err = toStatusT(status);
1256 }
1257 );
1258
1259 return hResult.isOk() ? err : DEAD_OBJECT;
1260}
1261
1262status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1263 Mutex::Autolock autoLock(mLock);
1264
1265 if (mInitCheck != OK) {
1266 return mInitCheck;
1267 }
1268
1269 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001270 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001271 }
1272
1273 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1274 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1275}
1276
1277status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1278 DrmPlugin::OfflineLicenseState *licenseState) const {
1279 Mutex::Autolock autoLock(mLock);
1280
1281 if (mInitCheck != OK) {
1282 return mInitCheck;
1283 }
1284
1285 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001286 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001287 }
1288 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1289
1290 status_t err = UNKNOWN_ERROR;
1291
1292 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1293 [&](Status status, OfflineLicenseState hLicenseState) {
1294 if (status == Status::OK) {
1295 *licenseState = toOfflineLicenseState(hLicenseState);
1296 }
1297 err = toStatusT(status);
1298 }
1299 );
1300
1301 return hResult.isOk() ? err : DEAD_OBJECT;
1302}
1303
Jeff Tinkera53d6552017-01-20 00:31:46 -08001304status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1305 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001306 return getPropertyStringInternal(name, value);
1307}
1308
1309status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1310 // This function is internal to the class and should only be called while
1311 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001312 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001313
1314 status_t err = UNKNOWN_ERROR;
1315
1316 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1317 [&](Status status, const hidl_string& hValue) {
1318 if (status == Status::OK) {
1319 value = toString8(hValue);
1320 }
1321 err = toStatusT(status);
1322 }
1323 );
1324
1325 return hResult.isOk() ? err : DEAD_OBJECT;
1326}
1327
1328status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1329 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001330 return getPropertyByteArrayInternal(name, value);
1331}
1332
1333status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1334 // This function is internal to the class and should only be called while
1335 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001336 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001337
1338 status_t err = UNKNOWN_ERROR;
1339
1340 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1341 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1342 if (status == Status::OK) {
1343 value = toVector(hValue);
1344 }
1345 err = toStatusT(status);
1346 }
1347 );
1348
Adam Stonecea91ce2018-01-22 19:23:28 -08001349 err = hResult.isOk() ? err : DEAD_OBJECT;
1350 if (name == kPropertyDeviceUniqueId) {
1351 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1352 }
1353 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001354}
1355
1356status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1357 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001358 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001359
Jeff Tinker58ad4752018-02-16 16:51:59 -08001360 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001361 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001362 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001363}
1364
1365status_t DrmHal::setPropertyByteArray(String8 const &name,
1366 Vector<uint8_t> const &value ) const {
1367 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001368 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001369
Jeff Tinker58ad4752018-02-16 16:51:59 -08001370 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001371 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001372 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001373}
1374
Adam Stone28f27c32018-02-05 15:07:48 -08001375status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1376 if (metrics == nullptr) {
1377 return UNEXPECTED_NULL;
1378 }
1379 mMetrics.Export(metrics);
1380
1381 // Append vendor metrics if they are supported.
1382 if (mPluginV1_1 != NULL) {
1383 String8 vendor;
1384 String8 description;
1385 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1386 || vendor.isEmpty()) {
1387 ALOGE("Get vendor failed or is empty");
1388 vendor = "NONE";
1389 }
1390 if (getPropertyStringInternal(String8("description"), description) != OK
1391 || description.isEmpty()) {
1392 ALOGE("Get description failed or is empty.");
1393 description = "NONE";
1394 }
1395 vendor += ".";
1396 vendor += description;
1397
1398 hidl_vec<DrmMetricGroup> pluginMetrics;
1399 status_t err = UNKNOWN_ERROR;
1400
1401 Return<void> status = mPluginV1_1->getMetrics(
1402 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1403 if (status != Status::OK) {
1404 ALOGV("Error getting plugin metrics: %d", status);
1405 } else {
1406 PersistableBundle pluginBundle;
1407 if (MediaDrmMetrics::HidlMetricsToBundle(
1408 pluginMetrics, &pluginBundle) == OK) {
1409 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1410 }
1411 }
1412 err = toStatusT(status);
1413 });
1414 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001415 }
1416
Adam Stoneab394d12017-12-22 12:34:20 -08001417 return OK;
1418}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001419
1420status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1421 String8 const &algorithm) {
1422 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001423 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001424
1425 DrmSessionManager::Instance()->useSession(sessionId);
1426
Jeff Tinkere6412942018-04-30 17:35:16 -07001427 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001428 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001429 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001430}
1431
1432status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1433 String8 const &algorithm) {
1434 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001435 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001436
1437 DrmSessionManager::Instance()->useSession(sessionId);
1438
Jeff Tinkere6412942018-04-30 17:35:16 -07001439 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001440 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001441 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001442}
1443
1444status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001445 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1446 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001447 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001448 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449
1450 DrmSessionManager::Instance()->useSession(sessionId);
1451
1452 status_t err = UNKNOWN_ERROR;
1453
1454 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1455 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1456 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1457 if (status == Status::OK) {
1458 output = toVector(hOutput);
1459 }
1460 err = toStatusT(status);
1461 }
1462 );
1463
1464 return hResult.isOk() ? err : DEAD_OBJECT;
1465}
1466
1467status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001468 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1469 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001470 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001471 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001472
1473 DrmSessionManager::Instance()->useSession(sessionId);
1474
1475 status_t err = UNKNOWN_ERROR;
1476
1477 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1478 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1479 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1480 if (status == Status::OK) {
1481 output = toVector(hOutput);
1482 }
1483 err = toStatusT(status);
1484 }
1485 );
1486
1487 return hResult.isOk() ? err : DEAD_OBJECT;
1488}
1489
1490status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001491 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1492 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001493 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001494 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001495
1496 DrmSessionManager::Instance()->useSession(sessionId);
1497
1498 status_t err = UNKNOWN_ERROR;
1499
1500 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1501 toHidlVec(keyId), toHidlVec(message),
1502 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1503 if (status == Status::OK) {
1504 signature = toVector(hSignature);
1505 }
1506 err = toStatusT(status);
1507 }
1508 );
1509
1510 return hResult.isOk() ? err : DEAD_OBJECT;
1511}
1512
1513status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001514 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1515 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001516 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001517 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001518
1519 DrmSessionManager::Instance()->useSession(sessionId);
1520
1521 status_t err = UNKNOWN_ERROR;
1522
1523 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1524 toHidlVec(message), toHidlVec(signature),
1525 [&](Status status, bool hMatch) {
1526 if (status == Status::OK) {
1527 match = hMatch;
1528 } else {
1529 match = false;
1530 }
1531 err = toStatusT(status);
1532 }
1533 );
1534
1535 return hResult.isOk() ? err : DEAD_OBJECT;
1536}
1537
1538status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001539 String8 const &algorithm, Vector<uint8_t> const &message,
1540 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001541 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001542 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001543
1544 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1545 return -EPERM;
1546 }
1547
1548 DrmSessionManager::Instance()->useSession(sessionId);
1549
1550 status_t err = UNKNOWN_ERROR;
1551
1552 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1553 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1554 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1555 if (status == Status::OK) {
1556 signature = toVector(hSignature);
1557 }
1558 err = toStatusT(status);
1559 }
1560 );
1561
1562 return hResult.isOk() ? err : DEAD_OBJECT;
1563}
1564
Adam Stonefb679e32018-02-07 10:25:48 -08001565void DrmHal::reportFrameworkMetrics() const
1566{
Ray Essick6a305222019-01-28 20:33:18 -08001567 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
Ray Essick6a305222019-01-28 20:33:18 -08001568 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001569 String8 vendor;
1570 String8 description;
1571 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1572 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001573 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001574 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001575 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001576 }
1577 result = getPropertyStringInternal(String8("description"), description);
1578 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001579 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001580 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001581 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001582 }
Adam Stoneab394d12017-12-22 12:34:20 -08001583
Adam Stonefb679e32018-02-07 10:25:48 -08001584 std::string serializedMetrics;
1585 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1586 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001587 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001588 }
Adam Stone32494f52018-02-26 22:53:27 -08001589 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1590 serializedMetrics.size());
1591 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001592 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001593 }
Ray Essick6a305222019-01-28 20:33:18 -08001594 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001595 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001596 }
1597}
1598
1599void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001600{
Adam Stone32494f52018-02-26 22:53:27 -08001601 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001602 String8 vendor;
1603 String8 description;
1604 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1605 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001606 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1607 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1608 metricsVector.size());
1609 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1610 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001611 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001612 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001613 }
1614 }
1615}
1616
Jeff Tinkera53d6552017-01-20 00:31:46 -08001617} // namespace android