blob: 53a7446b693d70bdd0951bae6971afc32e49ebf3 [file] [log] [blame]
Jeff Tinkera53d6552017-01-20 00:31:46 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmHal"
Adam Stonefb679e32018-02-07 10:25:48 -080019#include <iomanip>
20
Jeff Tinkera53d6552017-01-20 00:31:46 -080021#include <utils/Log.h>
22
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080025
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070026#include <android/hardware/drm/1.2/types.h>
Peter Kalauskasca5642c2018-11-12 12:34:42 -080027#include <android/hidl/manager/1.2/IServiceManager.h>
Chong Zhang181e6952019-10-09 13:23:39 -070028#include <android/media/BnResourceManagerClient.h>
Jeff Tinker593111f2017-05-25 16:00:21 -070029#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080030#include <media/EventMetric.h>
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
Chong Zhang181e6952019-10-09 13:23:39 -0700301struct DrmHal::DrmSessionClient : public android::media::BnResourceManagerClient {
302 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
303 : mSessionId(sessionId),
304 mDrm(drm) {}
305
306 ::android::binder::Status reclaimResource(bool* _aidl_return) override;
307 ::android::binder::Status getName(::std::string* _aidl_return) override;
308
309 const Vector<uint8_t> mSessionId;
310
311protected:
312 virtual ~DrmSessionClient();
313
314private:
315 wp<DrmHal> mDrm;
316
317 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
318};
319
320::android::binder::Status DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
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;
324 return ::android::binder::Status::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800325 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700326 status_t err = drm->closeSession(mSessionId);
327 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700328 *_aidl_return = false;
329 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700330 }
331 drm->sendEvent(EventType::SESSION_RECLAIMED,
332 toHidlVec(mSessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700333 *_aidl_return = true;
334 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700335}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800336
Chong Zhang181e6952019-10-09 13:23:39 -0700337::android::binder::Status 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;
352 return ::android::binder::Status::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 Shihc3af31b2019-09-20 21:45:01 -0700760 sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
761 DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
762 mOpenSessions.push(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800763 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800764 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800765
Adam Stonef0e618d2018-01-17 19:20:41 -0800766 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800767 return err;
768}
769
770status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
771 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800772 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800773
Jeff Tinker319d5f42017-07-26 15:44:33 -0700774 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
775 if (status.isOk()) {
776 if (status == Status::OK) {
777 DrmSessionManager::Instance()->removeSession(sessionId);
778 for (size_t i = 0; i < mOpenSessions.size(); i++) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700779 if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700780 mOpenSessions.removeAt(i);
781 break;
782 }
Jeff Tinker61332812017-05-15 16:53:10 -0700783 }
784 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800785 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800786 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800787 mMetrics.mCloseSessionCounter.Increment(response);
788 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800789 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800790 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700791 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800792}
793
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800794static DrmPlugin::KeyRequestType toKeyRequestType(
795 KeyRequestType keyRequestType) {
796 switch (keyRequestType) {
797 case KeyRequestType::INITIAL:
798 return DrmPlugin::kKeyRequestType_Initial;
799 break;
800 case KeyRequestType::RENEWAL:
801 return DrmPlugin::kKeyRequestType_Renewal;
802 break;
803 case KeyRequestType::RELEASE:
804 return DrmPlugin::kKeyRequestType_Release;
805 break;
806 default:
807 return DrmPlugin::kKeyRequestType_Unknown;
808 break;
809 }
810}
811
812static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
813 KeyRequestType_V1_1 keyRequestType) {
814 switch (keyRequestType) {
815 case KeyRequestType_V1_1::NONE:
816 return DrmPlugin::kKeyRequestType_None;
817 break;
818 case KeyRequestType_V1_1::UPDATE:
819 return DrmPlugin::kKeyRequestType_Update;
820 break;
821 default:
822 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
823 break;
824 }
825}
826
Jeff Tinkera53d6552017-01-20 00:31:46 -0800827status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
828 Vector<uint8_t> const &initData, String8 const &mimeType,
829 DrmPlugin::KeyType keyType, KeyedVector<String8,
830 String8> const &optionalParameters, Vector<uint8_t> &request,
831 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
832 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800833 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800834 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800835
836 DrmSessionManager::Instance()->useSession(sessionId);
837
838 KeyType hKeyType;
839 if (keyType == DrmPlugin::kKeyType_Streaming) {
840 hKeyType = KeyType::STREAMING;
841 } else if (keyType == DrmPlugin::kKeyType_Offline) {
842 hKeyType = KeyType::OFFLINE;
843 } else if (keyType == DrmPlugin::kKeyType_Release) {
844 hKeyType = KeyType::RELEASE;
845 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800846 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800847 return BAD_VALUE;
848 }
849
850 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
851
852 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800853 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800854
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800855 if (mPluginV1_2 != NULL) {
856 hResult = mPluginV1_2->getKeyRequest_1_2(
857 toHidlVec(sessionId), toHidlVec(initData),
858 toHidlString(mimeType), hKeyType, hOptionalParameters,
859 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
860 KeyRequestType_V1_1 hKeyRequestType,
861 const hidl_string& hDefaultUrl) {
862 if (status == Status_V1_2::OK) {
863 request = toVector(hRequest);
864 defaultUrl = toString8(hDefaultUrl);
865 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
866 }
867 err = toStatusT_1_2(status);
868 });
869 } else if (mPluginV1_1 != NULL) {
870 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800871 toHidlVec(sessionId), toHidlVec(initData),
872 toHidlString(mimeType), hKeyType, hOptionalParameters,
873 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800874 KeyRequestType_V1_1 hKeyRequestType,
875 const hidl_string& hDefaultUrl) {
876 if (status == Status::OK) {
877 request = toVector(hRequest);
878 defaultUrl = toString8(hDefaultUrl);
879 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800880 }
881 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800882 });
883 } else {
884 hResult = mPlugin->getKeyRequest(
885 toHidlVec(sessionId), toHidlVec(initData),
886 toHidlString(mimeType), hKeyType, hOptionalParameters,
887 [&](Status status, const hidl_vec<uint8_t>& hRequest,
888 KeyRequestType hKeyRequestType,
889 const hidl_string& hDefaultUrl) {
890 if (status == Status::OK) {
891 request = toVector(hRequest);
892 defaultUrl = toString8(hDefaultUrl);
893 *keyRequestType = toKeyRequestType(hKeyRequestType);
894 }
895 err = toStatusT(status);
896 });
897 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800898
Adam Stonef0e618d2018-01-17 19:20:41 -0800899 err = hResult.isOk() ? err : DEAD_OBJECT;
900 keyRequestTimer.SetAttribute(err);
901 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800902}
903
904status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
905 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
906 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800907 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700908 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800909
910 DrmSessionManager::Instance()->useSession(sessionId);
911
912 status_t err = UNKNOWN_ERROR;
913
914 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
915 toHidlVec(response),
916 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
917 if (status == Status::OK) {
918 keySetId = toVector(hKeySetId);
919 }
920 err = toStatusT(status);
921 }
922 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800923 err = hResult.isOk() ? err : DEAD_OBJECT;
924 keyResponseTimer.SetAttribute(err);
925 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800926}
927
928status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
929 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800930 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800931
Jeff Tinker58ad4752018-02-16 16:51:59 -0800932 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
933 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800934}
935
936status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
937 Vector<uint8_t> const &keySetId) {
938 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800939 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800940
941 DrmSessionManager::Instance()->useSession(sessionId);
942
Jeff Tinker58ad4752018-02-16 16:51:59 -0800943 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
944 toHidlVec(keySetId));
945 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800946}
947
948status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
949 KeyedVector<String8, String8> &infoMap) const {
950 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800951 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800952
953 DrmSessionManager::Instance()->useSession(sessionId);
954
955 ::KeyedVector hInfoMap;
956
957 status_t err = UNKNOWN_ERROR;
958
959 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
960 [&](Status status, const hidl_vec<KeyValue>& map) {
961 if (status == Status::OK) {
962 infoMap = toKeyedVector(map);
963 }
964 err = toStatusT(status);
965 }
966 );
967
968 return hResult.isOk() ? err : DEAD_OBJECT;
969}
970
971status_t DrmHal::getProvisionRequest(String8 const &certType,
972 String8 const &certAuthority, Vector<uint8_t> &request,
973 String8 &defaultUrl) {
974 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800975 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800976
977 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800978 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800979
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800980 if (mPluginV1_2 != NULL) {
981 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
982 toHidlString(certType), toHidlString(certAuthority),
983 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
984 const hidl_string& hDefaultUrl) {
985 if (status == Status_V1_2::OK) {
986 request = toVector(hRequest);
987 defaultUrl = toString8(hDefaultUrl);
988 }
989 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800990 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800991 );
992 } else {
993 Return<void> hResult = mPlugin->getProvisionRequest(
994 toHidlString(certType), toHidlString(certAuthority),
995 [&](Status status, const hidl_vec<uint8_t>& hRequest,
996 const hidl_string& hDefaultUrl) {
997 if (status == Status::OK) {
998 request = toVector(hRequest);
999 defaultUrl = toString8(hDefaultUrl);
1000 }
1001 err = toStatusT(status);
1002 }
1003 );
1004 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001005
Adam Stonecea91ce2018-01-22 19:23:28 -08001006 err = hResult.isOk() ? err : DEAD_OBJECT;
1007 mMetrics.mGetProvisionRequestCounter.Increment(err);
1008 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001009}
1010
1011status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001012 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001013 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001014 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001015
1016 status_t err = UNKNOWN_ERROR;
1017
1018 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1019 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1020 const hidl_vec<uint8_t>& hWrappedKey) {
1021 if (status == Status::OK) {
1022 certificate = toVector(hCertificate);
1023 wrappedKey = toVector(hWrappedKey);
1024 }
1025 err = toStatusT(status);
1026 }
1027 );
1028
Adam Stonecea91ce2018-01-22 19:23:28 -08001029 err = hResult.isOk() ? err : DEAD_OBJECT;
1030 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1031 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001032}
1033
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001034status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001035 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001036 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001037
1038 status_t err = UNKNOWN_ERROR;
1039
1040 Return<void> hResult = mPlugin->getSecureStops(
1041 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1042 if (status == Status::OK) {
1043 secureStops = toSecureStops(hSecureStops);
1044 }
1045 err = toStatusT(status);
1046 }
1047 );
1048
1049 return hResult.isOk() ? err : DEAD_OBJECT;
1050}
1051
1052
Jeff Tinker15177d72018-01-25 12:57:55 -08001053status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1054 Mutex::Autolock autoLock(mLock);
1055
1056 if (mInitCheck != OK) {
1057 return mInitCheck;
1058 }
1059
1060 if (mPluginV1_1 == NULL) {
1061 return ERROR_DRM_CANNOT_HANDLE;
1062 }
1063
1064 status_t err = UNKNOWN_ERROR;
1065
1066 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1067 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1068 if (status == Status::OK) {
1069 secureStopIds = toSecureStopIds(hSecureStopIds);
1070 }
1071 err = toStatusT(status);
1072 }
1073 );
1074
1075 return hResult.isOk() ? err : DEAD_OBJECT;
1076}
1077
1078
Jeff Tinkera53d6552017-01-20 00:31:46 -08001079status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1080 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001081 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001082
1083 status_t err = UNKNOWN_ERROR;
1084
1085 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1086 [&](Status status, const SecureStop& hSecureStop) {
1087 if (status == Status::OK) {
1088 secureStop = toVector(hSecureStop.opaqueData);
1089 }
1090 err = toStatusT(status);
1091 }
1092 );
1093
1094 return hResult.isOk() ? err : DEAD_OBJECT;
1095}
1096
1097status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1098 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001099 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001100
Jeff Tinker58ad4752018-02-16 16:51:59 -08001101 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001102 if (mPluginV1_1 != NULL) {
1103 SecureStopRelease secureStopRelease;
1104 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001105 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1106 } else {
1107 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001108 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001109 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001110}
1111
Jeff Tinker15177d72018-01-25 12:57:55 -08001112status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1113 Mutex::Autolock autoLock(mLock);
1114
1115 if (mInitCheck != OK) {
1116 return mInitCheck;
1117 }
1118
1119 if (mPluginV1_1 == NULL) {
1120 return ERROR_DRM_CANNOT_HANDLE;
1121 }
1122
Jeff Tinker58ad4752018-02-16 16:51:59 -08001123 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1124 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001125}
1126
1127status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001128 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001129 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001130
Jeff Tinker58ad4752018-02-16 16:51:59 -08001131 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001132 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001133 status = mPluginV1_1->removeAllSecureStops();
1134 } else {
1135 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001136 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001137 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001138}
1139
Jeff Tinker6d998b62017-12-18 14:37:43 -08001140status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1141 DrmPlugin::HdcpLevel *max) const {
1142 Mutex::Autolock autoLock(mLock);
1143 INIT_CHECK();
1144
1145 if (connected == NULL || max == NULL) {
1146 return BAD_VALUE;
1147 }
1148 status_t err = UNKNOWN_ERROR;
1149
Jeff Tinker6d998b62017-12-18 14:37:43 -08001150 *connected = DrmPlugin::kHdcpLevelUnknown;
1151 *max = DrmPlugin::kHdcpLevelUnknown;
1152
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001153 Return<void> hResult;
1154 if (mPluginV1_2 != NULL) {
1155 hResult = mPluginV1_2->getHdcpLevels_1_2(
1156 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1157 if (status == Status_V1_2::OK) {
1158 *connected = toHdcpLevel(hConnected);
1159 *max = toHdcpLevel(hMax);
1160 }
1161 err = toStatusT_1_2(status);
1162 });
1163 } else if (mPluginV1_1 != NULL) {
1164 hResult = mPluginV1_1->getHdcpLevels(
1165 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1166 if (status == Status::OK) {
1167 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1168 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1169 }
1170 err = toStatusT(status);
1171 });
1172 } else {
1173 return ERROR_DRM_CANNOT_HANDLE;
1174 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001175
1176 return hResult.isOk() ? err : DEAD_OBJECT;
1177}
1178
1179status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1180 Mutex::Autolock autoLock(mLock);
1181 INIT_CHECK();
1182
1183 if (open == NULL || max == NULL) {
1184 return BAD_VALUE;
1185 }
1186 status_t err = UNKNOWN_ERROR;
1187
1188 *open = 0;
1189 *max = 0;
1190
1191 if (mPluginV1_1 == NULL) {
1192 return ERROR_DRM_CANNOT_HANDLE;
1193 }
1194
1195 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1196 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1197 if (status == Status::OK) {
1198 *open = hOpen;
1199 *max = hMax;
1200 }
1201 err = toStatusT(status);
1202 }
1203 );
1204
1205 return hResult.isOk() ? err : DEAD_OBJECT;
1206}
1207
1208status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1209 DrmPlugin::SecurityLevel *level) const {
1210 Mutex::Autolock autoLock(mLock);
1211 INIT_CHECK();
1212
1213 if (level == NULL) {
1214 return BAD_VALUE;
1215 }
1216 status_t err = UNKNOWN_ERROR;
1217
1218 if (mPluginV1_1 == NULL) {
1219 return ERROR_DRM_CANNOT_HANDLE;
1220 }
1221
1222 *level = DrmPlugin::kSecurityLevelUnknown;
1223
1224 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1225 [&](Status status, SecurityLevel hLevel) {
1226 if (status == Status::OK) {
1227 *level = toSecurityLevel(hLevel);
1228 }
1229 err = toStatusT(status);
1230 }
1231 );
1232
1233 return hResult.isOk() ? err : DEAD_OBJECT;
1234}
1235
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001236status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1237 Mutex::Autolock autoLock(mLock);
1238
1239 if (mInitCheck != OK) {
1240 return mInitCheck;
1241 }
1242
1243 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001244 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001245 }
1246
1247 status_t err = UNKNOWN_ERROR;
1248
1249 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1250 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1251 if (status == Status::OK) {
1252 keySetIds = toKeySetIds(hKeySetIds);
1253 }
1254 err = toStatusT(status);
1255 }
1256 );
1257
1258 return hResult.isOk() ? err : DEAD_OBJECT;
1259}
1260
1261status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1262 Mutex::Autolock autoLock(mLock);
1263
1264 if (mInitCheck != OK) {
1265 return mInitCheck;
1266 }
1267
1268 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001269 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001270 }
1271
1272 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1273 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1274}
1275
1276status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1277 DrmPlugin::OfflineLicenseState *licenseState) const {
1278 Mutex::Autolock autoLock(mLock);
1279
1280 if (mInitCheck != OK) {
1281 return mInitCheck;
1282 }
1283
1284 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001285 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001286 }
1287 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1288
1289 status_t err = UNKNOWN_ERROR;
1290
1291 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1292 [&](Status status, OfflineLicenseState hLicenseState) {
1293 if (status == Status::OK) {
1294 *licenseState = toOfflineLicenseState(hLicenseState);
1295 }
1296 err = toStatusT(status);
1297 }
1298 );
1299
1300 return hResult.isOk() ? err : DEAD_OBJECT;
1301}
1302
Jeff Tinkera53d6552017-01-20 00:31:46 -08001303status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1304 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001305 return getPropertyStringInternal(name, value);
1306}
1307
1308status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1309 // This function is internal to the class and should only be called while
1310 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001311 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001312
1313 status_t err = UNKNOWN_ERROR;
1314
1315 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1316 [&](Status status, const hidl_string& hValue) {
1317 if (status == Status::OK) {
1318 value = toString8(hValue);
1319 }
1320 err = toStatusT(status);
1321 }
1322 );
1323
1324 return hResult.isOk() ? err : DEAD_OBJECT;
1325}
1326
1327status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1328 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001329 return getPropertyByteArrayInternal(name, value);
1330}
1331
1332status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1333 // This function is internal to the class and should only be called while
1334 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001335 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001336
1337 status_t err = UNKNOWN_ERROR;
1338
1339 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1340 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1341 if (status == Status::OK) {
1342 value = toVector(hValue);
1343 }
1344 err = toStatusT(status);
1345 }
1346 );
1347
Adam Stonecea91ce2018-01-22 19:23:28 -08001348 err = hResult.isOk() ? err : DEAD_OBJECT;
1349 if (name == kPropertyDeviceUniqueId) {
1350 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1351 }
1352 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001353}
1354
1355status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1356 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001357 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001358
Jeff Tinker58ad4752018-02-16 16:51:59 -08001359 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001360 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001361 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001362}
1363
1364status_t DrmHal::setPropertyByteArray(String8 const &name,
1365 Vector<uint8_t> const &value ) const {
1366 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001367 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001368
Jeff Tinker58ad4752018-02-16 16:51:59 -08001369 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001370 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001371 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001372}
1373
Adam Stone28f27c32018-02-05 15:07:48 -08001374status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1375 if (metrics == nullptr) {
1376 return UNEXPECTED_NULL;
1377 }
1378 mMetrics.Export(metrics);
1379
1380 // Append vendor metrics if they are supported.
1381 if (mPluginV1_1 != NULL) {
1382 String8 vendor;
1383 String8 description;
1384 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1385 || vendor.isEmpty()) {
1386 ALOGE("Get vendor failed or is empty");
1387 vendor = "NONE";
1388 }
1389 if (getPropertyStringInternal(String8("description"), description) != OK
1390 || description.isEmpty()) {
1391 ALOGE("Get description failed or is empty.");
1392 description = "NONE";
1393 }
1394 vendor += ".";
1395 vendor += description;
1396
1397 hidl_vec<DrmMetricGroup> pluginMetrics;
1398 status_t err = UNKNOWN_ERROR;
1399
1400 Return<void> status = mPluginV1_1->getMetrics(
1401 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1402 if (status != Status::OK) {
1403 ALOGV("Error getting plugin metrics: %d", status);
1404 } else {
1405 PersistableBundle pluginBundle;
1406 if (MediaDrmMetrics::HidlMetricsToBundle(
1407 pluginMetrics, &pluginBundle) == OK) {
1408 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1409 }
1410 }
1411 err = toStatusT(status);
1412 });
1413 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001414 }
1415
Adam Stoneab394d12017-12-22 12:34:20 -08001416 return OK;
1417}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001418
1419status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1420 String8 const &algorithm) {
1421 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001422 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001423
1424 DrmSessionManager::Instance()->useSession(sessionId);
1425
Jeff Tinkere6412942018-04-30 17:35:16 -07001426 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001427 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001428 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001429}
1430
1431status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1432 String8 const &algorithm) {
1433 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001434 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001435
1436 DrmSessionManager::Instance()->useSession(sessionId);
1437
Jeff Tinkere6412942018-04-30 17:35:16 -07001438 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001439 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001440 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001441}
1442
1443status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001444 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1445 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001446 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001447 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001448
1449 DrmSessionManager::Instance()->useSession(sessionId);
1450
1451 status_t err = UNKNOWN_ERROR;
1452
1453 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1454 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1455 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1456 if (status == Status::OK) {
1457 output = toVector(hOutput);
1458 }
1459 err = toStatusT(status);
1460 }
1461 );
1462
1463 return hResult.isOk() ? err : DEAD_OBJECT;
1464}
1465
1466status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001467 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1468 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001469 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001470 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001471
1472 DrmSessionManager::Instance()->useSession(sessionId);
1473
1474 status_t err = UNKNOWN_ERROR;
1475
1476 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1477 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1478 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1479 if (status == Status::OK) {
1480 output = toVector(hOutput);
1481 }
1482 err = toStatusT(status);
1483 }
1484 );
1485
1486 return hResult.isOk() ? err : DEAD_OBJECT;
1487}
1488
1489status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001490 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1491 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001492 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001493 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001494
1495 DrmSessionManager::Instance()->useSession(sessionId);
1496
1497 status_t err = UNKNOWN_ERROR;
1498
1499 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1500 toHidlVec(keyId), toHidlVec(message),
1501 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1502 if (status == Status::OK) {
1503 signature = toVector(hSignature);
1504 }
1505 err = toStatusT(status);
1506 }
1507 );
1508
1509 return hResult.isOk() ? err : DEAD_OBJECT;
1510}
1511
1512status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001513 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1514 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001515 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001516 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001517
1518 DrmSessionManager::Instance()->useSession(sessionId);
1519
1520 status_t err = UNKNOWN_ERROR;
1521
1522 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1523 toHidlVec(message), toHidlVec(signature),
1524 [&](Status status, bool hMatch) {
1525 if (status == Status::OK) {
1526 match = hMatch;
1527 } else {
1528 match = false;
1529 }
1530 err = toStatusT(status);
1531 }
1532 );
1533
1534 return hResult.isOk() ? err : DEAD_OBJECT;
1535}
1536
1537status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001538 String8 const &algorithm, Vector<uint8_t> const &message,
1539 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001540 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001541 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001542
1543 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1544 return -EPERM;
1545 }
1546
1547 DrmSessionManager::Instance()->useSession(sessionId);
1548
1549 status_t err = UNKNOWN_ERROR;
1550
1551 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1552 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1553 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1554 if (status == Status::OK) {
1555 signature = toVector(hSignature);
1556 }
1557 err = toStatusT(status);
1558 }
1559 );
1560
1561 return hResult.isOk() ? err : DEAD_OBJECT;
1562}
1563
Adam Stonefb679e32018-02-07 10:25:48 -08001564void DrmHal::reportFrameworkMetrics() const
1565{
Ray Essick6a305222019-01-28 20:33:18 -08001566 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
Ray Essick6a305222019-01-28 20:33:18 -08001567 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001568 String8 vendor;
1569 String8 description;
1570 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1571 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001572 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001573 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001574 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001575 }
1576 result = getPropertyStringInternal(String8("description"), description);
1577 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001578 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001579 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001580 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001581 }
Adam Stoneab394d12017-12-22 12:34:20 -08001582
Adam Stonefb679e32018-02-07 10:25:48 -08001583 std::string serializedMetrics;
1584 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1585 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001586 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001587 }
Adam Stone32494f52018-02-26 22:53:27 -08001588 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1589 serializedMetrics.size());
1590 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001591 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001592 }
Ray Essick6a305222019-01-28 20:33:18 -08001593 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001594 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001595 }
1596}
1597
1598void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001599{
Adam Stone32494f52018-02-26 22:53:27 -08001600 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001601 String8 vendor;
1602 String8 description;
1603 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1604 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001605 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1606 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1607 metricsVector.size());
1608 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1609 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001610 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001611 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001612 }
1613 }
1614}
1615
Jeff Tinkera53d6552017-01-20 00:31:46 -08001616} // namespace android