blob: 9b125af56a6e181d5428726e5bdb3ab658154671 [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 Shihbd790122021-03-01 20:45:31 -0800111 LOG2BE(uuid, "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 Shihbd790122021-03-01 20:45:31 -0800126 LOG2BE(uuid, "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;
258 case ::V1_4::Status::RETRYABLE_PROVISIONING_ERROR:
259 return ERROR_DRM_PROVISIONING_RETRY;
260 case ::V1_4::Status::SECURE_STOP_RELEASE_ERROR:
261 return ERROR_DRM_SECURE_STOP_RELEASE;
262 case ::V1_4::Status::STORAGE_READ_FAILURE:
263 return ERROR_DRM_STORAGE_READ;
264 case ::V1_4::Status::STORAGE_WRITE_FAILURE:
265 return ERROR_DRM_STORAGE_WRITE;
266
267 case ::V1_4::Status::ERROR_DRM_UNKNOWN:
268 default:
269 return ERROR_DRM_UNKNOWN;
270 }
271 return ERROR_DRM_UNKNOWN;
272}
273
Robert Shih8635cb12021-02-26 07:57:55 -0800274namespace {
275char logPriorityToChar(::V1_4::LogPriority priority) {
276 char p = 'U';
277 switch (priority) {
278 case ::V1_4::LogPriority::VERBOSE: p = 'V'; break;
279 case ::V1_4::LogPriority::DEBUG: p = 'D'; break;
280 case ::V1_4::LogPriority::INFO: p = 'I'; break;
281 case ::V1_4::LogPriority::WARN: p = 'W'; break;
282 case ::V1_4::LogPriority::ERROR: p = 'E'; break;
283 case ::V1_4::LogPriority::FATAL: p = 'F'; break;
284 default: p = 'U'; break;
285 }
286 return p;
287}
288} // namespace
289
290std::string GetExceptionMessage(status_t err, const char *msg,
291 const Vector<::V1_4::LogMessage> &logs) {
292 String8 msg8;
293 if (msg) {
294 msg8 += msg;
295 msg8 += ": ";
296 }
297 auto errStr = StrCryptoError(err);
298 msg8 += errStr.c_str();
299
300 for (auto log : logs) {
301 time_t seconds = log.timeMs / 1000;
302 int ms = log.timeMs % 1000;
303 char buf[64] = {0};
304 std::string timeStr = "00-00 00:00:00";
305 if (strftime(buf, sizeof buf, "%m-%d %H:%M:%S", std::localtime(&seconds))) {
306 timeStr = buf;
307 }
308
309 char p = logPriorityToChar(log.priority);
310 msg8 += String8::format("\n%s.%03d %c %s", timeStr.c_str(), ms, p, log.message.c_str());
311 }
312
313 return msg8.c_str();
314}
315
316void LogBuffer::addLog(const ::V1_4::LogMessage &log) {
317 std::unique_lock<std::mutex> lock(mMutex);
318 mBuffer.push_back(log);
319 while (mBuffer.size() > MAX_CAPACITY) {
320 mBuffer.pop_front();
321 }
322}
323
324Vector<::V1_4::LogMessage> LogBuffer::getLogs() {
325 std::unique_lock<std::mutex> lock(mMutex);
326 Vector<::V1_4::LogMessage> logs;
327 for (auto log : mBuffer) {
328 logs.push_back(log);
329 }
330 return logs;
331}
332
333LogBuffer gLogBuf;
Robert Shih28c2ed32019-10-27 22:55:12 -0700334} // namespace DrmUtils
335} // namespace android