blob: 4989b03bf3fd8fd3e92555752f422c5e56dbae5c [file] [log] [blame]
Robert Shih28c2ed32019-10-27 22:55:12 -07001/*
2 * Copyright (C) 2019 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 "DrmUtils"
19
Robert Shih10fe9432019-11-09 08:26:49 -080020#include <android/hardware/drm/1.0/ICryptoFactory.h>
21#include <android/hardware/drm/1.0/ICryptoPlugin.h>
Robert Shih5ff3ad62019-11-09 08:26:49 -080022#include <android/hardware/drm/1.0/IDrmFactory.h>
23#include <android/hardware/drm/1.0/IDrmPlugin.h>
Robert Shih10fe9432019-11-09 08:26:49 -080024#include <android/hardware/drm/1.1/ICryptoFactory.h>
Robert Shih5ff3ad62019-11-09 08:26:49 -080025#include <android/hardware/drm/1.1/IDrmFactory.h>
Robert Shih10fe9432019-11-09 08:26:49 -080026#include <android/hardware/drm/1.2/ICryptoFactory.h>
Robert Shih5ff3ad62019-11-09 08:26:49 -080027#include <android/hardware/drm/1.2/IDrmFactory.h>
Robert Shih2c377872019-11-24 22:17:46 -080028#include <android/hardware/drm/1.3/ICryptoFactory.h>
29#include <android/hardware/drm/1.3/IDrmFactory.h>
Robert Shih8635cb12021-02-26 07:57:55 -080030#include <android/hardware/drm/1.4/ICryptoFactory.h>
31#include <android/hardware/drm/1.4/IDrmFactory.h>
Juju Sunga4cfeca2020-04-10 15:02:32 +080032#include <android/hidl/manager/1.2/IServiceManager.h>
Robert Shih10fe9432019-11-09 08:26:49 -080033#include <hidl/HidlSupport.h>
34
35#include <utils/Errors.h>
36#include <utils/Log.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070037#include <utils/String16.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070038#include <cutils/properties.h>
39
40#include <mediadrm/CryptoHal.h>
41#include <mediadrm/DrmHal.h>
42#include <mediadrm/DrmUtils.h>
43#include <mediadrm/ICrypto.h>
44#include <mediadrm/IDrm.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070045
Juju Sunga4cfeca2020-04-10 15:02:32 +080046using HServiceManager = ::android::hidl::manager::V1_2::IServiceManager;
Robert Shih10fe9432019-11-09 08:26:49 -080047using ::android::hardware::hidl_array;
48using ::android::hardware::hidl_string;
49using ::android::hardware::hidl_vec;
50using namespace ::android::hardware::drm;
51
Robert Shih28c2ed32019-10-27 22:55:12 -070052namespace android {
53namespace DrmUtils {
54
55namespace {
Robert Shih6571bf62019-11-10 15:03:01 -080056
57template<typename Hal>
58Hal *MakeObject(status_t *pstatus) {
Robert Shih28c2ed32019-10-27 22:55:12 -070059 status_t err = OK;
60 status_t &status = pstatus ? *pstatus : err;
Robert Shih6571bf62019-11-10 15:03:01 -080061 auto obj = new Hal();
Robert Shih28c2ed32019-10-27 22:55:12 -070062 status = obj->initCheck();
63 if (status != OK && status != NO_INIT) {
64 return NULL;
65 }
66 return obj;
67}
68
Robert Shih10fe9432019-11-09 08:26:49 -080069template <typename Hal, typename V>
Robert Shih5ff3ad62019-11-09 08:26:49 -080070void MakeHidlFactories(const uint8_t uuid[16], V &factories) {
Robert Shih10fe9432019-11-09 08:26:49 -080071 sp<HServiceManager> serviceManager = HServiceManager::getService();
72 if (serviceManager == nullptr) {
Robert Shih8635cb12021-02-26 07:57:55 -080073 LOG2BE("Failed to get service manager");
74 return;
Robert Shih10fe9432019-11-09 08:26:49 -080075 }
76
Juju Sunga4cfeca2020-04-10 15:02:32 +080077 serviceManager->listManifestByInterface(Hal::descriptor, [&](const hidl_vec<hidl_string> &registered) {
Robert Shih10fe9432019-11-09 08:26:49 -080078 for (const auto &instance : registered) {
79 auto factory = Hal::getService(instance);
80 if (factory != nullptr) {
Robert Shih8635cb12021-02-26 07:57:55 -080081 LOG2BI("found %s %s", Hal::descriptor, instance.c_str());
Robert Shihc0d1d0e2019-11-24 13:21:04 -080082 if (!uuid || factory->isCryptoSchemeSupported(uuid)) {
Robert Shih5ff3ad62019-11-09 08:26:49 -080083 factories.push_back(factory);
Robert Shih10fe9432019-11-09 08:26:49 -080084 }
85 }
86 }
87 });
88}
89
90hidl_vec<uint8_t> toHidlVec(const void *ptr, size_t size) {
91 hidl_vec<uint8_t> vec(size);
92 if (ptr != nullptr) {
93 memcpy(vec.data(), ptr, size);
94 }
95 return vec;
96}
97
98hidl_array<uint8_t, 16> toHidlArray16(const uint8_t *ptr) {
99 if (ptr == nullptr) {
100 return hidl_array<uint8_t, 16>();
101 }
102 return hidl_array<uint8_t, 16>(ptr);
103}
104
Robert Shih5ff3ad62019-11-09 08:26:49 -0800105sp<::V1_0::IDrmPlugin> MakeDrmPlugin(const sp<::V1_0::IDrmFactory> &factory,
106 const uint8_t uuid[16], const char *appPackageName) {
107 sp<::V1_0::IDrmPlugin> plugin;
108 factory->createPlugin(toHidlArray16(uuid), hidl_string(appPackageName),
109 [&](::V1_0::Status status, const sp<::V1_0::IDrmPlugin> &hPlugin) {
110 if (status != ::V1_0::Status::OK) {
Robert Shih8635cb12021-02-26 07:57:55 -0800111 LOG2BE("MakeDrmPlugin failed: %d", status);
Robert Shih5ff3ad62019-11-09 08:26:49 -0800112 return;
113 }
114 plugin = hPlugin;
115 });
116 return plugin;
117}
118
Robert Shih10fe9432019-11-09 08:26:49 -0800119sp<::V1_0::ICryptoPlugin> MakeCryptoPlugin(const sp<::V1_0::ICryptoFactory> &factory,
120 const uint8_t uuid[16], const void *initData,
121 size_t initDataSize) {
122 sp<::V1_0::ICryptoPlugin> plugin;
123 factory->createPlugin(toHidlArray16(uuid), toHidlVec(initData, initDataSize),
124 [&](::V1_0::Status status, const sp<::V1_0::ICryptoPlugin> &hPlugin) {
125 if (status != ::V1_0::Status::OK) {
Robert Shih8635cb12021-02-26 07:57:55 -0800126 LOG2BE("MakeCryptoPlugin failed: %d", status);
Robert Shih10fe9432019-11-09 08:26:49 -0800127 return;
128 }
129 plugin = hPlugin;
130 });
131 return plugin;
132}
133
Robert Shih28c2ed32019-10-27 22:55:12 -0700134} // namespace
135
136bool UseDrmService() {
Robert Shih17c6d822019-11-07 11:31:43 -0800137 return property_get_bool("mediadrm.use_mediadrmserver", true);
Robert Shih28c2ed32019-10-27 22:55:12 -0700138}
139
140sp<IDrm> MakeDrm(status_t *pstatus) {
Robert Shih6571bf62019-11-10 15:03:01 -0800141 return MakeObject<DrmHal>(pstatus);
Robert Shih28c2ed32019-10-27 22:55:12 -0700142}
143
144sp<ICrypto> MakeCrypto(status_t *pstatus) {
Robert Shih6571bf62019-11-10 15:03:01 -0800145 return MakeObject<CryptoHal>(pstatus);
Robert Shih28c2ed32019-10-27 22:55:12 -0700146}
147
Robert Shih5ff3ad62019-11-09 08:26:49 -0800148std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16]) {
149 std::vector<sp<::V1_0::IDrmFactory>> drmFactories;
150 MakeHidlFactories<::V1_0::IDrmFactory>(uuid, drmFactories);
151 MakeHidlFactories<::V1_1::IDrmFactory>(uuid, drmFactories);
152 MakeHidlFactories<::V1_2::IDrmFactory>(uuid, drmFactories);
Robert Shih2c377872019-11-24 22:17:46 -0800153 MakeHidlFactories<::V1_3::IDrmFactory>(uuid, drmFactories);
Robert Shih8635cb12021-02-26 07:57:55 -0800154 MakeHidlFactories<::V1_4::IDrmFactory>(uuid, drmFactories);
Robert Shih5ff3ad62019-11-09 08:26:49 -0800155 return drmFactories;
156}
157
158std::vector<sp<::V1_0::IDrmPlugin>> MakeDrmPlugins(const uint8_t uuid[16],
159 const char *appPackageName) {
160 std::vector<sp<::V1_0::IDrmPlugin>> plugins;
161 for (const auto &factory : MakeDrmFactories(uuid)) {
162 plugins.push_back(MakeDrmPlugin(factory, uuid, appPackageName));
163 }
164 return plugins;
165}
166
Robert Shih10fe9432019-11-09 08:26:49 -0800167std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]) {
168 std::vector<sp<::V1_0::ICryptoFactory>> cryptoFactories;
Robert Shih5ff3ad62019-11-09 08:26:49 -0800169 MakeHidlFactories<::V1_0::ICryptoFactory>(uuid, cryptoFactories);
170 MakeHidlFactories<::V1_1::ICryptoFactory>(uuid, cryptoFactories);
171 MakeHidlFactories<::V1_2::ICryptoFactory>(uuid, cryptoFactories);
Robert Shih2c377872019-11-24 22:17:46 -0800172 MakeHidlFactories<::V1_3::ICryptoFactory>(uuid, cryptoFactories);
Robert Shih8635cb12021-02-26 07:57:55 -0800173 MakeHidlFactories<::V1_4::ICryptoFactory>(uuid, cryptoFactories);
Robert Shih10fe9432019-11-09 08:26:49 -0800174 return cryptoFactories;
175}
176
177std::vector<sp<ICryptoPlugin>> MakeCryptoPlugins(const uint8_t uuid[16], const void *initData,
178 size_t initDataSize) {
179 std::vector<sp<ICryptoPlugin>> plugins;
180 for (const auto &factory : MakeCryptoFactories(uuid)) {
181 plugins.push_back(MakeCryptoPlugin(factory, uuid, initData, initDataSize));
182 }
183 return plugins;
184}
185
Robert Shih5944a0b2021-02-10 04:26:33 -0800186status_t toStatusT_1_4(::V1_4::Status status) {
187 switch (status) {
188 case ::V1_4::Status::OK:
189 return OK;
190 case ::V1_4::Status::BAD_VALUE:
191 return BAD_VALUE;
192 case ::V1_4::Status::ERROR_DRM_CANNOT_HANDLE:
193 return ERROR_DRM_CANNOT_HANDLE;
194 case ::V1_4::Status::ERROR_DRM_DECRYPT:
195 return ERROR_DRM_DECRYPT;
196 case ::V1_4::Status::ERROR_DRM_DEVICE_REVOKED:
197 return ERROR_DRM_DEVICE_REVOKED;
198 case ::V1_4::Status::ERROR_DRM_FRAME_TOO_LARGE:
199 return ERROR_DRM_FRAME_TOO_LARGE;
200 case ::V1_4::Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
201 return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
202 case ::V1_4::Status::ERROR_DRM_INSUFFICIENT_SECURITY:
203 return ERROR_DRM_INSUFFICIENT_SECURITY;
204 case ::V1_4::Status::ERROR_DRM_INVALID_STATE:
205 return ERROR_DRM_INVALID_STATE;
206 case ::V1_4::Status::ERROR_DRM_LICENSE_EXPIRED:
207 return ERROR_DRM_LICENSE_EXPIRED;
208 case ::V1_4::Status::ERROR_DRM_NO_LICENSE:
209 return ERROR_DRM_NO_LICENSE;
210 case ::V1_4::Status::ERROR_DRM_NOT_PROVISIONED:
211 return ERROR_DRM_NOT_PROVISIONED;
212 case ::V1_4::Status::ERROR_DRM_RESOURCE_BUSY:
213 return ERROR_DRM_RESOURCE_BUSY;
214 case ::V1_4::Status::ERROR_DRM_RESOURCE_CONTENTION:
215 return ERROR_DRM_RESOURCE_CONTENTION;
216 case ::V1_4::Status::ERROR_DRM_SESSION_LOST_STATE:
217 return ERROR_DRM_SESSION_LOST_STATE;
218 case ::V1_4::Status::ERROR_DRM_SESSION_NOT_OPENED:
219 return ERROR_DRM_SESSION_NOT_OPENED;
220
221 // New in S / drm@1.4:
222 case ::V1_4::Status::CANNOT_DECRYPT_ZERO_SUBSAMPLES:
223 return ERROR_DRM_ZERO_SUBSAMPLES;
224 case ::V1_4::Status::CRYPTO_LIBRARY_ERROR:
225 return ERROR_DRM_CRYPTO_LIBRARY;
226 case ::V1_4::Status::GENERAL_OEM_ERROR:
227 return ERROR_DRM_GENERIC_OEM;
228 case ::V1_4::Status::GENERAL_PLUGIN_ERROR:
229 return ERROR_DRM_GENERIC_PLUGIN;
230 case ::V1_4::Status::INIT_DATA_INVALID:
231 return ERROR_DRM_INIT_DATA;
232 case ::V1_4::Status::KEY_NOT_LOADED:
233 return ERROR_DRM_KEY_NOT_LOADED;
234 case ::V1_4::Status::LICENSE_PARSE_ERROR:
235 return ERROR_DRM_LICENSE_PARSE;
236 case ::V1_4::Status::LICENSE_POLICY_ERROR:
237 return ERROR_DRM_LICENSE_POLICY;
238 case ::V1_4::Status::LICENSE_RELEASE_ERROR:
239 return ERROR_DRM_LICENSE_RELEASE;
240 case ::V1_4::Status::LICENSE_REQUEST_REJECTED:
241 return ERROR_DRM_LICENSE_REQUEST_REJECTED;
242 case ::V1_4::Status::LICENSE_RESTORE_ERROR:
243 return ERROR_DRM_LICENSE_RESTORE;
244 case ::V1_4::Status::LICENSE_STATE_ERROR:
245 return ERROR_DRM_LICENSE_STATE;
246 case ::V1_4::Status::MALFORMED_CERTIFICATE:
247 return ERROR_DRM_CERTIFICATE_MALFORMED;
248 case ::V1_4::Status::MEDIA_FRAMEWORK_ERROR:
249 return ERROR_DRM_MEDIA_FRAMEWORK;
250 case ::V1_4::Status::MISSING_CERTIFICATE:
251 return ERROR_DRM_CERTIFICATE_MISSING;
252 case ::V1_4::Status::PROVISIONING_CERTIFICATE_ERROR:
253 return ERROR_DRM_PROVISIONING_CERTIFICATE;
254 case ::V1_4::Status::PROVISIONING_CONFIGURATION_ERROR:
255 return ERROR_DRM_PROVISIONING_CONFIG;
256 case ::V1_4::Status::PROVISIONING_PARSE_ERROR:
257 return ERROR_DRM_PROVISIONING_PARSE;
Robert Shihe6c85332021-03-03 02:23:15 -0800258 case ::V1_4::Status::PROVISIONING_REQUEST_REJECTED:
259 return ERROR_DRM_PROVISIONING_REQUEST_REJECTED;
Robert Shih5944a0b2021-02-10 04:26:33 -0800260 case ::V1_4::Status::RETRYABLE_PROVISIONING_ERROR:
261 return ERROR_DRM_PROVISIONING_RETRY;
262 case ::V1_4::Status::SECURE_STOP_RELEASE_ERROR:
263 return ERROR_DRM_SECURE_STOP_RELEASE;
264 case ::V1_4::Status::STORAGE_READ_FAILURE:
265 return ERROR_DRM_STORAGE_READ;
266 case ::V1_4::Status::STORAGE_WRITE_FAILURE:
267 return ERROR_DRM_STORAGE_WRITE;
268
269 case ::V1_4::Status::ERROR_DRM_UNKNOWN:
270 default:
271 return ERROR_DRM_UNKNOWN;
272 }
273 return ERROR_DRM_UNKNOWN;
274}
275
Robert Shih8635cb12021-02-26 07:57:55 -0800276namespace {
277char logPriorityToChar(::V1_4::LogPriority priority) {
278 char p = 'U';
279 switch (priority) {
280 case ::V1_4::LogPriority::VERBOSE: p = 'V'; break;
281 case ::V1_4::LogPriority::DEBUG: p = 'D'; break;
282 case ::V1_4::LogPriority::INFO: p = 'I'; break;
283 case ::V1_4::LogPriority::WARN: p = 'W'; break;
284 case ::V1_4::LogPriority::ERROR: p = 'E'; break;
285 case ::V1_4::LogPriority::FATAL: p = 'F'; break;
286 default: p = 'U'; break;
287 }
288 return p;
289}
290} // namespace
291
292std::string GetExceptionMessage(status_t err, const char *msg,
293 const Vector<::V1_4::LogMessage> &logs) {
294 String8 msg8;
295 if (msg) {
296 msg8 += msg;
297 msg8 += ": ";
298 }
299 auto errStr = StrCryptoError(err);
300 msg8 += errStr.c_str();
301
302 for (auto log : logs) {
303 time_t seconds = log.timeMs / 1000;
304 int ms = log.timeMs % 1000;
305 char buf[64] = {0};
306 std::string timeStr = "00-00 00:00:00";
307 if (strftime(buf, sizeof buf, "%m-%d %H:%M:%S", std::localtime(&seconds))) {
308 timeStr = buf;
309 }
310
311 char p = logPriorityToChar(log.priority);
312 msg8 += String8::format("\n%s.%03d %c %s", timeStr.c_str(), ms, p, log.message.c_str());
313 }
314
315 return msg8.c_str();
316}
317
318void LogBuffer::addLog(const ::V1_4::LogMessage &log) {
319 std::unique_lock<std::mutex> lock(mMutex);
320 mBuffer.push_back(log);
321 while (mBuffer.size() > MAX_CAPACITY) {
322 mBuffer.pop_front();
323 }
324}
325
326Vector<::V1_4::LogMessage> LogBuffer::getLogs() {
327 std::unique_lock<std::mutex> lock(mMutex);
328 Vector<::V1_4::LogMessage> logs;
329 for (auto log : mBuffer) {
330 logs.push_back(log);
331 }
332 return logs;
333}
334
335LogBuffer gLogBuf;
Robert Shih28c2ed32019-10-27 22:55:12 -0700336} // namespace DrmUtils
337} // namespace android