blob: f8f2bc6772f6a88e14af3bae3eba32c554e02660 [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
Robert Shih6152d7c2019-11-19 22:54:27 -080023#include <android/binder_manager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080024
Robert Shih0f3a8a02019-11-14 15:43:39 -080025#include <aidl/android/media/BnResourceManagerClient.h>
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>
Jeff Tinker593111f2017-05-25 16:00:21 -070028#include <hidl/ServiceManagement.h>
Adam Stonef0e618d2018-01-17 19:20:41 -080029#include <media/EventMetric.h>
Robert Shih82ea6be2019-11-07 17:47:23 -080030#include <media/MediaMetrics.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>
Robert Shih93538812019-11-12 12:21:35 -080041#include <mediadrm/IDrmMetricsConsumer.h>
Robert Shihc0d1d0e2019-11-24 13:21:04 -080042#include <mediadrm/DrmUtils.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080043
Robert Shih61e1c762019-10-31 21:26:58 -070044#include <vector>
45
Jeff Tinker6d998b62017-12-18 14:37:43 -080046using drm::V1_0::KeyedVector;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080047using drm::V1_0::KeyRequestType;
Jeff Tinker6d998b62017-12-18 14:37:43 -080048using drm::V1_0::KeyType;
49using drm::V1_0::KeyValue;
Jeff Tinker6d998b62017-12-18 14:37:43 -080050using drm::V1_0::SecureStop;
Jeff Tinker15177d72018-01-25 12:57:55 -080051using drm::V1_0::SecureStopId;
Jeff Tinker6d998b62017-12-18 14:37:43 -080052using drm::V1_0::Status;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -070053using drm::V1_1::HdcpLevel;
54using drm::V1_1::SecureStopRelease;
55using drm::V1_1::SecurityLevel;
56using drm::V1_2::KeySetId;
Robert Shiha5033262019-05-06 14:15:12 -070057using drm::V1_2::KeyStatusType;
Robert Shih5944a0b2021-02-10 04:26:33 -080058using ::android::DrmUtils::toStatusT;
Adam Stone28f27c32018-02-05 15:07:48 -080059using ::android::hardware::drm::V1_1::DrmMetricGroup;
Jeff Tinkera53d6552017-01-20 00:31:46 -080060using ::android::hardware::hidl_array;
61using ::android::hardware::hidl_string;
62using ::android::hardware::hidl_vec;
63using ::android::hardware::Return;
64using ::android::hardware::Void;
Adam Stone637b7852018-01-30 12:09:36 -080065using ::android::os::PersistableBundle;
Jeff Tinkera53d6552017-01-20 00:31:46 -080066using ::android::sp;
67
Jeff Tinkerb8684f32018-12-12 08:41:31 -080068typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
69typedef drm::V1_2::Status Status_V1_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -080070typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
Jeff Tinkerb8684f32018-12-12 08:41:31 -080071
Adam Stonecea91ce2018-01-22 19:23:28 -080072namespace {
73
74// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
75// in the MediaDrm API.
76constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
Adam Stone32494f52018-02-26 22:53:27 -080077constexpr char kEqualsSign[] = "=";
Adam Stonecea91ce2018-01-22 19:23:28 -080078
Adam Stone32494f52018-02-26 22:53:27 -080079template<typename T>
80std::string toBase64StringNoPad(const T* data, size_t size) {
Adam Stone630092e2018-05-02 13:06:34 -070081 // Note that the base 64 conversion only works with arrays of single-byte
82 // values. If the source is empty or is not an array of single-byte values,
83 // return empty string.
84 if (size == 0 || sizeof(data[0]) != 1) {
Adam Stone32494f52018-02-26 22:53:27 -080085 return "";
86 }
Adam Stone32494f52018-02-26 22:53:27 -080087
88 android::AString outputString;
89 encodeBase64(data, size, &outputString);
90 // Remove trailing equals padding if it exists.
91 while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
92 outputString.erase(outputString.size() - 1, 1);
93 }
94
95 return std::string(outputString.c_str(), outputString.size());
Adam Stonecea91ce2018-01-22 19:23:28 -080096}
97
Adam Stone32494f52018-02-26 22:53:27 -080098} // anonymous namespace
99
Jeff Tinkera53d6552017-01-20 00:31:46 -0800100namespace android {
101
Jeff Tinker6d998b62017-12-18 14:37:43 -0800102#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
103
Jeff Tinkera53d6552017-01-20 00:31:46 -0800104static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
105 Vector<uint8_t> vector;
106 vector.appendArray(vec.data(), vec.size());
107 return *const_cast<const Vector<uint8_t> *>(&vector);
108}
109
110static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
111 hidl_vec<uint8_t> vec;
112 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
113 return vec;
114}
115
116static String8 toString8(const hidl_string &string) {
117 return String8(string.c_str());
118}
119
120static hidl_string toHidlString(const String8& string) {
121 return hidl_string(string.string());
122}
123
Jeff Tinker6d998b62017-12-18 14:37:43 -0800124static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
125 switch(level) {
126 case SecurityLevel::SW_SECURE_CRYPTO:
127 return DrmPlugin::kSecurityLevelSwSecureCrypto;
128 case SecurityLevel::SW_SECURE_DECODE:
129 return DrmPlugin::kSecurityLevelSwSecureDecode;
130 case SecurityLevel::HW_SECURE_CRYPTO:
131 return DrmPlugin::kSecurityLevelHwSecureCrypto;
132 case SecurityLevel::HW_SECURE_DECODE:
133 return DrmPlugin::kSecurityLevelHwSecureDecode;
134 case SecurityLevel::HW_SECURE_ALL:
135 return DrmPlugin::kSecurityLevelHwSecureAll;
136 default:
137 return DrmPlugin::kSecurityLevelUnknown;
138 }
139}
140
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800141static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
142 switch(level) {
143 case DrmPlugin::kSecurityLevelSwSecureCrypto:
144 return SecurityLevel::SW_SECURE_CRYPTO;
145 case DrmPlugin::kSecurityLevelSwSecureDecode:
146 return SecurityLevel::SW_SECURE_DECODE;
147 case DrmPlugin::kSecurityLevelHwSecureCrypto:
148 return SecurityLevel::HW_SECURE_CRYPTO;
149 case DrmPlugin::kSecurityLevelHwSecureDecode:
150 return SecurityLevel::HW_SECURE_DECODE;
151 case DrmPlugin::kSecurityLevelHwSecureAll:
152 return SecurityLevel::HW_SECURE_ALL;
153 default:
154 return SecurityLevel::UNKNOWN;
155 }
156}
157
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700158static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
159 OfflineLicenseState licenseState) {
160 switch(licenseState) {
161 case OfflineLicenseState::USABLE:
162 return DrmPlugin::kOfflineLicenseStateUsable;
163 case OfflineLicenseState::INACTIVE:
Jeff Tinker9a95b0f2019-01-30 17:39:20 -0800164 return DrmPlugin::kOfflineLicenseStateReleased;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700165 default:
166 return DrmPlugin::kOfflineLicenseStateUnknown;
167 }
168}
169
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800170static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
Jeff Tinker6d998b62017-12-18 14:37:43 -0800171 switch(level) {
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800172 case HdcpLevel_V1_2::HDCP_NONE:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800173 return DrmPlugin::kHdcpNone;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800174 case HdcpLevel_V1_2::HDCP_V1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800175 return DrmPlugin::kHdcpV1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800176 case HdcpLevel_V1_2::HDCP_V2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800177 return DrmPlugin::kHdcpV2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800178 case HdcpLevel_V1_2::HDCP_V2_1:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800179 return DrmPlugin::kHdcpV2_1;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800180 case HdcpLevel_V1_2::HDCP_V2_2:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800181 return DrmPlugin::kHdcpV2_2;
Jeff Tinker44c2cc42019-01-14 10:24:18 -0800182 case HdcpLevel_V1_2::HDCP_V2_3:
183 return DrmPlugin::kHdcpV2_3;
184 case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
Jeff Tinker6d998b62017-12-18 14:37:43 -0800185 return DrmPlugin::kHdcpNoOutput;
186 default:
187 return DrmPlugin::kHdcpLevelUnknown;
188 }
189}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800190static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
191 keyedVector) {
192 std::vector<KeyValue> stdKeyedVector;
193 for (size_t i = 0; i < keyedVector.size(); i++) {
194 KeyValue keyValue;
195 keyValue.key = toHidlString(keyedVector.keyAt(i));
196 keyValue.value = toHidlString(keyedVector.valueAt(i));
197 stdKeyedVector.push_back(keyValue);
198 }
199 return ::KeyedVector(stdKeyedVector);
200}
201
202static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
203 hKeyedVector) {
204 KeyedVector<String8, String8> keyedVector;
205 for (size_t i = 0; i < hKeyedVector.size(); i++) {
206 keyedVector.add(toString8(hKeyedVector[i].key),
207 toString8(hKeyedVector[i].value));
208 }
209 return keyedVector;
210}
211
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800212static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800213 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800214 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800215 for (size_t i = 0; i < hSecureStops.size(); i++) {
216 secureStops.push_back(toVector(hSecureStops[i].opaqueData));
217 }
218 return secureStops;
219}
220
Jeff Tinker15177d72018-01-25 12:57:55 -0800221static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
222 hSecureStopIds) {
223 List<Vector<uint8_t>> secureStopIds;
224 for (size_t i = 0; i < hSecureStopIds.size(); i++) {
225 secureStopIds.push_back(toVector(hSecureStopIds[i]));
226 }
227 return secureStopIds;
228}
229
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700230static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
231 hKeySetIds) {
232 List<Vector<uint8_t>> keySetIds;
233 for (size_t i = 0; i < hKeySetIds.size(); i++) {
234 keySetIds.push_back(toVector(hKeySetIds[i]));
235 }
236 return keySetIds;
237}
238
Jeff Tinkera53d6552017-01-20 00:31:46 -0800239Mutex DrmHal::mLock;
240
Robert Shih0f3a8a02019-11-14 15:43:39 -0800241struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
Chong Zhang181e6952019-10-09 13:23:39 -0700242 explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
243 : mSessionId(sessionId),
244 mDrm(drm) {}
245
Robert Shih0f3a8a02019-11-14 15:43:39 -0800246 ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
247 ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
Chong Zhang181e6952019-10-09 13:23:39 -0700248
249 const Vector<uint8_t> mSessionId;
250
Chong Zhang181e6952019-10-09 13:23:39 -0700251 virtual ~DrmSessionClient();
252
253private:
254 wp<DrmHal> mDrm;
255
256 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
257};
258
Robert Shih0f3a8a02019-11-14 15:43:39 -0800259::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
260 auto sessionId = mSessionId;
Robert Shihc3af31b2019-09-20 21:45:01 -0700261 sp<DrmHal> drm = mDrm.promote();
262 if (drm == NULL) {
Chong Zhang181e6952019-10-09 13:23:39 -0700263 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800264 return ::ndk::ScopedAStatus::ok();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800265 }
Robert Shih0f3a8a02019-11-14 15:43:39 -0800266 status_t err = drm->closeSession(sessionId);
Robert Shihc3af31b2019-09-20 21:45:01 -0700267 if (err != OK) {
Chong Zhang181e6952019-10-09 13:23:39 -0700268 *_aidl_return = false;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800269 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700270 }
271 drm->sendEvent(EventType::SESSION_RECLAIMED,
Robert Shih0f3a8a02019-11-14 15:43:39 -0800272 toHidlVec(sessionId), hidl_vec<uint8_t>());
Chong Zhang181e6952019-10-09 13:23:39 -0700273 *_aidl_return = true;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800274 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700275}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800276
Robert Shih0f3a8a02019-11-14 15:43:39 -0800277::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700278 String8 name;
279 sp<DrmHal> drm = mDrm.promote();
280 if (drm == NULL) {
281 name.append("<deleted>");
282 } else if (drm->getPropertyStringInternal(String8("vendor"), name) != OK
283 || name.isEmpty()) {
284 name.append("<Get vendor failed or is empty>");
285 }
286 name.append("[");
287 for (size_t i = 0; i < mSessionId.size(); ++i) {
288 name.appendFormat("%02x", mSessionId[i]);
289 }
290 name.append("]");
Chong Zhang181e6952019-10-09 13:23:39 -0700291 *_aidl_return = name;
Robert Shih0f3a8a02019-11-14 15:43:39 -0800292 return ::ndk::ScopedAStatus::ok();
Robert Shihc3af31b2019-09-20 21:45:01 -0700293}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800294
Robert Shihc3af31b2019-09-20 21:45:01 -0700295DrmHal::DrmSessionClient::~DrmSessionClient() {
296 DrmSessionManager::Instance()->removeSession(mSessionId);
297}
Jeff Tinkera53d6552017-01-20 00:31:46 -0800298
299DrmHal::DrmHal()
Robert Shihc3af31b2019-09-20 21:45:01 -0700300 : mFactories(makeDrmFactories()),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800301 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800302}
303
Jeff Tinker61332812017-05-15 16:53:10 -0700304void DrmHal::closeOpenSessions() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800305 Mutex::Autolock autoLock(mLock);
306 auto openSessions = mOpenSessions;
307 for (size_t i = 0; i < openSessions.size(); i++) {
308 mLock.unlock();
Robert Shihc3af31b2019-09-20 21:45:01 -0700309 closeSession(openSessions[i]->mSessionId);
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800310 mLock.lock();
Jeff Tinker61332812017-05-15 16:53:10 -0700311 }
312 mOpenSessions.clear();
313}
314
Jeff Tinkera53d6552017-01-20 00:31:46 -0800315DrmHal::~DrmHal() {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800316}
317
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800318void DrmHal::cleanup() {
319 closeOpenSessions();
320
321 Mutex::Autolock autoLock(mLock);
322 reportPluginMetrics();
323 reportFrameworkMetrics();
324
325 setListener(NULL);
326 mInitCheck = NO_INIT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800327 if (mPluginV1_2 != NULL) {
328 if (!mPluginV1_2->setListener(NULL).isOk()) {
329 mInitCheck = DEAD_OBJECT;
330 }
331 } else if (mPlugin != NULL) {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800332 if (!mPlugin->setListener(NULL).isOk()) {
333 mInitCheck = DEAD_OBJECT;
334 }
335 }
336 mPlugin.clear();
337 mPluginV1_1.clear();
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700338 mPluginV1_2.clear();
Robert Shihfbe581e2021-01-14 05:12:04 -0800339 mPluginV1_4.clear();
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800340}
341
Robert Shihc0d1d0e2019-11-24 13:21:04 -0800342std::vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
343 std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800344 if (factories.size() == 0) {
345 // must be in passthrough mode, load the default passthrough service
Jeff Tinkere309b222017-04-05 08:01:28 -0700346 auto passthrough = IDrmFactory::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800347 if (passthrough != NULL) {
Jeff Tinkere307dc42018-02-11 19:53:54 +0000348 ALOGI("makeDrmFactories: using default passthrough drm instance");
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800349 factories.push_back(passthrough);
350 } else {
351 ALOGE("Failed to find any drm factories");
352 }
353 }
354 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800355}
356
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800357sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
358 const uint8_t uuid[16], const String8& appPackageName) {
Adam Stone32494f52018-02-26 22:53:27 -0800359 mAppPackageName = appPackageName;
Adam Stonefb679e32018-02-07 10:25:48 -0800360 mMetrics.SetAppPackageName(appPackageName);
Robert Shih6152d7c2019-11-19 22:54:27 -0800361 mMetrics.SetAppUid(AIBinder_getCallingUid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800362
363 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800364 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800365 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800366 if (status != Status::OK) {
367 ALOGE("Failed to make drm plugin");
368 return;
369 }
370 plugin = hPlugin;
371 }
372 );
Jeff Tinkerf0e89b02017-08-07 15:58:41 -0700373
374 if (!hResult.isOk()) {
375 ALOGE("createPlugin remote call failed");
376 }
377
Jeff Tinkera53d6552017-01-20 00:31:46 -0800378 return plugin;
379}
380
381status_t DrmHal::initCheck() const {
382 return mInitCheck;
383}
384
385status_t DrmHal::setListener(const sp<IDrmClient>& listener)
386{
387 Mutex::Autolock lock(mEventLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800388 mListener = listener;
389 return NO_ERROR;
390}
391
392Return<void> DrmHal::sendEvent(EventType hEventType,
393 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
Adam Stonecea91ce2018-01-22 19:23:28 -0800394 mMetrics.mEventCounter.Increment(hEventType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800395
396 mEventLock.lock();
397 sp<IDrmClient> listener = mListener;
398 mEventLock.unlock();
399
400 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800401 Mutex::Autolock lock(mNotifyLock);
402 DrmPlugin::EventType eventType;
403 switch(hEventType) {
404 case EventType::PROVISION_REQUIRED:
405 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
406 break;
407 case EventType::KEY_NEEDED:
408 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
409 break;
410 case EventType::KEY_EXPIRED:
411 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
412 break;
413 case EventType::VENDOR_DEFINED:
414 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
415 break;
Rahul Friasb86f4b32017-03-27 15:13:30 -0700416 case EventType::SESSION_RECLAIMED:
417 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
418 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800419 default:
420 return Void();
421 }
Robert Shih61e1c762019-10-31 21:26:58 -0700422 listener->sendEvent(eventType, sessionId, data);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800423 }
424 return Void();
425}
426
427Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
428 int64_t expiryTimeInMS) {
429
430 mEventLock.lock();
431 sp<IDrmClient> listener = mListener;
432 mEventLock.unlock();
433
434 if (listener != NULL) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800435 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700436 listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800437 }
438 return Void();
439}
440
441Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
Robert Shiha5033262019-05-06 14:15:12 -0700442 const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
443 std::vector<KeyStatus> keyStatusVec;
444 for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
445 keyStatusVec.push_back({keyStatus_V1_0.keyId,
446 static_cast<KeyStatusType>(keyStatus_V1_0.type)});
447 }
448 hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
449 return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
450}
451
452Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
Robert Shih61e1c762019-10-31 21:26:58 -0700453 const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800454
455 mEventLock.lock();
456 sp<IDrmClient> listener = mListener;
457 mEventLock.unlock();
458
459 if (listener != NULL) {
Robert Shih61e1c762019-10-31 21:26:58 -0700460 std::vector<DrmKeyStatus> keyStatusList;
461 size_t nKeys = hKeyStatusList.size();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800462 for (size_t i = 0; i < nKeys; ++i) {
Robert Shih61e1c762019-10-31 21:26:58 -0700463 const KeyStatus &keyStatus = hKeyStatusList[i];
Jeff Tinkera53d6552017-01-20 00:31:46 -0800464 uint32_t type;
465 switch(keyStatus.type) {
466 case KeyStatusType::USABLE:
467 type = DrmPlugin::kKeyStatusType_Usable;
468 break;
469 case KeyStatusType::EXPIRED:
470 type = DrmPlugin::kKeyStatusType_Expired;
471 break;
472 case KeyStatusType::OUTPUTNOTALLOWED:
473 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
474 break;
475 case KeyStatusType::STATUSPENDING:
476 type = DrmPlugin::kKeyStatusType_StatusPending;
477 break;
Robert Shiha5033262019-05-06 14:15:12 -0700478 case KeyStatusType::USABLEINFUTURE:
479 type = DrmPlugin::kKeyStatusType_UsableInFuture;
480 break;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800481 case KeyStatusType::INTERNALERROR:
482 default:
483 type = DrmPlugin::kKeyStatusType_InternalError;
484 break;
485 }
Robert Shih61e1c762019-10-31 21:26:58 -0700486 keyStatusList.push_back({type, keyStatus.keyId});
Adam Stonecea91ce2018-01-22 19:23:28 -0800487 mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800488 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800489
490 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700491 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
Adam Stonecea91ce2018-01-22 19:23:28 -0800492 } else {
493 // There's no listener. But we still want to count the key change
494 // events.
Robert Shih61e1c762019-10-31 21:26:58 -0700495 size_t nKeys = hKeyStatusList.size();
Adam Stonecea91ce2018-01-22 19:23:28 -0800496 for (size_t i = 0; i < nKeys; i++) {
Robert Shih61e1c762019-10-31 21:26:58 -0700497 mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
Adam Stonecea91ce2018-01-22 19:23:28 -0800498 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800499 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800500
Jeff Tinkera53d6552017-01-20 00:31:46 -0800501 return Void();
502}
503
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800504Return<void> DrmHal::sendSessionLostState(
505 const hidl_vec<uint8_t>& sessionId) {
506
507 mEventLock.lock();
508 sp<IDrmClient> listener = mListener;
509 mEventLock.unlock();
510
511 if (listener != NULL) {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800512 Mutex::Autolock lock(mNotifyLock);
Robert Shih61e1c762019-10-31 21:26:58 -0700513 listener->sendSessionLostState(sessionId);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800514 }
515 return Void();
516}
517
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800518status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
519 const uint8_t uuid[16],
520 const String8 &mimeType,
521 DrmPlugin::SecurityLevel level,
522 bool *isSupported) {
523 *isSupported = false;
524
525 // handle default value cases
526 if (level == DrmPlugin::kSecurityLevelUnknown) {
527 if (mimeType == "") {
528 // isCryptoSchemeSupported(uuid)
529 *isSupported = true;
530 } else {
531 // isCryptoSchemeSupported(uuid, mimeType)
532 *isSupported = factory->isContentTypeSupported(mimeType.string());
533 }
534 return OK;
535 } else if (mimeType == "") {
536 return BAD_VALUE;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800537 }
538
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800539 sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
540 if (factoryV1_2 == NULL) {
541 return ERROR_UNSUPPORTED;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800542 } else {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800543 *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
544 mimeType.string(), toHidlSecurityLevel(level));
545 return OK;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800546 }
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800547}
548
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800549status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
550 const String8 &mimeType,
551 DrmPlugin::SecurityLevel level,
552 bool *isSupported) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800553 Mutex::Autolock autoLock(mLock);
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800554 *isSupported = false;
555 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
556 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
557 return matchMimeTypeAndSecurityLevel(mFactories[i],
558 uuid, mimeType, level, isSupported);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800559 }
560 }
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800561 return OK;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800562}
563
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800564status_t DrmHal::createPlugin(const uint8_t uuid[16],
565 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800566 Mutex::Autolock autoLock(mLock);
567
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -0800568 for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800569 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
Peter Kalauskas7676a402018-12-27 11:04:16 -0800570 auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
571 if (plugin != NULL) {
572 mPlugin = plugin;
Edwin Wong5641aa22018-01-30 17:52:21 -0800573 mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
Jeff Tinkerc8baaba2018-10-23 11:32:36 -0700574 mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
Robert Shihfbe581e2021-01-14 05:12:04 -0800575 mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
Peter Kalauskas7676a402018-12-27 11:04:16 -0800576 break;
Edwin Wong5641aa22018-01-30 17:52:21 -0800577 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800578 }
579 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800580
581 if (mPlugin == NULL) {
582 mInitCheck = ERROR_UNSUPPORTED;
583 } else {
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800584 mInitCheck = OK;
585 if (mPluginV1_2 != NULL) {
586 if (!mPluginV1_2->setListener(this).isOk()) {
587 mInitCheck = DEAD_OBJECT;
588 }
589 } else if (!mPlugin->setListener(this).isOk()) {
Jeff Tinker319d5f42017-07-26 15:44:33 -0700590 mInitCheck = DEAD_OBJECT;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800591 }
592 if (mInitCheck != OK) {
593 mPlugin.clear();
594 mPluginV1_1.clear();
595 mPluginV1_2.clear();
Robert Shihfbe581e2021-01-14 05:12:04 -0800596 mPluginV1_4.clear();
Jeff Tinker319d5f42017-07-26 15:44:33 -0700597 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800598 }
599
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800600
Jeff Tinkera53d6552017-01-20 00:31:46 -0800601 return mInitCheck;
602}
603
604status_t DrmHal::destroyPlugin() {
Jeff Tinker7dfe28f2018-02-15 12:17:40 -0800605 cleanup();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800606 return OK;
607}
608
Jeff Tinker41d279a2018-02-11 19:52:08 +0000609status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
610 Vector<uint8_t> &sessionId) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800611 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800612 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800613
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800614 SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
Jeff Tinker41d279a2018-02-11 19:52:08 +0000615 bool setSecurityLevel = true;
Tobias Thierer5f5e43f2018-02-11 15:00:57 +0000616
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800617 if (level == DrmPlugin::kSecurityLevelMax) {
Jeff Tinker41d279a2018-02-11 19:52:08 +0000618 setSecurityLevel = false;
Jeff Tinker99dbfa82019-01-17 17:27:06 -0800619 } else {
620 if (hSecurityLevel == SecurityLevel::UNKNOWN) {
621 return ERROR_DRM_CANNOT_HANDLE;
622 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000623 }
624
625 status_t err = UNKNOWN_ERROR;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800626 bool retry = true;
627 do {
628 hidl_vec<uint8_t> hSessionId;
629
Jeff Tinker41d279a2018-02-11 19:52:08 +0000630 Return<void> hResult;
631 if (mPluginV1_1 == NULL || !setSecurityLevel) {
632 hResult = mPlugin->openSession(
633 [&](Status status,const hidl_vec<uint8_t>& id) {
634 if (status == Status::OK) {
635 sessionId = toVector(id);
636 }
637 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800638 }
Jeff Tinker41d279a2018-02-11 19:52:08 +0000639 );
640 } else {
641 hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
642 [&](Status status, const hidl_vec<uint8_t>& id) {
643 if (status == Status::OK) {
644 sessionId = toVector(id);
645 }
646 err = toStatusT(status);
647 }
648 );
649 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800650
651 if (!hResult.isOk()) {
652 err = DEAD_OBJECT;
653 }
654
655 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
656 mLock.unlock();
657 // reclaimSession may call back to closeSession, since mLock is
658 // shared between Drm instances, we should unlock here to avoid
659 // deadlock.
Robert Shih6152d7c2019-11-19 22:54:27 -0800660 retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
Jeff Tinkera53d6552017-01-20 00:31:46 -0800661 mLock.lock();
662 } else {
663 retry = false;
664 }
665 } while (retry);
666
667 if (err == OK) {
Steven Morelande0496a22020-02-13 13:13:52 -0800668 std::shared_ptr<DrmSessionClient> client =
669 ndk::SharedRefBase::make<DrmSessionClient>(this, sessionId);
Robert Shih6152d7c2019-11-19 22:54:27 -0800670 DrmSessionManager::Instance()->addSession(AIBinder_getCallingPid(),
Robert Shih0f3a8a02019-11-14 15:43:39 -0800671 std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
672 mOpenSessions.push_back(client);
Adam Stone568b3c42018-01-31 12:57:16 -0800673 mMetrics.SetSessionStart(sessionId);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800674 }
Adam Stoneaaf87dd2018-01-08 11:55:06 -0800675
Adam Stonef0e618d2018-01-17 19:20:41 -0800676 mMetrics.mOpenSessionCounter.Increment(err);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800677 return err;
678}
679
680status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
681 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800682 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800683
Jeff Tinker319d5f42017-07-26 15:44:33 -0700684 Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
685 if (status.isOk()) {
686 if (status == Status::OK) {
687 DrmSessionManager::Instance()->removeSession(sessionId);
Robert Shih0f3a8a02019-11-14 15:43:39 -0800688 for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
689 if (isEqualSessionId((*i)->mSessionId, sessionId)) {
690 mOpenSessions.erase(i);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700691 break;
692 }
Jeff Tinker61332812017-05-15 16:53:10 -0700693 }
694 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800695 status_t response = toStatusT(status);
Adam Stone568b3c42018-01-31 12:57:16 -0800696 mMetrics.SetSessionEnd(sessionId);
Adam Stonecea91ce2018-01-22 19:23:28 -0800697 mMetrics.mCloseSessionCounter.Increment(response);
698 return response;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800699 }
Adam Stonecea91ce2018-01-22 19:23:28 -0800700 mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
Jeff Tinker319d5f42017-07-26 15:44:33 -0700701 return DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800702}
703
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800704static DrmPlugin::KeyRequestType toKeyRequestType(
705 KeyRequestType keyRequestType) {
706 switch (keyRequestType) {
707 case KeyRequestType::INITIAL:
708 return DrmPlugin::kKeyRequestType_Initial;
709 break;
710 case KeyRequestType::RENEWAL:
711 return DrmPlugin::kKeyRequestType_Renewal;
712 break;
713 case KeyRequestType::RELEASE:
714 return DrmPlugin::kKeyRequestType_Release;
715 break;
716 default:
717 return DrmPlugin::kKeyRequestType_Unknown;
718 break;
719 }
720}
721
722static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
723 KeyRequestType_V1_1 keyRequestType) {
724 switch (keyRequestType) {
725 case KeyRequestType_V1_1::NONE:
726 return DrmPlugin::kKeyRequestType_None;
727 break;
728 case KeyRequestType_V1_1::UPDATE:
729 return DrmPlugin::kKeyRequestType_Update;
730 break;
731 default:
732 return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
733 break;
734 }
735}
736
Jeff Tinkera53d6552017-01-20 00:31:46 -0800737status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
738 Vector<uint8_t> const &initData, String8 const &mimeType,
739 DrmPlugin::KeyType keyType, KeyedVector<String8,
740 String8> const &optionalParameters, Vector<uint8_t> &request,
741 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
742 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800743 INIT_CHECK();
Adam Stonefb679e32018-02-07 10:25:48 -0800744 EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800745
746 DrmSessionManager::Instance()->useSession(sessionId);
747
748 KeyType hKeyType;
749 if (keyType == DrmPlugin::kKeyType_Streaming) {
750 hKeyType = KeyType::STREAMING;
751 } else if (keyType == DrmPlugin::kKeyType_Offline) {
752 hKeyType = KeyType::OFFLINE;
753 } else if (keyType == DrmPlugin::kKeyType_Release) {
754 hKeyType = KeyType::RELEASE;
755 } else {
Adam Stonef0e618d2018-01-17 19:20:41 -0800756 keyRequestTimer.SetAttribute(BAD_VALUE);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800757 return BAD_VALUE;
758 }
759
760 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
761
762 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800763 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800764
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800765 if (mPluginV1_2 != NULL) {
766 hResult = mPluginV1_2->getKeyRequest_1_2(
767 toHidlVec(sessionId), toHidlVec(initData),
768 toHidlString(mimeType), hKeyType, hOptionalParameters,
769 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
770 KeyRequestType_V1_1 hKeyRequestType,
771 const hidl_string& hDefaultUrl) {
772 if (status == Status_V1_2::OK) {
773 request = toVector(hRequest);
774 defaultUrl = toString8(hDefaultUrl);
775 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
776 }
Robert Shih5944a0b2021-02-10 04:26:33 -0800777 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800778 });
779 } else if (mPluginV1_1 != NULL) {
780 hResult = mPluginV1_1->getKeyRequest_1_1(
Rahul Frias59bc3fa2018-01-22 23:48:52 -0800781 toHidlVec(sessionId), toHidlVec(initData),
782 toHidlString(mimeType), hKeyType, hOptionalParameters,
783 [&](Status status, const hidl_vec<uint8_t>& hRequest,
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800784 KeyRequestType_V1_1 hKeyRequestType,
785 const hidl_string& hDefaultUrl) {
786 if (status == Status::OK) {
787 request = toVector(hRequest);
788 defaultUrl = toString8(hDefaultUrl);
789 *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800790 }
791 err = toStatusT(status);
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800792 });
793 } else {
794 hResult = mPlugin->getKeyRequest(
795 toHidlVec(sessionId), toHidlVec(initData),
796 toHidlString(mimeType), hKeyType, hOptionalParameters,
797 [&](Status status, const hidl_vec<uint8_t>& hRequest,
798 KeyRequestType hKeyRequestType,
799 const hidl_string& hDefaultUrl) {
800 if (status == Status::OK) {
801 request = toVector(hRequest);
802 defaultUrl = toString8(hDefaultUrl);
803 *keyRequestType = toKeyRequestType(hKeyRequestType);
804 }
805 err = toStatusT(status);
806 });
807 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800808
Adam Stonef0e618d2018-01-17 19:20:41 -0800809 err = hResult.isOk() ? err : DEAD_OBJECT;
810 keyRequestTimer.SetAttribute(err);
811 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800812}
813
814status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
815 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
816 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800817 INIT_CHECK();
George Burgess IVc42403d2019-10-18 09:54:32 -0700818 EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800819
820 DrmSessionManager::Instance()->useSession(sessionId);
821
822 status_t err = UNKNOWN_ERROR;
823
824 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
825 toHidlVec(response),
826 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
827 if (status == Status::OK) {
828 keySetId = toVector(hKeySetId);
829 }
830 err = toStatusT(status);
831 }
832 );
Adam Stonecea91ce2018-01-22 19:23:28 -0800833 err = hResult.isOk() ? err : DEAD_OBJECT;
834 keyResponseTimer.SetAttribute(err);
835 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800836}
837
838status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
839 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800840 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800841
Jeff Tinker58ad4752018-02-16 16:51:59 -0800842 Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
843 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800844}
845
846status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
847 Vector<uint8_t> const &keySetId) {
848 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800849 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800850
851 DrmSessionManager::Instance()->useSession(sessionId);
852
Jeff Tinker58ad4752018-02-16 16:51:59 -0800853 Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId),
854 toHidlVec(keySetId));
855 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800856}
857
858status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
859 KeyedVector<String8, String8> &infoMap) const {
860 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800861 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800862
863 DrmSessionManager::Instance()->useSession(sessionId);
864
865 ::KeyedVector hInfoMap;
866
867 status_t err = UNKNOWN_ERROR;
868
869 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
870 [&](Status status, const hidl_vec<KeyValue>& map) {
871 if (status == Status::OK) {
872 infoMap = toKeyedVector(map);
873 }
874 err = toStatusT(status);
875 }
876 );
877
878 return hResult.isOk() ? err : DEAD_OBJECT;
879}
880
881status_t DrmHal::getProvisionRequest(String8 const &certType,
882 String8 const &certAuthority, Vector<uint8_t> &request,
883 String8 &defaultUrl) {
884 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800885 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800886
887 status_t err = UNKNOWN_ERROR;
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800888 Return<void> hResult;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800889
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800890 if (mPluginV1_2 != NULL) {
891 Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
892 toHidlString(certType), toHidlString(certAuthority),
893 [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
894 const hidl_string& hDefaultUrl) {
895 if (status == Status_V1_2::OK) {
896 request = toVector(hRequest);
897 defaultUrl = toString8(hDefaultUrl);
898 }
Robert Shih5944a0b2021-02-10 04:26:33 -0800899 err = toStatusT(status);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800900 }
Jeff Tinkerb8684f32018-12-12 08:41:31 -0800901 );
902 } else {
903 Return<void> hResult = mPlugin->getProvisionRequest(
904 toHidlString(certType), toHidlString(certAuthority),
905 [&](Status status, const hidl_vec<uint8_t>& hRequest,
906 const hidl_string& hDefaultUrl) {
907 if (status == Status::OK) {
908 request = toVector(hRequest);
909 defaultUrl = toString8(hDefaultUrl);
910 }
911 err = toStatusT(status);
912 }
913 );
914 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800915
Adam Stonecea91ce2018-01-22 19:23:28 -0800916 err = hResult.isOk() ? err : DEAD_OBJECT;
917 mMetrics.mGetProvisionRequestCounter.Increment(err);
918 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800919}
920
921status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800922 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800923 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800924 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800925
926 status_t err = UNKNOWN_ERROR;
927
928 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
929 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
930 const hidl_vec<uint8_t>& hWrappedKey) {
931 if (status == Status::OK) {
932 certificate = toVector(hCertificate);
933 wrappedKey = toVector(hWrappedKey);
934 }
935 err = toStatusT(status);
936 }
937 );
938
Adam Stonecea91ce2018-01-22 19:23:28 -0800939 err = hResult.isOk() ? err : DEAD_OBJECT;
940 mMetrics.mProvideProvisionResponseCounter.Increment(err);
941 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800942}
943
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800944status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800945 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800946 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800947
948 status_t err = UNKNOWN_ERROR;
949
950 Return<void> hResult = mPlugin->getSecureStops(
951 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
952 if (status == Status::OK) {
953 secureStops = toSecureStops(hSecureStops);
954 }
955 err = toStatusT(status);
956 }
957 );
958
959 return hResult.isOk() ? err : DEAD_OBJECT;
960}
961
962
Jeff Tinker15177d72018-01-25 12:57:55 -0800963status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) {
964 Mutex::Autolock autoLock(mLock);
965
966 if (mInitCheck != OK) {
967 return mInitCheck;
968 }
969
970 if (mPluginV1_1 == NULL) {
971 return ERROR_DRM_CANNOT_HANDLE;
972 }
973
974 status_t err = UNKNOWN_ERROR;
975
976 Return<void> hResult = mPluginV1_1->getSecureStopIds(
977 [&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
978 if (status == Status::OK) {
979 secureStopIds = toSecureStopIds(hSecureStopIds);
980 }
981 err = toStatusT(status);
982 }
983 );
984
985 return hResult.isOk() ? err : DEAD_OBJECT;
986}
987
988
Jeff Tinkera53d6552017-01-20 00:31:46 -0800989status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
990 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -0800991 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -0800992
993 status_t err = UNKNOWN_ERROR;
994
995 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
996 [&](Status status, const SecureStop& hSecureStop) {
997 if (status == Status::OK) {
998 secureStop = toVector(hSecureStop.opaqueData);
999 }
1000 err = toStatusT(status);
1001 }
1002 );
1003
1004 return hResult.isOk() ? err : DEAD_OBJECT;
1005}
1006
1007status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
1008 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001009 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001010
Jeff Tinker58ad4752018-02-16 16:51:59 -08001011 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001012 if (mPluginV1_1 != NULL) {
1013 SecureStopRelease secureStopRelease;
1014 secureStopRelease.opaqueData = toHidlVec(ssRelease);
Jeff Tinker58ad4752018-02-16 16:51:59 -08001015 status = mPluginV1_1->releaseSecureStops(secureStopRelease);
1016 } else {
1017 status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
Jeff Tinker15177d72018-01-25 12:57:55 -08001018 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001019 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001020}
1021
Jeff Tinker15177d72018-01-25 12:57:55 -08001022status_t DrmHal::removeSecureStop(Vector<uint8_t> const &ssid) {
1023 Mutex::Autolock autoLock(mLock);
1024
1025 if (mInitCheck != OK) {
1026 return mInitCheck;
1027 }
1028
1029 if (mPluginV1_1 == NULL) {
1030 return ERROR_DRM_CANNOT_HANDLE;
1031 }
1032
Jeff Tinker58ad4752018-02-16 16:51:59 -08001033 Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
1034 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinker15177d72018-01-25 12:57:55 -08001035}
1036
1037status_t DrmHal::removeAllSecureStops() {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001038 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001039 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001040
Jeff Tinker58ad4752018-02-16 16:51:59 -08001041 Return<Status> status(Status::ERROR_DRM_UNKNOWN);
Jeff Tinker15177d72018-01-25 12:57:55 -08001042 if (mPluginV1_1 != NULL) {
Jeff Tinker58ad4752018-02-16 16:51:59 -08001043 status = mPluginV1_1->removeAllSecureStops();
1044 } else {
1045 status = mPlugin->releaseAllSecureStops();
Jeff Tinker15177d72018-01-25 12:57:55 -08001046 }
Jeff Tinker58ad4752018-02-16 16:51:59 -08001047 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001048}
1049
Jeff Tinker6d998b62017-12-18 14:37:43 -08001050status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
1051 DrmPlugin::HdcpLevel *max) const {
1052 Mutex::Autolock autoLock(mLock);
1053 INIT_CHECK();
1054
1055 if (connected == NULL || max == NULL) {
1056 return BAD_VALUE;
1057 }
1058 status_t err = UNKNOWN_ERROR;
1059
Jeff Tinker6d998b62017-12-18 14:37:43 -08001060 *connected = DrmPlugin::kHdcpLevelUnknown;
1061 *max = DrmPlugin::kHdcpLevelUnknown;
1062
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001063 Return<void> hResult;
1064 if (mPluginV1_2 != NULL) {
1065 hResult = mPluginV1_2->getHdcpLevels_1_2(
1066 [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
1067 if (status == Status_V1_2::OK) {
1068 *connected = toHdcpLevel(hConnected);
1069 *max = toHdcpLevel(hMax);
1070 }
Robert Shih5944a0b2021-02-10 04:26:33 -08001071 err = toStatusT(status);
Jeff Tinker44c2cc42019-01-14 10:24:18 -08001072 });
1073 } else if (mPluginV1_1 != NULL) {
1074 hResult = mPluginV1_1->getHdcpLevels(
1075 [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
1076 if (status == Status::OK) {
1077 *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
1078 *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
1079 }
1080 err = toStatusT(status);
1081 });
1082 } else {
1083 return ERROR_DRM_CANNOT_HANDLE;
1084 }
Jeff Tinker6d998b62017-12-18 14:37:43 -08001085
1086 return hResult.isOk() ? err : DEAD_OBJECT;
1087}
1088
1089status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
1090 Mutex::Autolock autoLock(mLock);
1091 INIT_CHECK();
1092
1093 if (open == NULL || max == NULL) {
1094 return BAD_VALUE;
1095 }
1096 status_t err = UNKNOWN_ERROR;
1097
1098 *open = 0;
1099 *max = 0;
1100
1101 if (mPluginV1_1 == NULL) {
1102 return ERROR_DRM_CANNOT_HANDLE;
1103 }
1104
1105 Return<void> hResult = mPluginV1_1->getNumberOfSessions(
1106 [&](Status status, uint32_t hOpen, uint32_t hMax) {
1107 if (status == Status::OK) {
1108 *open = hOpen;
1109 *max = hMax;
1110 }
1111 err = toStatusT(status);
1112 }
1113 );
1114
1115 return hResult.isOk() ? err : DEAD_OBJECT;
1116}
1117
1118status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
1119 DrmPlugin::SecurityLevel *level) const {
1120 Mutex::Autolock autoLock(mLock);
1121 INIT_CHECK();
1122
1123 if (level == NULL) {
1124 return BAD_VALUE;
1125 }
1126 status_t err = UNKNOWN_ERROR;
1127
1128 if (mPluginV1_1 == NULL) {
1129 return ERROR_DRM_CANNOT_HANDLE;
1130 }
1131
1132 *level = DrmPlugin::kSecurityLevelUnknown;
1133
1134 Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
1135 [&](Status status, SecurityLevel hLevel) {
1136 if (status == Status::OK) {
1137 *level = toSecurityLevel(hLevel);
1138 }
1139 err = toStatusT(status);
1140 }
1141 );
1142
1143 return hResult.isOk() ? err : DEAD_OBJECT;
1144}
1145
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001146status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
1147 Mutex::Autolock autoLock(mLock);
1148
1149 if (mInitCheck != OK) {
1150 return mInitCheck;
1151 }
1152
1153 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001154 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001155 }
1156
1157 status_t err = UNKNOWN_ERROR;
1158
1159 Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
1160 [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
1161 if (status == Status::OK) {
1162 keySetIds = toKeySetIds(hKeySetIds);
1163 }
1164 err = toStatusT(status);
1165 }
1166 );
1167
1168 return hResult.isOk() ? err : DEAD_OBJECT;
1169}
1170
1171status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
1172 Mutex::Autolock autoLock(mLock);
1173
1174 if (mInitCheck != OK) {
1175 return mInitCheck;
1176 }
1177
1178 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001179 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001180 }
1181
1182 Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
1183 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
1184}
1185
1186status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
1187 DrmPlugin::OfflineLicenseState *licenseState) const {
1188 Mutex::Autolock autoLock(mLock);
1189
1190 if (mInitCheck != OK) {
1191 return mInitCheck;
1192 }
1193
1194 if (mPluginV1_2 == NULL) {
Jeff Tinkerdb3fa5f2019-01-25 22:56:56 -08001195 return ERROR_UNSUPPORTED;
Jeff Tinkerc8baaba2018-10-23 11:32:36 -07001196 }
1197 *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
1198
1199 status_t err = UNKNOWN_ERROR;
1200
1201 Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
1202 [&](Status status, OfflineLicenseState hLicenseState) {
1203 if (status == Status::OK) {
1204 *licenseState = toOfflineLicenseState(hLicenseState);
1205 }
1206 err = toStatusT(status);
1207 }
1208 );
1209
1210 return hResult.isOk() ? err : DEAD_OBJECT;
1211}
1212
Jeff Tinkera53d6552017-01-20 00:31:46 -08001213status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
1214 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001215 return getPropertyStringInternal(name, value);
1216}
1217
1218status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
1219 // This function is internal to the class and should only be called while
1220 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001221 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001222
1223 status_t err = UNKNOWN_ERROR;
1224
1225 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
1226 [&](Status status, const hidl_string& hValue) {
1227 if (status == Status::OK) {
1228 value = toString8(hValue);
1229 }
1230 err = toStatusT(status);
1231 }
1232 );
1233
1234 return hResult.isOk() ? err : DEAD_OBJECT;
1235}
1236
1237status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
1238 Mutex::Autolock autoLock(mLock);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001239 return getPropertyByteArrayInternal(name, value);
1240}
1241
1242status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
1243 // This function is internal to the class and should only be called while
1244 // mLock is already held.
Jeff Tinker6d998b62017-12-18 14:37:43 -08001245 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001246
1247 status_t err = UNKNOWN_ERROR;
1248
1249 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
1250 [&](Status status, const hidl_vec<uint8_t>& hValue) {
1251 if (status == Status::OK) {
1252 value = toVector(hValue);
1253 }
1254 err = toStatusT(status);
1255 }
1256 );
1257
Adam Stonecea91ce2018-01-22 19:23:28 -08001258 err = hResult.isOk() ? err : DEAD_OBJECT;
1259 if (name == kPropertyDeviceUniqueId) {
1260 mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
1261 }
1262 return err;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001263}
1264
1265status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
1266 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001267 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001268
Jeff Tinker58ad4752018-02-16 16:51:59 -08001269 Return<Status> status = mPlugin->setPropertyString(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001270 toHidlString(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001271 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001272}
1273
1274status_t DrmHal::setPropertyByteArray(String8 const &name,
1275 Vector<uint8_t> const &value ) const {
1276 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001277 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001278
Jeff Tinker58ad4752018-02-16 16:51:59 -08001279 Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001280 toHidlVec(value));
Jeff Tinker58ad4752018-02-16 16:51:59 -08001281 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001282}
1283
Robert Shih93538812019-11-12 12:21:35 -08001284status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
1285 if (consumer == nullptr) {
Adam Stone28f27c32018-02-05 15:07:48 -08001286 return UNEXPECTED_NULL;
1287 }
Robert Shih93538812019-11-12 12:21:35 -08001288 consumer->consumeFrameworkMetrics(mMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001289
1290 // Append vendor metrics if they are supported.
1291 if (mPluginV1_1 != NULL) {
1292 String8 vendor;
1293 String8 description;
1294 if (getPropertyStringInternal(String8("vendor"), vendor) != OK
1295 || vendor.isEmpty()) {
1296 ALOGE("Get vendor failed or is empty");
1297 vendor = "NONE";
1298 }
1299 if (getPropertyStringInternal(String8("description"), description) != OK
1300 || description.isEmpty()) {
1301 ALOGE("Get description failed or is empty.");
1302 description = "NONE";
1303 }
1304 vendor += ".";
1305 vendor += description;
1306
1307 hidl_vec<DrmMetricGroup> pluginMetrics;
1308 status_t err = UNKNOWN_ERROR;
1309
1310 Return<void> status = mPluginV1_1->getMetrics(
1311 [&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
1312 if (status != Status::OK) {
1313 ALOGV("Error getting plugin metrics: %d", status);
1314 } else {
Robert Shih93538812019-11-12 12:21:35 -08001315 consumer->consumeHidlMetrics(vendor, pluginMetrics);
Adam Stone28f27c32018-02-05 15:07:48 -08001316 }
1317 err = toStatusT(status);
1318 });
1319 return status.isOk() ? err : DEAD_OBJECT;
Adam Stonef0e618d2018-01-17 19:20:41 -08001320 }
1321
Adam Stoneab394d12017-12-22 12:34:20 -08001322 return OK;
1323}
Jeff Tinkera53d6552017-01-20 00:31:46 -08001324
1325status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
1326 String8 const &algorithm) {
1327 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001328 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001329
1330 DrmSessionManager::Instance()->useSession(sessionId);
1331
Jeff Tinkere6412942018-04-30 17:35:16 -07001332 Return<Status> status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001333 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001334 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001335}
1336
1337status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
1338 String8 const &algorithm) {
1339 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001340 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001341
1342 DrmSessionManager::Instance()->useSession(sessionId);
1343
Jeff Tinkere6412942018-04-30 17:35:16 -07001344 Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
Jeff Tinkera53d6552017-01-20 00:31:46 -08001345 toHidlString(algorithm));
Jeff Tinkere6412942018-04-30 17:35:16 -07001346 return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
Jeff Tinkera53d6552017-01-20 00:31:46 -08001347}
1348
1349status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001350 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1351 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001352 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001353 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001354
1355 DrmSessionManager::Instance()->useSession(sessionId);
1356
1357 status_t err = UNKNOWN_ERROR;
1358
1359 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
1360 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1361 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1362 if (status == Status::OK) {
1363 output = toVector(hOutput);
1364 }
1365 err = toStatusT(status);
1366 }
1367 );
1368
1369 return hResult.isOk() ? err : DEAD_OBJECT;
1370}
1371
1372status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001373 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
1374 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001375 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001376 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001377
1378 DrmSessionManager::Instance()->useSession(sessionId);
1379
1380 status_t err = UNKNOWN_ERROR;
1381
1382 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
1383 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
1384 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
1385 if (status == Status::OK) {
1386 output = toVector(hOutput);
1387 }
1388 err = toStatusT(status);
1389 }
1390 );
1391
1392 return hResult.isOk() ? err : DEAD_OBJECT;
1393}
1394
1395status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001396 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1397 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001398 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001399 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001400
1401 DrmSessionManager::Instance()->useSession(sessionId);
1402
1403 status_t err = UNKNOWN_ERROR;
1404
1405 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
1406 toHidlVec(keyId), toHidlVec(message),
1407 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1408 if (status == Status::OK) {
1409 signature = toVector(hSignature);
1410 }
1411 err = toStatusT(status);
1412 }
1413 );
1414
1415 return hResult.isOk() ? err : DEAD_OBJECT;
1416}
1417
1418status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001419 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
1420 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001421 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001422 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001423
1424 DrmSessionManager::Instance()->useSession(sessionId);
1425
1426 status_t err = UNKNOWN_ERROR;
1427
1428 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
1429 toHidlVec(message), toHidlVec(signature),
1430 [&](Status status, bool hMatch) {
1431 if (status == Status::OK) {
1432 match = hMatch;
1433 } else {
1434 match = false;
1435 }
1436 err = toStatusT(status);
1437 }
1438 );
1439
1440 return hResult.isOk() ? err : DEAD_OBJECT;
1441}
1442
1443status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -08001444 String8 const &algorithm, Vector<uint8_t> const &message,
1445 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -08001446 Mutex::Autolock autoLock(mLock);
Jeff Tinker6d998b62017-12-18 14:37:43 -08001447 INIT_CHECK();
Jeff Tinkera53d6552017-01-20 00:31:46 -08001448
Jeff Tinkera53d6552017-01-20 00:31:46 -08001449 DrmSessionManager::Instance()->useSession(sessionId);
1450
1451 status_t err = UNKNOWN_ERROR;
1452
1453 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
1454 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
1455 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
1456 if (status == Status::OK) {
1457 signature = toVector(hSignature);
1458 }
1459 err = toStatusT(status);
1460 }
1461 );
1462
1463 return hResult.isOk() ? err : DEAD_OBJECT;
1464}
1465
Adam Stonefb679e32018-02-07 10:25:48 -08001466void DrmHal::reportFrameworkMetrics() const
1467{
Robert Shih82ea6be2019-11-07 17:47:23 -08001468 mediametrics_handle_t item(mediametrics_create("mediadrm"));
1469 mediametrics_setUid(item, mMetrics.GetAppUid());
Adam Stonefb679e32018-02-07 10:25:48 -08001470 String8 vendor;
1471 String8 description;
1472 status_t result = getPropertyStringInternal(String8("vendor"), vendor);
1473 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001474 ALOGE("Failed to get vendor from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001475 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001476 mediametrics_setCString(item, "vendor", vendor.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001477 }
1478 result = getPropertyStringInternal(String8("description"), description);
1479 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001480 ALOGE("Failed to get description from drm plugin: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001481 } else {
Robert Shih82ea6be2019-11-07 17:47:23 -08001482 mediametrics_setCString(item, "description", description.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001483 }
Adam Stoneab394d12017-12-22 12:34:20 -08001484
Adam Stonefb679e32018-02-07 10:25:48 -08001485 std::string serializedMetrics;
1486 result = mMetrics.GetSerializedMetrics(&serializedMetrics);
1487 if (result != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001488 ALOGE("Failed to serialize framework metrics: %d", result);
Adam Stonefb679e32018-02-07 10:25:48 -08001489 }
Adam Stone32494f52018-02-26 22:53:27 -08001490 std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
1491 serializedMetrics.size());
1492 if (!b64EncodedMetrics.empty()) {
Robert Shih82ea6be2019-11-07 17:47:23 -08001493 mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
Adam Stonefb679e32018-02-07 10:25:48 -08001494 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001495 if (!mediametrics_selfRecord(item)) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001496 ALOGE("Failed to self record framework metrics");
Adam Stonefb679e32018-02-07 10:25:48 -08001497 }
Robert Shih82ea6be2019-11-07 17:47:23 -08001498 mediametrics_delete(item);
Adam Stonefb679e32018-02-07 10:25:48 -08001499}
1500
1501void DrmHal::reportPluginMetrics() const
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001502{
Adam Stone32494f52018-02-26 22:53:27 -08001503 Vector<uint8_t> metricsVector;
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001504 String8 vendor;
1505 String8 description;
1506 if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
1507 getPropertyStringInternal(String8("description"), description) == OK &&
Adam Stone32494f52018-02-26 22:53:27 -08001508 getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
1509 std::string metricsString = toBase64StringNoPad(metricsVector.array(),
1510 metricsVector.size());
1511 status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
Robert Shih82ea6be2019-11-07 17:47:23 -08001512 description, mMetrics.GetAppUid());
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001513 if (res != OK) {
Jeff Tinker987ac702018-02-15 17:02:22 -08001514 ALOGE("Metrics were retrieved but could not be reported: %d", res);
John W. Bruce33ecc4f2017-04-03 16:49:05 -07001515 }
1516 }
1517}
1518
Robert Shihfbe581e2021-01-14 05:12:04 -08001519bool DrmHal::requiresSecureDecoder(const char *mime) const {
1520 Mutex::Autolock autoLock(mLock);
1521 if (mPluginV1_4 == NULL) {
1522 return false;
1523 }
1524 return mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
1525}
1526
1527bool DrmHal::requiresSecureDecoder(const char *mime,
1528 DrmPlugin::SecurityLevel securityLevel) const {
1529 Mutex::Autolock autoLock(mLock);
1530 if (mPluginV1_4 == NULL) {
1531 return false;
1532 }
1533 auto hLevel = toHidlSecurityLevel(securityLevel);
1534 return mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
1535}
1536
Robert Shih726afea2021-01-17 23:41:12 -08001537status_t DrmHal::setPlaybackId(Vector<uint8_t> const &sessionId, const char *playbackId) {
1538 Mutex::Autolock autoLock(mLock);
1539 if (mPluginV1_4 == NULL) {
1540 return ERROR_UNSUPPORTED;
1541 }
1542 drm::V1_0::Status err = mPluginV1_4->setPlaybackId(
1543 toHidlVec(sessionId),
1544 hidl_string(playbackId));
1545 return toStatusT(err);
1546}
1547
Robert Shih9afca952021-02-12 01:36:06 -08001548status_t DrmHal::getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const {
1549 Mutex::Autolock autoLock(mLock);
1550 return DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs);
1551}
1552
Jeff Tinkera53d6552017-01-20 00:31:46 -08001553} // namespace android