blob: 7fe3501d684674ceb3692bf044df48ddb57005b2 [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#ifndef ANDROID_DRMUTILS_H
18#define ANDROID_DRMUTILS_H
19
Robert Shih10fe9432019-11-09 08:26:49 -080020#include <android/hardware/drm/1.0/ICryptoFactory.h>
Robert Shih5ff3ad62019-11-09 08:26:49 -080021#include <android/hardware/drm/1.0/IDrmFactory.h>
Robert Shih9afca952021-02-12 01:36:06 -080022#include <android/hardware/drm/1.4/IDrmPlugin.h>
Robert Shih5944a0b2021-02-10 04:26:33 -080023#include <android/hardware/drm/1.4/types.h>
Robert Shih9afca952021-02-12 01:36:06 -080024#include <media/stagefright/MediaErrors.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070025#include <utils/Errors.h> // for status_t
Robert Shih0beba052021-02-14 00:47:00 -080026#include <utils/Log.h>
27#include <utils/String8.h>
Robert Shih28c2ed32019-10-27 22:55:12 -070028#include <utils/StrongPointer.h>
Robert Shih0beba052021-02-14 00:47:00 -080029#include <utils/Vector.h>
Robert Shih8635cb12021-02-26 07:57:55 -080030#include <algorithm>
31#include <chrono>
32#include <cstddef>
33#include <cstdint>
Robert Shih0beba052021-02-14 00:47:00 -080034#include <ctime>
Robert Shih8635cb12021-02-26 07:57:55 -080035#include <deque>
36#include <iterator>
37#include <mutex>
Robert Shih10fe9432019-11-09 08:26:49 -080038#include <vector>
39
Robert Shih9afca952021-02-12 01:36:06 -080040
Robert Shih10fe9432019-11-09 08:26:49 -080041using namespace ::android::hardware::drm;
Robert Shih9afca952021-02-12 01:36:06 -080042using ::android::hardware::hidl_vec;
43using ::android::hardware::Return;
Robert Shih28c2ed32019-10-27 22:55:12 -070044
45namespace android {
46
47struct ICrypto;
48struct IDrm;
49
50namespace DrmUtils {
51
Robert Shih8635cb12021-02-26 07:57:55 -080052// Log APIs
53class LogBuffer {
54 public:
55 static const int MAX_CAPACITY = 100;
56 void addLog(const ::V1_4::LogMessage &log);
57 Vector<::V1_4::LogMessage> getLogs();
58
59 private:
60 std::deque<::V1_4::LogMessage> mBuffer;
61 std::mutex mMutex;
62};
63
64extern LogBuffer gLogBuf;
65
66static inline int formatBuffer(char *buf, size_t size, const char *msg) {
67 return snprintf(buf, size, "%s", msg);
68}
69
70template <typename First, typename... Args>
71static inline int formatBuffer(char *buf, size_t size, const char *fmt, First first, Args... args) {
72 return snprintf(buf, size, fmt, first, args...);
73}
74
75template <typename... Args>
76void LogToBuffer(android_LogPriority level, const char *fmt, Args... args) {
77 const int LOG_BUF_SIZE = 256;
78 char buf[LOG_BUF_SIZE];
79 int len = formatBuffer(buf, LOG_BUF_SIZE, fmt, args...);
80 if (len <= 0) {
81 return;
82 }
83 __android_log_write(level, LOG_TAG, buf);
84 if (level >= ANDROID_LOG_INFO) {
85 int64_t epochTimeMs =
86 std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
87 gLogBuf.addLog({epochTimeMs, static_cast<::V1_4::LogPriority>(level), buf});
88 }
89}
90
91#ifndef LOG2BE
92#define LOG2BE(...) LogToBuffer(ANDROID_LOG_ERROR, __VA_ARGS__)
93#define LOG2BW(...) LogToBuffer(ANDROID_LOG_WARN, __VA_ARGS__)
94#define LOG2BI(...) LogToBuffer(ANDROID_LOG_INFO, __VA_ARGS__)
95#define LOG2BD(...) LogToBuffer(ANDROID_LOG_DEBUG, __VA_ARGS__)
96#define LOG2BV(...) LogToBuffer(ANDROID_LOG_VERBOSE, __VA_ARGS__)
97#endif
98
Robert Shih28c2ed32019-10-27 22:55:12 -070099bool UseDrmService();
100
101sp<IDrm> MakeDrm(status_t *pstatus = nullptr);
102
103sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
104
Robert Shihd3f9ba72019-11-20 17:25:26 -0800105template<typename BA, typename PARCEL>
106void WriteByteArray(PARCEL &obj, const BA &vec) {
Robert Shih61e1c762019-10-31 21:26:58 -0700107 obj.writeInt32(vec.size());
108 if (vec.size()) {
109 obj.write(vec.data(), vec.size());
110 }
111}
112
Robert Shihd3f9ba72019-11-20 17:25:26 -0800113template<typename ET, typename BA, typename PARCEL>
Robert Shih61e1c762019-10-31 21:26:58 -0700114void WriteEventToParcel(
Robert Shihd3f9ba72019-11-20 17:25:26 -0800115 PARCEL &obj,
Robert Shih61e1c762019-10-31 21:26:58 -0700116 ET eventType,
117 const BA &sessionId,
118 const BA &data) {
119 WriteByteArray(obj, sessionId);
120 WriteByteArray(obj, data);
121 obj.writeInt32(eventType);
122}
123
Robert Shihd3f9ba72019-11-20 17:25:26 -0800124template<typename BA, typename PARCEL>
Robert Shih61e1c762019-10-31 21:26:58 -0700125void WriteExpirationUpdateToParcel(
Robert Shihd3f9ba72019-11-20 17:25:26 -0800126 PARCEL &obj,
Robert Shih61e1c762019-10-31 21:26:58 -0700127 const BA &sessionId,
128 int64_t expiryTimeInMS) {
129 WriteByteArray(obj, sessionId);
130 obj.writeInt64(expiryTimeInMS);
131}
132
Robert Shihd3f9ba72019-11-20 17:25:26 -0800133template<typename BA, typename KSL, typename PARCEL>
Robert Shih61e1c762019-10-31 21:26:58 -0700134void WriteKeysChange(
Robert Shihd3f9ba72019-11-20 17:25:26 -0800135 PARCEL &obj,
Robert Shih61e1c762019-10-31 21:26:58 -0700136 const BA &sessionId,
137 const KSL &keyStatusList,
138 bool hasNewUsableKey) {
139 WriteByteArray(obj, sessionId);
140 obj.writeInt32(keyStatusList.size());
141 for (const auto &keyStatus : keyStatusList) {
142 WriteByteArray(obj, keyStatus.keyId);
143 obj.writeInt32(keyStatus.type);
144 }
145 obj.writeInt32(hasNewUsableKey);
146}
147
Robert Shihc0d1d0e2019-11-24 13:21:04 -0800148std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16] = nullptr);
Robert Shih5ff3ad62019-11-09 08:26:49 -0800149
150std::vector<sp<::V1_0::IDrmPlugin>> MakeDrmPlugins(const uint8_t uuid[16],
151 const char *appPackageName);
152
Robert Shih10fe9432019-11-09 08:26:49 -0800153std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]);
154
155std::vector<sp<::V1_0::ICryptoPlugin>> MakeCryptoPlugins(const uint8_t uuid[16],
156 const void *initData, size_t initDataSize);
157
Robert Shih5944a0b2021-02-10 04:26:33 -0800158status_t toStatusT_1_4(::V1_4::Status status);
159
160template<typename S>
161inline status_t toStatusT(S status) {
162 auto err = static_cast<::V1_4::Status>(status);
163 return toStatusT_1_4(err);
164}
165
166template<typename T>
167inline status_t toStatusT(const android::hardware::Return<T> &status) {
168 auto t = static_cast<T>(status);
169 auto err = static_cast<::V1_4::Status>(t);
170 return toStatusT_1_4(err);
171}
172
Robert Shih9afca952021-02-12 01:36:06 -0800173template<typename T, typename U>
174status_t GetLogMessages(const sp<U> &obj, Vector<::V1_4::LogMessage> &logs) {
175 sp<T> plugin = T::castFrom(obj);
Robert Shih8635cb12021-02-26 07:57:55 -0800176 if (obj == NULL) {
177 LOG2BW("%s obj is null", U::descriptor);
178 } else if (plugin == NULL) {
179 LOG2BW("Cannot cast %s obj to %s plugin", U::descriptor, T::descriptor);
Robert Shih9afca952021-02-12 01:36:06 -0800180 }
181
182 ::V1_4::Status err{};
Robert Shih8635cb12021-02-26 07:57:55 -0800183 std::vector<::V1_4::LogMessage> pluginLogs;
Robert Shih9afca952021-02-12 01:36:06 -0800184 ::V1_4::IDrmPlugin::getLogMessages_cb cb = [&](
185 ::V1_4::Status status,
186 hidl_vec<::V1_4::LogMessage> hLogs) {
Robert Shihfaae26a2021-02-20 00:01:19 -0800187 if (::V1_4::Status::OK != status) {
Robert Shih9afca952021-02-12 01:36:06 -0800188 err = status;
189 return;
190 }
Robert Shih8635cb12021-02-26 07:57:55 -0800191 pluginLogs.assign(hLogs.data(), hLogs.data() + hLogs.size());
Robert Shih9afca952021-02-12 01:36:06 -0800192 };
193
Robert Shih8635cb12021-02-26 07:57:55 -0800194 Return<void> hResult;
195 if (plugin != NULL) {
196 hResult = plugin->getLogMessages(cb);
Robert Shih9afca952021-02-12 01:36:06 -0800197 }
Robert Shih8635cb12021-02-26 07:57:55 -0800198 if (!hResult.isOk()) {
199 LOG2BW("%s::getLogMessages remote call failed", T::descriptor);
200 }
201
202 auto allLogs(gLogBuf.getLogs());
203 std::copy(pluginLogs.begin(), pluginLogs.end(), std::back_inserter(allLogs));
204 std::sort(allLogs.begin(), allLogs.end(),
205 [](const ::V1_4::LogMessage &a, const ::V1_4::LogMessage &b) {
206 return a.timeMs < b.timeMs;
207 });
208
209 logs.appendVector(allLogs);
210 return OK;
Robert Shih9afca952021-02-12 01:36:06 -0800211}
212
Robert Shih8635cb12021-02-26 07:57:55 -0800213std::string GetExceptionMessage(status_t err, const char *msg,
214 const Vector<::V1_4::LogMessage> &logs);
Robert Shih0beba052021-02-14 00:47:00 -0800215
216template<typename T>
217std::string GetExceptionMessage(status_t err, const char *msg, const sp<T> &iface) {
Robert Shih0beba052021-02-14 00:47:00 -0800218 Vector<::V1_4::LogMessage> logs;
Robert Shih8635cb12021-02-26 07:57:55 -0800219 iface->getLogMessages(logs);
220 return GetExceptionMessage(err, msg, logs);
Robert Shih0beba052021-02-14 00:47:00 -0800221}
222
Robert Shih28c2ed32019-10-27 22:55:12 -0700223} // namespace DrmUtils
Robert Shih28c2ed32019-10-27 22:55:12 -0700224} // namespace android
Robert Shih28c2ed32019-10-27 22:55:12 -0700225#endif // ANDROID_DRMUTILS_H