blob: 8a08a7be80a73d87626ec9cf389e7743661ab4d9 [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
Jeff Tinker6d998b62017-12-18 14:37:43 -080042using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080043using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080044using drm::V1_0::KeyType;
45using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080047using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070049using drm::V1_1::HdcpLevel;
50using drm::V1_1::SecureStopRelease;
51using drm::V1_1::SecurityLevel;
52using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070053using drm::V1_2::KeyStatusType;
Adam Stone28f27c32018-02-05 15:07:48 -080054using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080055using ::android::hardware::hidl_array;
56using ::android::hardware::hidl_string;
57using ::android::hardware::hidl_vec;
58using ::android::hardware::Return;
59using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080060using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080061using ::android::sp;
62
Jeff Tinkerb8684f32018-12-12 08:41:31 -080063typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
64typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080065typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080066
Adam Stonecea91ce2018-01-22 19:23:28 -080067namespace {
68
69// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
70// in the MediaDrm API.
71constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080072constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080073
Adam Stone32494f52018-02-26 22:53:27 -080074template<typename T>
75std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070076 // Note that the base 64 conversion only works with arrays of single-byte
77 // values. If the source is empty or is not an array of single-byte values,
78 // return empty string.
79 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080080 return "";
81 }
Adam Stone32494f52018-02-26 22:53:27 -080082
83 android::AString outputString;
84 encodeBase64(data, size, &outputString);
85 // Remove trailing equals padding if it exists.
86 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
87 outputString.erase(outputString.size() - 1, 1);
88 }
89
90 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080091}
92
Adam Stone32494f52018-02-26 22:53:27 -080093} // anonymous namespace
94
Jeff Tinkera53d6552017-01-20 00:31:46 -080095namespace android {
96
Jeff Tinker6d998b62017-12-18 14:37:43 -080097#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
98
Jeff Tinkera53d6552017-01-20 00:31:46 -080099static inline int getCallingPid() {
100 return IPCThreadState::self()->getCallingPid();
101}
102
103static bool checkPermission(const char* permissionString) {
104 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
105 bool ok = checkCallingPermission(String16(permissionString));
106 if (!ok) ALOGE("Request requires %s", permissionString);
107 return ok;
108}
109
110static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
111 Vector<uint8_t> vector;
112 vector.appendArray(vec.data(), vec.size());
113 return *const_cast<const Vector<uint8_t> *>(&vector);
114}
115
116static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
117 hidl_vec<uint8_t> vec;
118 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
119 return vec;
120}
121
122static String8 toString8(const hidl_string &string) {
123 return String8(string.c_str());
124}
125
126static hidl_string toHidlString(const String8& string) {
127 return hidl_string(string.string());
128}
129
Jeff Tinker6d998b62017-12-18 14:37:43 -0800130static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
131 switch(level) {
132 case SecurityLevel::SW_SECURE_CRYPTO:
133 return DrmPlugin::kSecurityLevelSwSecureCrypto;
134 case SecurityLevel::SW_SECURE_DECODE:
135 return DrmPlugin::kSecurityLevelSwSecureDecode;
136 case SecurityLevel::HW_SECURE_CRYPTO:
137 return DrmPlugin::kSecurityLevelHwSecureCrypto;
138 case SecurityLevel::HW_SECURE_DECODE:
139 return DrmPlugin::kSecurityLevelHwSecureDecode;
140 case SecurityLevel::HW_SECURE_ALL:
141 return DrmPlugin::kSecurityLevelHwSecureAll;
142 default:
143 return DrmPlugin::kSecurityLevelUnknown;
144 }
145}
146
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800147static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
148 switch(level) {
149 case DrmPlugin::kSecurityLevelSwSecureCrypto:
150 return SecurityLevel::SW_SECURE_CRYPTO;
151 case DrmPlugin::kSecurityLevelSwSecureDecode:
152 return SecurityLevel::SW_SECURE_DECODE;
153 case DrmPlugin::kSecurityLevelHwSecureCrypto:
154 return SecurityLevel::HW_SECURE_CRYPTO;
155 case DrmPlugin::kSecurityLevelHwSecureDecode:
156 return SecurityLevel::HW_SECURE_DECODE;
157 case DrmPlugin::kSecurityLevelHwSecureAll:
158 return SecurityLevel::HW_SECURE_ALL;
159 default:
160 return SecurityLevel::UNKNOWN;
161 }
162}
163
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700164static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
165 OfflineLicenseState licenseState) {
166 switch(licenseState) {
167 case OfflineLicenseState::USABLE:
168 return DrmPlugin::kOfflineLicenseStateUsable;
169 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800170 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700171 default:
172 return DrmPlugin::kOfflineLicenseStateUnknown;
173 }
174}
175
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800176static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800177 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800178 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800179 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800180 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800181 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800182 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800183 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800184 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800185 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800186 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800187 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800188 case HdcpLevel_V1_2::HDCP_V2_3:
189 return DrmPlugin::kHdcpV2_3;
190 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800191 return DrmPlugin::kHdcpNoOutput;
192 default:
193 return DrmPlugin::kHdcpLevelUnknown;
194 }
195}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800196static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
197 keyedVector) {
198 std::vector<KeyValue> stdKeyedVector;
199 for (size_t i = 0; i < keyedVector.size(); i++) {
200 KeyValue keyValue;
201 keyValue.key = toHidlString(keyedVector.keyAt(i));
202 keyValue.value = toHidlString(keyedVector.valueAt(i));
203 stdKeyedVector.push_back(keyValue);
204 }
205 return ::KeyedVector(stdKeyedVector);
206}
207
208static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
209 hKeyedVector) {
210 KeyedVector<String8, String8> keyedVector;
211 for (size_t i = 0; i < hKeyedVector.size(); i++) {
212 keyedVector.add(toString8(hKeyedVector[i].key),
213 toString8(hKeyedVector[i].value));
214 }
215 return keyedVector;
216}
217
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800218static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800219 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800220 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800221 for (size_t i = 0; i < hSecureStops.size(); i++) {
222 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
223 }
224 return secureStops;
225}
226
Jeff Tinker15177d72018-01-25 12:57:55 -0800227static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
228 hSecureStopIds) {
229 List<Vector<uint8_t>> secureStopIds;
230 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
231 secureStopIds.push_back(toVector(hSecureStopIds[i]));
232 }
233 return secureStopIds;
234}
235
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700236static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
237 hKeySetIds) {
238 List<Vector<uint8_t>> keySetIds;
239 for (size_t i = 0; i < hKeySetIds.size(); i++) {
240 keySetIds.push_back(toVector(hKeySetIds[i]));
241 }
242 return keySetIds;
243}
244
Jeff Tinkera53d6552017-01-20 00:31:46 -0800245static status_t toStatusT(Status status) {
246 switch (status) {
247 case Status::OK:
248 return OK;
249 break;
250 case Status::ERROR_DRM_NO_LICENSE:
251 return ERROR_DRM_NO_LICENSE;
252 break;
253 case Status::ERROR_DRM_LICENSE_EXPIRED:
254 return ERROR_DRM_LICENSE_EXPIRED;
255 break;
256 case Status::ERROR_DRM_SESSION_NOT_OPENED:
257 return ERROR_DRM_SESSION_NOT_OPENED;
258 break;
259 case Status::ERROR_DRM_CANNOT_HANDLE:
260 return ERROR_DRM_CANNOT_HANDLE;
261 break;
262 case Status::ERROR_DRM_INVALID_STATE:
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800263 return ERROR_DRM_INVALID_STATE;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800264 break;
265 case Status::BAD_VALUE:
266 return BAD_VALUE;
267 break;
268 case Status::ERROR_DRM_NOT_PROVISIONED:
269 return ERROR_DRM_NOT_PROVISIONED;
270 break;
271 case Status::ERROR_DRM_RESOURCE_BUSY:
272 return ERROR_DRM_RESOURCE_BUSY;
273 break;
274 case Status::ERROR_DRM_DEVICE_REVOKED:
275 return ERROR_DRM_DEVICE_REVOKED;
276 break;
277 case Status::ERROR_DRM_UNKNOWN:
278 default:
279 return ERROR_DRM_UNKNOWN;
280 break;
281 }
282}
283
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800284static status_t toStatusT_1_2(Status_V1_2 status) {
285 switch (status) {
286 case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
287 return ERROR_DRM_RESOURCE_CONTENTION;
288 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
289 return ERROR_DRM_FRAME_TOO_LARGE;
290 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
291 return ERROR_DRM_INSUFFICIENT_SECURITY;
292 default:
293 return toStatusT(static_cast<Status>(status));
294 }
295}
296
Jeff Tinkera53d6552017-01-20 00:31:46 -0800297Mutex DrmHal::mLock;
298
Chong Zhang181e6952019-10-09 13:23:39 -0700299struct DrmHal::DrmSessionClient : public android::media::BnResourceManagerClient {
300 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
301 : mSessionId(sessionId),
302 mDrm(drm) {}
303
304 ::android::binder::Status reclaimResource(bool* _aidl_return) override;
305 ::android::binder::Status getName(::std::string* _aidl_return) override;
306
307 const Vector<uint8_t> mSessionId;
308
309protected:
310 virtual ~DrmSessionClient();
311
312private:
313 wp<DrmHal> mDrm;
314
315 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
316};
317
318::android::binder::Status DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700319 sp<DrmHal> drm = mDrm.promote();
320 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700321 *_aidl_return = true;
322 return ::android::binder::Status::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800323 }
Robert Shihc3af31b2019-09-20 21:45:01 -0700324 status_t err = drm->closeSession(mSessionId);
325 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700326 *_aidl_return = false;
327 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700328 }
329 drm->sendEvent(EventType::SESSION_RECLAIMED,
330 toHidlVec(mSessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700331 *_aidl_return = true;
332 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700333}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800334
Chong Zhang181e6952019-10-09 13:23:39 -0700335::android::binder::Status DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700336 String8 name;
337 sp<DrmHal> drm = mDrm.promote();
338 if (drm == NULL) {
339 name.append("<deleted>");
340 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
341 || name.isEmpty()) {
342 name.append("<Get vendor failed or is empty>");
343 }
344 name.append("[");
345 for (size_t i = 0; i < mSessionId.size(); ++i) {
346 name.appendFormat("%02x", mSessionId[i]);
347 }
348 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700349 *_aidl_return = name;
350 return ::android::binder::Status::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700351}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800352
Robert Shihc3af31b2019-09-20 21:45:01 -0700353DrmHal::DrmSessionClient::~DrmSessionClient() {
354 DrmSessionManager::Instance()->removeSession(mSessionId);
355}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800356
357DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700358 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800359 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800360}
361
Jeff Tinker61332812017-05-15 16:53:10 -0700362void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800363 Mutex::Autolock autoLock(mLock);
364 auto openSessions = mOpenSessions;
365 for (size_t i = 0; i < openSessions.size(); i++) {
366 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700367 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800368 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700369 }
370 mOpenSessions.clear();
371}
372
Jeff Tinkera53d6552017-01-20 00:31:46 -0800373DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800374}
375
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800376void DrmHal::cleanup() {
377 closeOpenSessions();
378
379 Mutex::Autolock autoLock(mLock);
380 reportPluginMetrics();
381 reportFrameworkMetrics();
382
383 setListener(NULL);
384 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800385 if (mPluginV1_2 != NULL) {
386 if (!mPluginV1_2->setListener(NULL).isOk()) {
387 mInitCheck = DEAD_OBJECT;
388 }
389 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800390 if (!mPlugin->setListener(NULL).isOk()) {
391 mInitCheck = DEAD_OBJECT;
392 }
393 }
394 mPlugin.clear();
395 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700396 mPluginV1_2.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800397}
398
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800399Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
400 Vector<sp<IDrmFactory>> factories;
401
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800402 auto manager = hardware::defaultServiceManager1_2();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800403
404 if (manager != NULL) {
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800405 manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800406 [&factories](const hidl_vec<hidl_string> &registered) {
407 for (const auto &instance : registered) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000408 auto factory = drm::V1_0::IDrmFactory::getService(instance);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800409 if (factory != NULL) {
410 factories.push_back(factory);
Jeff Tinkere307dc42018-02-11 19:53:54 +0000411 }
412 }
413 }
414 );
Peter Kalauskasca5642c2018-11-12 12:34:42 -0800415 manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
Jeff Tinkere307dc42018-02-11 19:53:54 +0000416 [&factories](const hidl_vec<hidl_string> &registered) {
417 for (const auto &instance : registered) {
418 auto factory = drm::V1_1::IDrmFactory::getService(instance);
419 if (factory != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000420 factories.push_back(factory);
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800421 }
422 }
423 }
424 );
Steven Moreland7dcb4db2019-05-13 13:10:51 -0700425 manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700426 [&factories](const hidl_vec<hidl_string> &registered) {
427 for (const auto &instance : registered) {
428 auto factory = drm::V1_2::IDrmFactory::getService(instance);
429 if (factory != NULL) {
430 factories.push_back(factory);
431 }
432 }
433 }
434 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800435 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800436
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800437 if (factories.size() == 0) {
438 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700439 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800440 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000441 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800442 factories.push_back(passthrough);
443 } else {
444 ALOGE("Failed to find any drm factories");
445 }
446 }
447 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800448}
449
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800450sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
451 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800452 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800453 mMetrics.SetAppPackageName(appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800454
455 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800456 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800457 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800458 if (status != Status::OK) {
459 ALOGE("Failed to make drm plugin");
460 return;
461 }
462 plugin = hPlugin;
463 }
464 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700465
466 if (!hResult.isOk()) {
467 ALOGE("createPlugin remote call failed");
468 }
469
Jeff Tinkera53d6552017-01-20 00:31:46 -0800470 return plugin;
471}
472
473status_t DrmHal::initCheck() const {
474 return mInitCheck;
475}
476
477status_t DrmHal::setListener(const sp<IDrmClient>& listener)
478{
479 Mutex::Autolock lock(mEventLock);
480 if (mListener != NULL){
481 IInterface::asBinder(mListener)->unlinkToDeath(this);
482 }
483 if (listener != NULL) {
484 IInterface::asBinder(listener)->linkToDeath(this);
485 }
486 mListener = listener;
487 return NO_ERROR;
488}
489
490Return<void> DrmHal::sendEvent(EventType hEventType,
491 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800492 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800493
494 mEventLock.lock();
495 sp<IDrmClient> listener = mListener;
496 mEventLock.unlock();
497
498 if (listener != NULL) {
499 Parcel obj;
500 writeByteArray(obj, sessionId);
501 writeByteArray(obj, data);
502
503 Mutex::Autolock lock(mNotifyLock);
504 DrmPlugin::EventType eventType;
505 switch(hEventType) {
506 case EventType::PROVISION_REQUIRED:
507 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
508 break;
509 case EventType::KEY_NEEDED:
510 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
511 break;
512 case EventType::KEY_EXPIRED:
513 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
514 break;
515 case EventType::VENDOR_DEFINED:
516 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
517 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700518 case EventType::SESSION_RECLAIMED:
519 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
520 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800521 default:
522 return Void();
523 }
524 listener->notify(eventType, 0, &obj);
525 }
526 return Void();
527}
528
529Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
530 int64_t expiryTimeInMS) {
531
532 mEventLock.lock();
533 sp<IDrmClient> listener = mListener;
534 mEventLock.unlock();
535
536 if (listener != NULL) {
537 Parcel obj;
538 writeByteArray(obj, sessionId);
539 obj.writeInt64(expiryTimeInMS);
540
541 Mutex::Autolock lock(mNotifyLock);
542 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
543 }
544 return Void();
545}
546
547Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700548 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
549 std::vector<KeyStatus> keyStatusVec;
550 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
551 keyStatusVec.push_back({keyStatus_V1_0.keyId,
552 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
553 }
554 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
555 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
556}
557
558Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Jeff Tinkera53d6552017-01-20 00:31:46 -0800559 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
560
561 mEventLock.lock();
562 sp<IDrmClient> listener = mListener;
563 mEventLock.unlock();
564
565 if (listener != NULL) {
566 Parcel obj;
567 writeByteArray(obj, sessionId);
568
569 size_t nKeys = keyStatusList.size();
570 obj.writeInt32(nKeys);
571 for (size_t i = 0; i < nKeys; ++i) {
572 const KeyStatus &keyStatus = keyStatusList[i];
573 writeByteArray(obj, keyStatus.keyId);
574 uint32_t type;
575 switch(keyStatus.type) {
576 case KeyStatusType::USABLE:
577 type = DrmPlugin::kKeyStatusType_Usable;
578 break;
579 case KeyStatusType::EXPIRED:
580 type = DrmPlugin::kKeyStatusType_Expired;
581 break;
582 case KeyStatusType::OUTPUTNOTALLOWED:
583 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
584 break;
585 case KeyStatusType::STATUSPENDING:
586 type = DrmPlugin::kKeyStatusType_StatusPending;
587 break;
Robert Shiha5033262019-05-06 14:15:12 -0700588 case KeyStatusType::USABLEINFUTURE:
589 type = DrmPlugin::kKeyStatusType_UsableInFuture;
590 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800591 case KeyStatusType::INTERNALERROR:
592 default:
593 type = DrmPlugin::kKeyStatusType_InternalError;
594 break;
595 }
596 obj.writeInt32(type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800597 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800598 }
599 obj.writeInt32(hasNewUsableKey);
600
601 Mutex::Autolock lock(mNotifyLock);
602 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
Adam Stonecea91ce2018-01-22 19:23:28 -0800603 } else {
604 // There's no listener. But we still want to count the key change
605 // events.
606 size_t nKeys = keyStatusList.size();
607 for (size_t i = 0; i < nKeys; i++) {
608 mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
609 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800610 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800611
Jeff Tinkera53d6552017-01-20 00:31:46 -0800612 return Void();
613}
614
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800615Return<void> DrmHal::sendSessionLostState(
616 const hidl_vec<uint8_t>& sessionId) {
617
618 mEventLock.lock();
619 sp<IDrmClient> listener = mListener;
620 mEventLock.unlock();
621
622 if (listener != NULL) {
623 Parcel obj;
624 writeByteArray(obj, sessionId);
625 Mutex::Autolock lock(mNotifyLock);
626 listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
627 }
628 return Void();
629}
630
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800631status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
632 const uint8_t uuid[16],
633 const String8 &mimeType,
634 DrmPlugin::SecurityLevel level,
635 bool *isSupported) {
636 *isSupported = false;
637
638 // handle default value cases
639 if (level == DrmPlugin::kSecurityLevelUnknown) {
640 if (mimeType == "") {
641 // isCryptoSchemeSupported(uuid)
642 *isSupported = true;
643 } else {
644 // isCryptoSchemeSupported(uuid, mimeType)
645 *isSupported = factory->isContentTypeSupported(mimeType.string());
646 }
647 return OK;
648 } else if (mimeType == "") {
649 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800650 }
651
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800652 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
653 if (factoryV1_2 == NULL) {
654 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800655 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800656 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
657 mimeType.string(), toHidlSecurityLevel(level));
658 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800659 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800660}
661
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800662status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
663 const String8 &mimeType,
664 DrmPlugin::SecurityLevel level,
665 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800666 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800667 *isSupported = false;
668 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
669 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
670 return matchMimeTypeAndSecurityLevel(mFactories[i],
671 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800672 }
673 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800674 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800675}
676
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800677status_t DrmHal::createPlugin(const uint8_t uuid[16],
678 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800679 Mutex::Autolock autoLock(mLock);
680
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800681 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800682 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800683 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
684 if (plugin != NULL) {
685 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800686 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700687 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800688 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800689 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800690 }
691 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800692
693 if (mPlugin == NULL) {
694 mInitCheck = ERROR_UNSUPPORTED;
695 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800696 mInitCheck = OK;
697 if (mPluginV1_2 != NULL) {
698 if (!mPluginV1_2->setListener(this).isOk()) {
699 mInitCheck = DEAD_OBJECT;
700 }
701 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700702 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800703 }
704 if (mInitCheck != OK) {
705 mPlugin.clear();
706 mPluginV1_1.clear();
707 mPluginV1_2.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700708 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800709 }
710
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800711
Jeff Tinkera53d6552017-01-20 00:31:46 -0800712 return mInitCheck;
713}
714
715status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800716 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800717 return OK;
718}
719
Jeff Tinker41d279a2018-02-11 19:52:08 +0000720status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
721 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800722 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800723 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800724
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800725 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000726 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000727
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800728 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000729 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800730 } else {
731 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
732 return ERROR_DRM_CANNOT_HANDLE;
733 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000734 }
735
736 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800737 bool retry = true;
738 do {
739 hidl_vec<uint8_t> hSessionId;
740
Jeff Tinker41d279a2018-02-11 19:52:08 +0000741 Return<void> hResult;
742 if (mPluginV1_1 == NULL || !setSecurityLevel) {
743 hResult = mPlugin->openSession(
744 [&](Status status,const hidl_vec<uint8_t>& id) {
745 if (status == Status::OK) {
746 sessionId = toVector(id);
747 }
748 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800749 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000750 );
751 } else {
752 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
753 [&](Status status, const hidl_vec<uint8_t>& id) {
754 if (status == Status::OK) {
755 sessionId = toVector(id);
756 }
757 err = toStatusT(status);
758 }
759 );
760 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800761
762 if (!hResult.isOk()) {
763 err = DEAD_OBJECT;
764 }
765
766 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
767 mLock.unlock();
768 // reclaimSession may call back to closeSession, since mLock is
769 // shared between Drm instances, we should unlock here to avoid
770 // deadlock.
771 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
772 mLock.lock();
773 } else {
774 retry = false;
775 }
776 } while (retry);
777
778 if (err == OK) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700779 sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
780 DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
781 mOpenSessions.push(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800782 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800783 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800784
Adam Stonef0e618d2018-01-17 19:20:41 -0800785 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800786 return err;
787}
788
789status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
790 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800791 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800792
Jeff Tinker319d5f42017-07-26 15:44:33 -0700793 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
794 if (status.isOk()) {
795 if (status == Status::OK) {
796 DrmSessionManager::Instance()->removeSession(sessionId);
797 for (size_t i = 0; i < mOpenSessions.size(); i++) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700798 if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700799 mOpenSessions.removeAt(i);
800 break;
801 }
Jeff Tinker61332812017-05-15 16:53:10 -0700802 }
803 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800804 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800805 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800806 mMetrics.mCloseSessionCounter.Increment(response);
807 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800808 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800809 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700810 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800811}
812
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800813static DrmPlugin::KeyRequestType toKeyRequestType(
814 KeyRequestType keyRequestType) {
815 switch (keyRequestType) {
816 case KeyRequestType::INITIAL:
817 return DrmPlugin::kKeyRequestType_Initial;
818 break;
819 case KeyRequestType::RENEWAL:
820 return DrmPlugin::kKeyRequestType_Renewal;
821 break;
822 case KeyRequestType::RELEASE:
823 return DrmPlugin::kKeyRequestType_Release;
824 break;
825 default:
826 return DrmPlugin::kKeyRequestType_Unknown;
827 break;
828 }
829}
830
831static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
832 KeyRequestType_V1_1 keyRequestType) {
833 switch (keyRequestType) {
834 case KeyRequestType_V1_1::NONE:
835 return DrmPlugin::kKeyRequestType_None;
836 break;
837 case KeyRequestType_V1_1::UPDATE:
838 return DrmPlugin::kKeyRequestType_Update;
839 break;
840 default:
841 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
842 break;
843 }
844}
845
Jeff Tinkera53d6552017-01-20 00:31:46 -0800846status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
847 Vector<uint8_t> const &initData, String8 const &mimeType,
848 DrmPlugin::KeyType keyType, KeyedVector<String8,
849 String8> const &optionalParameters, Vector<uint8_t> &request,
850 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
851 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800852 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800853 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800854
855 DrmSessionManager::Instance()->useSession(sessionId);
856
857 KeyType hKeyType;
858 if (keyType == DrmPlugin::kKeyType_Streaming) {
859 hKeyType = KeyType::STREAMING;
860 } else if (keyType == DrmPlugin::kKeyType_Offline) {
861 hKeyType = KeyType::OFFLINE;
862 } else if (keyType == DrmPlugin::kKeyType_Release) {
863 hKeyType = KeyType::RELEASE;
864 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800865 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800866 return BAD_VALUE;
867 }
868
869 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
870
871 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800872 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800873
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800874 if (mPluginV1_2 != NULL) {
875 hResult = mPluginV1_2->getKeyRequest_1_2(
876 toHidlVec(sessionId), toHidlVec(initData),
877 toHidlString(mimeType), hKeyType, hOptionalParameters,
878 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
879 KeyRequestType_V1_1 hKeyRequestType,
880 const hidl_string& hDefaultUrl) {
881 if (status == Status_V1_2::OK) {
882 request = toVector(hRequest);
883 defaultUrl = toString8(hDefaultUrl);
884 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
885 }
886 err = toStatusT_1_2(status);
887 });
888 } else if (mPluginV1_1 != NULL) {
889 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800890 toHidlVec(sessionId), toHidlVec(initData),
891 toHidlString(mimeType), hKeyType, hOptionalParameters,
892 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800893 KeyRequestType_V1_1 hKeyRequestType,
894 const hidl_string& hDefaultUrl) {
895 if (status == Status::OK) {
896 request = toVector(hRequest);
897 defaultUrl = toString8(hDefaultUrl);
898 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899 }
900 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800901 });
902 } else {
903 hResult = mPlugin->getKeyRequest(
904 toHidlVec(sessionId), toHidlVec(initData),
905 toHidlString(mimeType), hKeyType, hOptionalParameters,
906 [&](Status status, const hidl_vec<uint8_t>& hRequest,
907 KeyRequestType hKeyRequestType,
908 const hidl_string& hDefaultUrl) {
909 if (status == Status::OK) {
910 request = toVector(hRequest);
911 defaultUrl = toString8(hDefaultUrl);
912 *keyRequestType = toKeyRequestType(hKeyRequestType);
913 }
914 err = toStatusT(status);
915 });
916 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800917
Adam Stonef0e618d2018-01-17 19:20:41 -0800918 err = hResult.isOk() ? err : DEAD_OBJECT;
919 keyRequestTimer.SetAttribute(err);
920 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800921}
922
923status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
924 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
925 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800926 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700927 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800928
929 DrmSessionManager::Instance()->useSession(sessionId);
930
931 status_t err = UNKNOWN_ERROR;
932
933 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
934 toHidlVec(response),
935 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
936 if (status == Status::OK) {
937 keySetId = toVector(hKeySetId);
938 }
939 err = toStatusT(status);
940 }
941 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800942 err = hResult.isOk() ? err : DEAD_OBJECT;
943 keyResponseTimer.SetAttribute(err);
944 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800945}
946
947status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
948 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800949 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800950
Jeff Tinker58ad4752018-02-16 16:51:59 -0800951 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
952 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800953}
954
955status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
956 Vector<uint8_t> const &keySetId) {
957 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800958 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800959
960 DrmSessionManager::Instance()->useSession(sessionId);
961
Jeff Tinker58ad4752018-02-16 16:51:59 -0800962 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
963 toHidlVec(keySetId));
964 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800965}
966
967status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
968 KeyedVector<String8, String8> &infoMap) const {
969 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800970 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800971
972 DrmSessionManager::Instance()->useSession(sessionId);
973
974 ::KeyedVector hInfoMap;
975
976 status_t err = UNKNOWN_ERROR;
977
978 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
979 [&](Status status, const hidl_vec<KeyValue>& map) {
980 if (status == Status::OK) {
981 infoMap = toKeyedVector(map);
982 }
983 err = toStatusT(status);
984 }
985 );
986
987 return hResult.isOk() ? err : DEAD_OBJECT;
988}
989
990status_t DrmHal::getProvisionRequest(String8 const &certType,
991 String8 const &certAuthority, Vector<uint8_t> &request,
992 String8 &defaultUrl) {
993 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800994 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800995
996 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800997 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800998
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800999 if (mPluginV1_2 != NULL) {
1000 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
1001 toHidlString(certType), toHidlString(certAuthority),
1002 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
1003 const hidl_string& hDefaultUrl) {
1004 if (status == Status_V1_2::OK) {
1005 request = toVector(hRequest);
1006 defaultUrl = toString8(hDefaultUrl);
1007 }
1008 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -08001009 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -08001010 );
1011 } else {
1012 Return<void> hResult = mPlugin->getProvisionRequest(
1013 toHidlString(certType), toHidlString(certAuthority),
1014 [&](Status status, const hidl_vec<uint8_t>& hRequest,
1015 const hidl_string& hDefaultUrl) {
1016 if (status == Status::OK) {
1017 request = toVector(hRequest);
1018 defaultUrl = toString8(hDefaultUrl);
1019 }
1020 err = toStatusT(status);
1021 }
1022 );
1023 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001024
Adam Stonecea91ce2018-01-22 19:23:28 -08001025 err = hResult.isOk() ? err : DEAD_OBJECT;
1026 mMetrics.mGetProvisionRequestCounter.Increment(err);
1027 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001028}
1029
1030status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001031 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001032 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001033 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001034
1035 status_t err = UNKNOWN_ERROR;
1036
1037 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1038 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1039 const hidl_vec<uint8_t>& hWrappedKey) {
1040 if (status == Status::OK) {
1041 certificate = toVector(hCertificate);
1042 wrappedKey = toVector(hWrappedKey);
1043 }
1044 err = toStatusT(status);
1045 }
1046 );
1047
Adam Stonecea91ce2018-01-22 19:23:28 -08001048 err = hResult.isOk() ? err : DEAD_OBJECT;
1049 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1050 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001051}
1052
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001053status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001054 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001055 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001056
1057 status_t err = UNKNOWN_ERROR;
1058
1059 Return<void> hResult = mPlugin->getSecureStops(
1060 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1061 if (status == Status::OK) {
1062 secureStops = toSecureStops(hSecureStops);
1063 }
1064 err = toStatusT(status);
1065 }
1066 );
1067
1068 return hResult.isOk() ? err : DEAD_OBJECT;
1069}
1070
1071
Jeff Tinker15177d72018-01-25 12:57:55 -08001072status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1073 Mutex::Autolock autoLock(mLock);
1074
1075 if (mInitCheck != OK) {
1076 return mInitCheck;
1077 }
1078
1079 if (mPluginV1_1 == NULL) {
1080 return ERROR_DRM_CANNOT_HANDLE;
1081 }
1082
1083 status_t err = UNKNOWN_ERROR;
1084
1085 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1086 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1087 if (status == Status::OK) {
1088 secureStopIds = toSecureStopIds(hSecureStopIds);
1089 }
1090 err = toStatusT(status);
1091 }
1092 );
1093
1094 return hResult.isOk() ? err : DEAD_OBJECT;
1095}
1096
1097
Jeff Tinkera53d6552017-01-20 00:31:46 -08001098status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1099 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001100 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001101
1102 status_t err = UNKNOWN_ERROR;
1103
1104 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1105 [&](Status status, const SecureStop& hSecureStop) {
1106 if (status == Status::OK) {
1107 secureStop = toVector(hSecureStop.opaqueData);
1108 }
1109 err = toStatusT(status);
1110 }
1111 );
1112
1113 return hResult.isOk() ? err : DEAD_OBJECT;
1114}
1115
1116status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1117 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001118 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001119
Jeff Tinker58ad4752018-02-16 16:51:59 -08001120 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001121 if (mPluginV1_1 != NULL) {
1122 SecureStopRelease secureStopRelease;
1123 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001124 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1125 } else {
1126 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001127 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001128 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001129}
1130
Jeff Tinker15177d72018-01-25 12:57:55 -08001131status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1132 Mutex::Autolock autoLock(mLock);
1133
1134 if (mInitCheck != OK) {
1135 return mInitCheck;
1136 }
1137
1138 if (mPluginV1_1 == NULL) {
1139 return ERROR_DRM_CANNOT_HANDLE;
1140 }
1141
Jeff Tinker58ad4752018-02-16 16:51:59 -08001142 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1143 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001144}
1145
1146status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001147 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001148 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001149
Jeff Tinker58ad4752018-02-16 16:51:59 -08001150 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001151 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001152 status = mPluginV1_1->removeAllSecureStops();
1153 } else {
1154 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001155 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001156 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001157}
1158
Jeff Tinker6d998b62017-12-18 14:37:43 -08001159status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1160 DrmPlugin::HdcpLevel *max) const {
1161 Mutex::Autolock autoLock(mLock);
1162 INIT_CHECK();
1163
1164 if (connected == NULL || max == NULL) {
1165 return BAD_VALUE;
1166 }
1167 status_t err = UNKNOWN_ERROR;
1168
Jeff Tinker6d998b62017-12-18 14:37:43 -08001169 *connected = DrmPlugin::kHdcpLevelUnknown;
1170 *max = DrmPlugin::kHdcpLevelUnknown;
1171
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001172 Return<void> hResult;
1173 if (mPluginV1_2 != NULL) {
1174 hResult = mPluginV1_2->getHdcpLevels_1_2(
1175 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1176 if (status == Status_V1_2::OK) {
1177 *connected = toHdcpLevel(hConnected);
1178 *max = toHdcpLevel(hMax);
1179 }
1180 err = toStatusT_1_2(status);
1181 });
1182 } else if (mPluginV1_1 != NULL) {
1183 hResult = mPluginV1_1->getHdcpLevels(
1184 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1185 if (status == Status::OK) {
1186 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1187 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1188 }
1189 err = toStatusT(status);
1190 });
1191 } else {
1192 return ERROR_DRM_CANNOT_HANDLE;
1193 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001194
1195 return hResult.isOk() ? err : DEAD_OBJECT;
1196}
1197
1198status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1199 Mutex::Autolock autoLock(mLock);
1200 INIT_CHECK();
1201
1202 if (open == NULL || max == NULL) {
1203 return BAD_VALUE;
1204 }
1205 status_t err = UNKNOWN_ERROR;
1206
1207 *open = 0;
1208 *max = 0;
1209
1210 if (mPluginV1_1 == NULL) {
1211 return ERROR_DRM_CANNOT_HANDLE;
1212 }
1213
1214 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1215 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1216 if (status == Status::OK) {
1217 *open = hOpen;
1218 *max = hMax;
1219 }
1220 err = toStatusT(status);
1221 }
1222 );
1223
1224 return hResult.isOk() ? err : DEAD_OBJECT;
1225}
1226
1227status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1228 DrmPlugin::SecurityLevel *level) const {
1229 Mutex::Autolock autoLock(mLock);
1230 INIT_CHECK();
1231
1232 if (level == NULL) {
1233 return BAD_VALUE;
1234 }
1235 status_t err = UNKNOWN_ERROR;
1236
1237 if (mPluginV1_1 == NULL) {
1238 return ERROR_DRM_CANNOT_HANDLE;
1239 }
1240
1241 *level = DrmPlugin::kSecurityLevelUnknown;
1242
1243 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1244 [&](Status status, SecurityLevel hLevel) {
1245 if (status == Status::OK) {
1246 *level = toSecurityLevel(hLevel);
1247 }
1248 err = toStatusT(status);
1249 }
1250 );
1251
1252 return hResult.isOk() ? err : DEAD_OBJECT;
1253}
1254
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001255status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1256 Mutex::Autolock autoLock(mLock);
1257
1258 if (mInitCheck != OK) {
1259 return mInitCheck;
1260 }
1261
1262 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001263 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001264 }
1265
1266 status_t err = UNKNOWN_ERROR;
1267
1268 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1269 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1270 if (status == Status::OK) {
1271 keySetIds = toKeySetIds(hKeySetIds);
1272 }
1273 err = toStatusT(status);
1274 }
1275 );
1276
1277 return hResult.isOk() ? err : DEAD_OBJECT;
1278}
1279
1280status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1281 Mutex::Autolock autoLock(mLock);
1282
1283 if (mInitCheck != OK) {
1284 return mInitCheck;
1285 }
1286
1287 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001288 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001289 }
1290
1291 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1292 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1293}
1294
1295status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1296 DrmPlugin::OfflineLicenseState *licenseState) const {
1297 Mutex::Autolock autoLock(mLock);
1298
1299 if (mInitCheck != OK) {
1300 return mInitCheck;
1301 }
1302
1303 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001304 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001305 }
1306 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1307
1308 status_t err = UNKNOWN_ERROR;
1309
1310 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1311 [&](Status status, OfflineLicenseState hLicenseState) {
1312 if (status == Status::OK) {
1313 *licenseState = toOfflineLicenseState(hLicenseState);
1314 }
1315 err = toStatusT(status);
1316 }
1317 );
1318
1319 return hResult.isOk() ? err : DEAD_OBJECT;
1320}
1321
Jeff Tinkera53d6552017-01-20 00:31:46 -08001322status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1323 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001324 return getPropertyStringInternal(name, value);
1325}
1326
1327status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1328 // This function is internal to the class and should only be called while
1329 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001330 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001331
1332 status_t err = UNKNOWN_ERROR;
1333
1334 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1335 [&](Status status, const hidl_string& hValue) {
1336 if (status == Status::OK) {
1337 value = toString8(hValue);
1338 }
1339 err = toStatusT(status);
1340 }
1341 );
1342
1343 return hResult.isOk() ? err : DEAD_OBJECT;
1344}
1345
1346status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1347 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001348 return getPropertyByteArrayInternal(name, value);
1349}
1350
1351status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1352 // This function is internal to the class and should only be called while
1353 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001354 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001355
1356 status_t err = UNKNOWN_ERROR;
1357
1358 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1359 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1360 if (status == Status::OK) {
1361 value = toVector(hValue);
1362 }
1363 err = toStatusT(status);
1364 }
1365 );
1366
Adam Stonecea91ce2018-01-22 19:23:28 -08001367 err = hResult.isOk() ? err : DEAD_OBJECT;
1368 if (name == kPropertyDeviceUniqueId) {
1369 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1370 }
1371 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001372}
1373
1374status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1375 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001376 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001377
Jeff Tinker58ad4752018-02-16 16:51:59 -08001378 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001379 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001380 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001381}
1382
1383status_t DrmHal::setPropertyByteArray(String8 const &name,
1384 Vector<uint8_t> const &value ) const {
1385 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001386 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001387
Jeff Tinker58ad4752018-02-16 16:51:59 -08001388 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001389 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001390 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001391}
1392
Adam Stone28f27c32018-02-05 15:07:48 -08001393status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1394 if (metrics == nullptr) {
1395 return UNEXPECTED_NULL;
1396 }
1397 mMetrics.Export(metrics);
1398
1399 // Append vendor metrics if they are supported.
1400 if (mPluginV1_1 != NULL) {
1401 String8 vendor;
1402 String8 description;
1403 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1404 || vendor.isEmpty()) {
1405 ALOGE("Get vendor failed or is empty");
1406 vendor = "NONE";
1407 }
1408 if (getPropertyStringInternal(String8("description"), description) != OK
1409 || description.isEmpty()) {
1410 ALOGE("Get description failed or is empty.");
1411 description = "NONE";
1412 }
1413 vendor += ".";
1414 vendor += description;
1415
1416 hidl_vec<DrmMetricGroup> pluginMetrics;
1417 status_t err = UNKNOWN_ERROR;
1418
1419 Return<void> status = mPluginV1_1->getMetrics(
1420 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1421 if (status != Status::OK) {
1422 ALOGV("Error getting plugin metrics: %d", status);
1423 } else {
1424 PersistableBundle pluginBundle;
1425 if (MediaDrmMetrics::HidlMetricsToBundle(
1426 pluginMetrics, &pluginBundle) == OK) {
1427 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1428 }
1429 }
1430 err = toStatusT(status);
1431 });
1432 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001433 }
1434
Adam Stoneab394d12017-12-22 12:34:20 -08001435 return OK;
1436}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001437
1438status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1439 String8 const &algorithm) {
1440 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001441 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001442
1443 DrmSessionManager::Instance()->useSession(sessionId);
1444
Jeff Tinkere6412942018-04-30 17:35:16 -07001445 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001446 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001447 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001448}
1449
1450status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1451 String8 const &algorithm) {
1452 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001453 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001454
1455 DrmSessionManager::Instance()->useSession(sessionId);
1456
Jeff Tinkere6412942018-04-30 17:35:16 -07001457 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001458 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001459 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001460}
1461
1462status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001463 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1464 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001465 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001466 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001467
1468 DrmSessionManager::Instance()->useSession(sessionId);
1469
1470 status_t err = UNKNOWN_ERROR;
1471
1472 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1473 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1474 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1475 if (status == Status::OK) {
1476 output = toVector(hOutput);
1477 }
1478 err = toStatusT(status);
1479 }
1480 );
1481
1482 return hResult.isOk() ? err : DEAD_OBJECT;
1483}
1484
1485status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001486 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1487 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001488 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001489 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001490
1491 DrmSessionManager::Instance()->useSession(sessionId);
1492
1493 status_t err = UNKNOWN_ERROR;
1494
1495 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1496 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1497 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1498 if (status == Status::OK) {
1499 output = toVector(hOutput);
1500 }
1501 err = toStatusT(status);
1502 }
1503 );
1504
1505 return hResult.isOk() ? err : DEAD_OBJECT;
1506}
1507
1508status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001509 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1510 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001511 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001512 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001513
1514 DrmSessionManager::Instance()->useSession(sessionId);
1515
1516 status_t err = UNKNOWN_ERROR;
1517
1518 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1519 toHidlVec(keyId), toHidlVec(message),
1520 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1521 if (status == Status::OK) {
1522 signature = toVector(hSignature);
1523 }
1524 err = toStatusT(status);
1525 }
1526 );
1527
1528 return hResult.isOk() ? err : DEAD_OBJECT;
1529}
1530
1531status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001532 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1533 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001534 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001535 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001536
1537 DrmSessionManager::Instance()->useSession(sessionId);
1538
1539 status_t err = UNKNOWN_ERROR;
1540
1541 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1542 toHidlVec(message), toHidlVec(signature),
1543 [&](Status status, bool hMatch) {
1544 if (status == Status::OK) {
1545 match = hMatch;
1546 } else {
1547 match = false;
1548 }
1549 err = toStatusT(status);
1550 }
1551 );
1552
1553 return hResult.isOk() ? err : DEAD_OBJECT;
1554}
1555
1556status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001557 String8 const &algorithm, Vector<uint8_t> const &message,
1558 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001559 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001560 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001561
1562 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1563 return -EPERM;
1564 }
1565
1566 DrmSessionManager::Instance()->useSession(sessionId);
1567
1568 status_t err = UNKNOWN_ERROR;
1569
1570 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1571 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1572 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1573 if (status == Status::OK) {
1574 signature = toVector(hSignature);
1575 }
1576 err = toStatusT(status);
1577 }
1578 );
1579
1580 return hResult.isOk() ? err : DEAD_OBJECT;
1581}
1582
1583void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1584{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001585 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001586}
1587
1588void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1589{
1590 if (vec.size()) {
1591 obj.writeInt32(vec.size());
1592 obj.write(vec.data(), vec.size());
1593 } else {
1594 obj.writeInt32(0);
1595 }
1596}
1597
Adam Stonefb679e32018-02-07 10:25:48 -08001598void DrmHal::reportFrameworkMetrics() const
1599{
Ray Essick6a305222019-01-28 20:33:18 -08001600 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
Ray Essick6a305222019-01-28 20:33:18 -08001601 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001602 String8 vendor;
1603 String8 description;
1604 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1605 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001606 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001607 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001608 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001609 }
1610 result = getPropertyStringInternal(String8("description"), description);
1611 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001612 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001613 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001614 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001615 }
Adam Stoneab394d12017-12-22 12:34:20 -08001616
Adam Stonefb679e32018-02-07 10:25:48 -08001617 std::string serializedMetrics;
1618 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1619 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001620 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001621 }
Adam Stone32494f52018-02-26 22:53:27 -08001622 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1623 serializedMetrics.size());
1624 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001625 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001626 }
Ray Essick6a305222019-01-28 20:33:18 -08001627 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001628 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001629 }
1630}
1631
1632void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001633{
Adam Stone32494f52018-02-26 22:53:27 -08001634 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001635 String8 vendor;
1636 String8 description;
1637 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1638 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001639 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1640 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1641 metricsVector.size());
1642 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1643 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001644 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001645 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001646 }
1647 }
1648}
1649
Jeff Tinkera53d6552017-01-20 00:31:46 -08001650} // namespace android