blob: cac90eaa54218382bc64367de3c8890a9834fcfc [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);
Adam Stonefb679e32018-02-07 10:25:48 -0800926 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Adam Stonecea91ce2018-01-22 19:23:28 -0800927
Jeff Tinker6d998b62017-12-18 14:37:43 -0800928 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800929
930 DrmSessionManager::Instance()->useSession(sessionId);
931
932 status_t err = UNKNOWN_ERROR;
933
934 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
935 toHidlVec(response),
936 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
937 if (status == Status::OK) {
938 keySetId = toVector(hKeySetId);
939 }
940 err = toStatusT(status);
941 }
942 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800943 err = hResult.isOk() ? err : DEAD_OBJECT;
944 keyResponseTimer.SetAttribute(err);
945 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800946}
947
948status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
949 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800950 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800951
Jeff Tinker58ad4752018-02-16 16:51:59 -0800952 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
953 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800954}
955
956status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
957 Vector<uint8_t> const &keySetId) {
958 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800959 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800960
961 DrmSessionManager::Instance()->useSession(sessionId);
962
Jeff Tinker58ad4752018-02-16 16:51:59 -0800963 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
964 toHidlVec(keySetId));
965 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800966}
967
968status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
969 KeyedVector<String8, String8> &infoMap) const {
970 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800971 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800972
973 DrmSessionManager::Instance()->useSession(sessionId);
974
975 ::KeyedVector hInfoMap;
976
977 status_t err = UNKNOWN_ERROR;
978
979 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
980 [&](Status status, const hidl_vec<KeyValue>& map) {
981 if (status == Status::OK) {
982 infoMap = toKeyedVector(map);
983 }
984 err = toStatusT(status);
985 }
986 );
987
988 return hResult.isOk() ? err : DEAD_OBJECT;
989}
990
991status_t DrmHal::getProvisionRequest(String8 const &certType,
992 String8 const &certAuthority, Vector<uint8_t> &request,
993 String8 &defaultUrl) {
994 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800995 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800996
997 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800998 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800999
Jeff Tinkerb8684f32018-12-12 08:41:31 -08001000 if (mPluginV1_2 != NULL) {
1001 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
1002 toHidlString(certType), toHidlString(certAuthority),
1003 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
1004 const hidl_string& hDefaultUrl) {
1005 if (status == Status_V1_2::OK) {
1006 request = toVector(hRequest);
1007 defaultUrl = toString8(hDefaultUrl);
1008 }
1009 err = toStatusT_1_2(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -08001010 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -08001011 );
1012 } else {
1013 Return<void> hResult = mPlugin->getProvisionRequest(
1014 toHidlString(certType), toHidlString(certAuthority),
1015 [&](Status status, const hidl_vec<uint8_t>& hRequest,
1016 const hidl_string& hDefaultUrl) {
1017 if (status == Status::OK) {
1018 request = toVector(hRequest);
1019 defaultUrl = toString8(hDefaultUrl);
1020 }
1021 err = toStatusT(status);
1022 }
1023 );
1024 }
Jeff Tinkera53d6552017-01-20 00:31:46 -08001025
Adam Stonecea91ce2018-01-22 19:23:28 -08001026 err = hResult.isOk() ? err : DEAD_OBJECT;
1027 mMetrics.mGetProvisionRequestCounter.Increment(err);
1028 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001029}
1030
1031status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001032 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001033 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001034 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001035
1036 status_t err = UNKNOWN_ERROR;
1037
1038 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
1039 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
1040 const hidl_vec<uint8_t>& hWrappedKey) {
1041 if (status == Status::OK) {
1042 certificate = toVector(hCertificate);
1043 wrappedKey = toVector(hWrappedKey);
1044 }
1045 err = toStatusT(status);
1046 }
1047 );
1048
Adam Stonecea91ce2018-01-22 19:23:28 -08001049 err = hResult.isOk() ? err : DEAD_OBJECT;
1050 mMetrics.mProvideProvisionResponseCounter.Increment(err);
1051 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001052}
1053
Jeff Tinkerabeb36a2017-02-17 09:42:46 -08001054status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001055 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001056 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001057
1058 status_t err = UNKNOWN_ERROR;
1059
1060 Return<void> hResult = mPlugin->getSecureStops(
1061 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
1062 if (status == Status::OK) {
1063 secureStops = toSecureStops(hSecureStops);
1064 }
1065 err = toStatusT(status);
1066 }
1067 );
1068
1069 return hResult.isOk() ? err : DEAD_OBJECT;
1070}
1071
1072
Jeff Tinker15177d72018-01-25 12:57:55 -08001073status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
1074 Mutex::Autolock autoLock(mLock);
1075
1076 if (mInitCheck != OK) {
1077 return mInitCheck;
1078 }
1079
1080 if (mPluginV1_1 == NULL) {
1081 return ERROR_DRM_CANNOT_HANDLE;
1082 }
1083
1084 status_t err = UNKNOWN_ERROR;
1085
1086 Return<void> hResult = mPluginV1_1->getSecureStopIds(
1087 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
1088 if (status == Status::OK) {
1089 secureStopIds = toSecureStopIds(hSecureStopIds);
1090 }
1091 err = toStatusT(status);
1092 }
1093 );
1094
1095 return hResult.isOk() ? err : DEAD_OBJECT;
1096}
1097
1098
Jeff Tinkera53d6552017-01-20 00:31:46 -08001099status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
1100 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001101 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001102
1103 status_t err = UNKNOWN_ERROR;
1104
1105 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
1106 [&](Status status, const SecureStop& hSecureStop) {
1107 if (status == Status::OK) {
1108 secureStop = toVector(hSecureStop.opaqueData);
1109 }
1110 err = toStatusT(status);
1111 }
1112 );
1113
1114 return hResult.isOk() ? err : DEAD_OBJECT;
1115}
1116
1117status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1118 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001119 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001120
Jeff Tinker58ad4752018-02-16 16:51:59 -08001121 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001122 if (mPluginV1_1 != NULL) {
1123 SecureStopRelease secureStopRelease;
1124 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001125 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1126 } else {
1127 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001128 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001129 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001130}
1131
Jeff Tinker15177d72018-01-25 12:57:55 -08001132status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1133 Mutex::Autolock autoLock(mLock);
1134
1135 if (mInitCheck != OK) {
1136 return mInitCheck;
1137 }
1138
1139 if (mPluginV1_1 == NULL) {
1140 return ERROR_DRM_CANNOT_HANDLE;
1141 }
1142
Jeff Tinker58ad4752018-02-16 16:51:59 -08001143 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1144 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001145}
1146
1147status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001148 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001149 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001150
Jeff Tinker58ad4752018-02-16 16:51:59 -08001151 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001152 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001153 status = mPluginV1_1->removeAllSecureStops();
1154 } else {
1155 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001156 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001157 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001158}
1159
Jeff Tinker6d998b62017-12-18 14:37:43 -08001160status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1161 DrmPlugin::HdcpLevel *max) const {
1162 Mutex::Autolock autoLock(mLock);
1163 INIT_CHECK();
1164
1165 if (connected == NULL || max == NULL) {
1166 return BAD_VALUE;
1167 }
1168 status_t err = UNKNOWN_ERROR;
1169
Jeff Tinker6d998b62017-12-18 14:37:43 -08001170 *connected = DrmPlugin::kHdcpLevelUnknown;
1171 *max = DrmPlugin::kHdcpLevelUnknown;
1172
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001173 Return<void> hResult;
1174 if (mPluginV1_2 != NULL) {
1175 hResult = mPluginV1_2->getHdcpLevels_1_2(
1176 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1177 if (status == Status_V1_2::OK) {
1178 *connected = toHdcpLevel(hConnected);
1179 *max = toHdcpLevel(hMax);
1180 }
1181 err = toStatusT_1_2(status);
1182 });
1183 } else if (mPluginV1_1 != NULL) {
1184 hResult = mPluginV1_1->getHdcpLevels(
1185 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1186 if (status == Status::OK) {
1187 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1188 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1189 }
1190 err = toStatusT(status);
1191 });
1192 } else {
1193 return ERROR_DRM_CANNOT_HANDLE;
1194 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001195
1196 return hResult.isOk() ? err : DEAD_OBJECT;
1197}
1198
1199status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1200 Mutex::Autolock autoLock(mLock);
1201 INIT_CHECK();
1202
1203 if (open == NULL || max == NULL) {
1204 return BAD_VALUE;
1205 }
1206 status_t err = UNKNOWN_ERROR;
1207
1208 *open = 0;
1209 *max = 0;
1210
1211 if (mPluginV1_1 == NULL) {
1212 return ERROR_DRM_CANNOT_HANDLE;
1213 }
1214
1215 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1216 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1217 if (status == Status::OK) {
1218 *open = hOpen;
1219 *max = hMax;
1220 }
1221 err = toStatusT(status);
1222 }
1223 );
1224
1225 return hResult.isOk() ? err : DEAD_OBJECT;
1226}
1227
1228status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1229 DrmPlugin::SecurityLevel *level) const {
1230 Mutex::Autolock autoLock(mLock);
1231 INIT_CHECK();
1232
1233 if (level == NULL) {
1234 return BAD_VALUE;
1235 }
1236 status_t err = UNKNOWN_ERROR;
1237
1238 if (mPluginV1_1 == NULL) {
1239 return ERROR_DRM_CANNOT_HANDLE;
1240 }
1241
1242 *level = DrmPlugin::kSecurityLevelUnknown;
1243
1244 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1245 [&](Status status, SecurityLevel hLevel) {
1246 if (status == Status::OK) {
1247 *level = toSecurityLevel(hLevel);
1248 }
1249 err = toStatusT(status);
1250 }
1251 );
1252
1253 return hResult.isOk() ? err : DEAD_OBJECT;
1254}
1255
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001256status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1257 Mutex::Autolock autoLock(mLock);
1258
1259 if (mInitCheck != OK) {
1260 return mInitCheck;
1261 }
1262
1263 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001264 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001265 }
1266
1267 status_t err = UNKNOWN_ERROR;
1268
1269 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1270 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1271 if (status == Status::OK) {
1272 keySetIds = toKeySetIds(hKeySetIds);
1273 }
1274 err = toStatusT(status);
1275 }
1276 );
1277
1278 return hResult.isOk() ? err : DEAD_OBJECT;
1279}
1280
1281status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1282 Mutex::Autolock autoLock(mLock);
1283
1284 if (mInitCheck != OK) {
1285 return mInitCheck;
1286 }
1287
1288 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001289 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001290 }
1291
1292 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1293 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1294}
1295
1296status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1297 DrmPlugin::OfflineLicenseState *licenseState) const {
1298 Mutex::Autolock autoLock(mLock);
1299
1300 if (mInitCheck != OK) {
1301 return mInitCheck;
1302 }
1303
1304 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001305 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001306 }
1307 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1308
1309 status_t err = UNKNOWN_ERROR;
1310
1311 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1312 [&](Status status, OfflineLicenseState hLicenseState) {
1313 if (status == Status::OK) {
1314 *licenseState = toOfflineLicenseState(hLicenseState);
1315 }
1316 err = toStatusT(status);
1317 }
1318 );
1319
1320 return hResult.isOk() ? err : DEAD_OBJECT;
1321}
1322
Jeff Tinkera53d6552017-01-20 00:31:46 -08001323status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1324 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001325 return getPropertyStringInternal(name, value);
1326}
1327
1328status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1329 // This function is internal to the class and should only be called while
1330 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001331 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001332
1333 status_t err = UNKNOWN_ERROR;
1334
1335 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1336 [&](Status status, const hidl_string& hValue) {
1337 if (status == Status::OK) {
1338 value = toString8(hValue);
1339 }
1340 err = toStatusT(status);
1341 }
1342 );
1343
1344 return hResult.isOk() ? err : DEAD_OBJECT;
1345}
1346
1347status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1348 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001349 return getPropertyByteArrayInternal(name, value);
1350}
1351
1352status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1353 // This function is internal to the class and should only be called while
1354 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001355 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001356
1357 status_t err = UNKNOWN_ERROR;
1358
1359 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1360 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1361 if (status == Status::OK) {
1362 value = toVector(hValue);
1363 }
1364 err = toStatusT(status);
1365 }
1366 );
1367
Adam Stonecea91ce2018-01-22 19:23:28 -08001368 err = hResult.isOk() ? err : DEAD_OBJECT;
1369 if (name == kPropertyDeviceUniqueId) {
1370 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1371 }
1372 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001373}
1374
1375status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1376 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001377 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001378
Jeff Tinker58ad4752018-02-16 16:51:59 -08001379 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001380 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001381 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001382}
1383
1384status_t DrmHal::setPropertyByteArray(String8 const &name,
1385 Vector<uint8_t> const &value ) const {
1386 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001387 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001388
Jeff Tinker58ad4752018-02-16 16:51:59 -08001389 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001390 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001391 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001392}
1393
Adam Stone28f27c32018-02-05 15:07:48 -08001394status_t DrmHal::getMetrics(PersistableBundle* metrics) {
1395 if (metrics == nullptr) {
1396 return UNEXPECTED_NULL;
1397 }
1398 mMetrics.Export(metrics);
1399
1400 // Append vendor metrics if they are supported.
1401 if (mPluginV1_1 != NULL) {
1402 String8 vendor;
1403 String8 description;
1404 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1405 || vendor.isEmpty()) {
1406 ALOGE("Get vendor failed or is empty");
1407 vendor = "NONE";
1408 }
1409 if (getPropertyStringInternal(String8("description"), description) != OK
1410 || description.isEmpty()) {
1411 ALOGE("Get description failed or is empty.");
1412 description = "NONE";
1413 }
1414 vendor += ".";
1415 vendor += description;
1416
1417 hidl_vec<DrmMetricGroup> pluginMetrics;
1418 status_t err = UNKNOWN_ERROR;
1419
1420 Return<void> status = mPluginV1_1->getMetrics(
1421 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1422 if (status != Status::OK) {
1423 ALOGV("Error getting plugin metrics: %d", status);
1424 } else {
1425 PersistableBundle pluginBundle;
1426 if (MediaDrmMetrics::HidlMetricsToBundle(
1427 pluginMetrics, &pluginBundle) == OK) {
1428 metrics->putPersistableBundle(String16(vendor), pluginBundle);
1429 }
1430 }
1431 err = toStatusT(status);
1432 });
1433 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001434 }
1435
Adam Stoneab394d12017-12-22 12:34:20 -08001436 return OK;
1437}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001438
1439status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1440 String8 const &algorithm) {
1441 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001442 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001443
1444 DrmSessionManager::Instance()->useSession(sessionId);
1445
Jeff Tinkere6412942018-04-30 17:35:16 -07001446 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001447 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001448 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449}
1450
1451status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1452 String8 const &algorithm) {
1453 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001454 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001455
1456 DrmSessionManager::Instance()->useSession(sessionId);
1457
Jeff Tinkere6412942018-04-30 17:35:16 -07001458 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001459 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001460 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001461}
1462
1463status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001464 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1465 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001466 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001467 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001468
1469 DrmSessionManager::Instance()->useSession(sessionId);
1470
1471 status_t err = UNKNOWN_ERROR;
1472
1473 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1474 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1475 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1476 if (status == Status::OK) {
1477 output = toVector(hOutput);
1478 }
1479 err = toStatusT(status);
1480 }
1481 );
1482
1483 return hResult.isOk() ? err : DEAD_OBJECT;
1484}
1485
1486status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001487 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1488 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001489 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001490 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001491
1492 DrmSessionManager::Instance()->useSession(sessionId);
1493
1494 status_t err = UNKNOWN_ERROR;
1495
1496 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1497 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1498 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1499 if (status == Status::OK) {
1500 output = toVector(hOutput);
1501 }
1502 err = toStatusT(status);
1503 }
1504 );
1505
1506 return hResult.isOk() ? err : DEAD_OBJECT;
1507}
1508
1509status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001510 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1511 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001512 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001513 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001514
1515 DrmSessionManager::Instance()->useSession(sessionId);
1516
1517 status_t err = UNKNOWN_ERROR;
1518
1519 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1520 toHidlVec(keyId), toHidlVec(message),
1521 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1522 if (status == Status::OK) {
1523 signature = toVector(hSignature);
1524 }
1525 err = toStatusT(status);
1526 }
1527 );
1528
1529 return hResult.isOk() ? err : DEAD_OBJECT;
1530}
1531
1532status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001533 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1534 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001535 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001536 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001537
1538 DrmSessionManager::Instance()->useSession(sessionId);
1539
1540 status_t err = UNKNOWN_ERROR;
1541
1542 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1543 toHidlVec(message), toHidlVec(signature),
1544 [&](Status status, bool hMatch) {
1545 if (status == Status::OK) {
1546 match = hMatch;
1547 } else {
1548 match = false;
1549 }
1550 err = toStatusT(status);
1551 }
1552 );
1553
1554 return hResult.isOk() ? err : DEAD_OBJECT;
1555}
1556
1557status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001558 String8 const &algorithm, Vector<uint8_t> const &message,
1559 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001560 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001561 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001562
1563 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
1564 return -EPERM;
1565 }
1566
1567 DrmSessionManager::Instance()->useSession(sessionId);
1568
1569 status_t err = UNKNOWN_ERROR;
1570
1571 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1572 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1573 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1574 if (status == Status::OK) {
1575 signature = toVector(hSignature);
1576 }
1577 err = toStatusT(status);
1578 }
1579 );
1580
1581 return hResult.isOk() ? err : DEAD_OBJECT;
1582}
1583
1584void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
1585{
Jeff Tinker7dfe28f2018-02-15 12:17:40 -08001586 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001587}
1588
1589void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
1590{
1591 if (vec.size()) {
1592 obj.writeInt32(vec.size());
1593 obj.write(vec.data(), vec.size());
1594 } else {
1595 obj.writeInt32(0);
1596 }
1597}
1598
Adam Stonefb679e32018-02-07 10:25:48 -08001599void DrmHal::reportFrameworkMetrics() const
1600{
Ray Essick6a305222019-01-28 20:33:18 -08001601 std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
1602 item->generateSessionID();
1603 item->setPkgName(mMetrics.GetAppPackageName().c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001604 String8 vendor;
1605 String8 description;
1606 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1607 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001608 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001609 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001610 item->setCString("vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001611 }
1612 result = getPropertyStringInternal(String8("description"), description);
1613 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001614 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001615 } else {
Ray Essick6a305222019-01-28 20:33:18 -08001616 item->setCString("description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001617 }
Adam Stoneab394d12017-12-22 12:34:20 -08001618
Adam Stonefb679e32018-02-07 10:25:48 -08001619 std::string serializedMetrics;
1620 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1621 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001622 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001623 }
Adam Stone32494f52018-02-26 22:53:27 -08001624 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1625 serializedMetrics.size());
1626 if (!b64EncodedMetrics.empty()) {
Ray Essick6a305222019-01-28 20:33:18 -08001627 item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001628 }
Ray Essick6a305222019-01-28 20:33:18 -08001629 if (!item->selfrecord()) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001630 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001631 }
1632}
1633
1634void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001635{
Adam Stone32494f52018-02-26 22:53:27 -08001636 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001637 String8 vendor;
1638 String8 description;
1639 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1640 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001641 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1642 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1643 metricsVector.size());
1644 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
1645 description, mAppPackageName);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001646 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001647 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001648 }
1649 }
1650}
1651
Jeff Tinkera53d6552017-01-20 00:31:46 -08001652} // namespace android