blob: c362aa681eaadd712722a41dcbeae3c1b0dae25b [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>
30#include <ctime>
Robert Shih10fe9432019-11-09 08:26:49 -080031#include <vector>
32
Robert Shih9afca952021-02-12 01:36:06 -080033
Robert Shih10fe9432019-11-09 08:26:49 -080034using namespace ::android::hardware::drm;
Robert Shih9afca952021-02-12 01:36:06 -080035using ::android::hardware::hidl_vec;
36using ::android::hardware::Return;
Robert Shih28c2ed32019-10-27 22:55:12 -070037
38namespace android {
39
40struct ICrypto;
41struct IDrm;
42
43namespace DrmUtils {
44
45bool UseDrmService();
46
47sp<IDrm> MakeDrm(status_t *pstatus = nullptr);
48
49sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
50
Robert Shihd3f9ba72019-11-20 17:25:26 -080051template<typename BA, typename PARCEL>
52void WriteByteArray(PARCEL &obj, const BA &vec) {
Robert Shih61e1c762019-10-31 21:26:58 -070053 obj.writeInt32(vec.size());
54 if (vec.size()) {
55 obj.write(vec.data(), vec.size());
56 }
57}
58
Robert Shihd3f9ba72019-11-20 17:25:26 -080059template<typename ET, typename BA, typename PARCEL>
Robert Shih61e1c762019-10-31 21:26:58 -070060void WriteEventToParcel(
Robert Shihd3f9ba72019-11-20 17:25:26 -080061 PARCEL &obj,
Robert Shih61e1c762019-10-31 21:26:58 -070062 ET eventType,
63 const BA &sessionId,
64 const BA &data) {
65 WriteByteArray(obj, sessionId);
66 WriteByteArray(obj, data);
67 obj.writeInt32(eventType);
68}
69
Robert Shihd3f9ba72019-11-20 17:25:26 -080070template<typename BA, typename PARCEL>
Robert Shih61e1c762019-10-31 21:26:58 -070071void WriteExpirationUpdateToParcel(
Robert Shihd3f9ba72019-11-20 17:25:26 -080072 PARCEL &obj,
Robert Shih61e1c762019-10-31 21:26:58 -070073 const BA &sessionId,
74 int64_t expiryTimeInMS) {
75 WriteByteArray(obj, sessionId);
76 obj.writeInt64(expiryTimeInMS);
77}
78
Robert Shihd3f9ba72019-11-20 17:25:26 -080079template<typename BA, typename KSL, typename PARCEL>
Robert Shih61e1c762019-10-31 21:26:58 -070080void WriteKeysChange(
Robert Shihd3f9ba72019-11-20 17:25:26 -080081 PARCEL &obj,
Robert Shih61e1c762019-10-31 21:26:58 -070082 const BA &sessionId,
83 const KSL &keyStatusList,
84 bool hasNewUsableKey) {
85 WriteByteArray(obj, sessionId);
86 obj.writeInt32(keyStatusList.size());
87 for (const auto &keyStatus : keyStatusList) {
88 WriteByteArray(obj, keyStatus.keyId);
89 obj.writeInt32(keyStatus.type);
90 }
91 obj.writeInt32(hasNewUsableKey);
92}
93
Robert Shihc0d1d0e2019-11-24 13:21:04 -080094std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16] = nullptr);
Robert Shih5ff3ad62019-11-09 08:26:49 -080095
96std::vector<sp<::V1_0::IDrmPlugin>> MakeDrmPlugins(const uint8_t uuid[16],
97 const char *appPackageName);
98
Robert Shih10fe9432019-11-09 08:26:49 -080099std::vector<sp<::V1_0::ICryptoFactory>> MakeCryptoFactories(const uint8_t uuid[16]);
100
101std::vector<sp<::V1_0::ICryptoPlugin>> MakeCryptoPlugins(const uint8_t uuid[16],
102 const void *initData, size_t initDataSize);
103
Robert Shih5944a0b2021-02-10 04:26:33 -0800104status_t toStatusT_1_4(::V1_4::Status status);
105
106template<typename S>
107inline status_t toStatusT(S status) {
108 auto err = static_cast<::V1_4::Status>(status);
109 return toStatusT_1_4(err);
110}
111
112template<typename T>
113inline status_t toStatusT(const android::hardware::Return<T> &status) {
114 auto t = static_cast<T>(status);
115 auto err = static_cast<::V1_4::Status>(t);
116 return toStatusT_1_4(err);
117}
118
Robert Shih9afca952021-02-12 01:36:06 -0800119template<typename T, typename U>
120status_t GetLogMessages(const sp<U> &obj, Vector<::V1_4::LogMessage> &logs) {
121 sp<T> plugin = T::castFrom(obj);
122 if (plugin == NULL) {
123 return ERROR_UNSUPPORTED;
124 }
125
126 ::V1_4::Status err{};
127 ::V1_4::IDrmPlugin::getLogMessages_cb cb = [&](
128 ::V1_4::Status status,
129 hidl_vec<::V1_4::LogMessage> hLogs) {
Robert Shihfaae26a2021-02-20 00:01:19 -0800130 if (::V1_4::Status::OK != status) {
Robert Shih9afca952021-02-12 01:36:06 -0800131 err = status;
132 return;
133 }
134 logs.appendArray(hLogs.data(), hLogs.size());
135 };
136
137 Return<void> hResult = plugin->getLogMessages(cb);
138 if (!hResult.isOk()) {
139 return DEAD_OBJECT;
140 }
141 return toStatusT(err);
142}
143
Robert Shih0beba052021-02-14 00:47:00 -0800144namespace {
145static inline char logPriorityToChar(::V1_4::LogPriority priority) {
146 char p = 'U';
147 switch (priority) {
148 case ::V1_4::LogPriority::VERBOSE: p = 'V'; break;
149 case ::V1_4::LogPriority::DEBUG: p = 'D'; break;
150 case ::V1_4::LogPriority::INFO: p = 'I'; break;
151 case ::V1_4::LogPriority::WARN: p = 'W'; break;
152 case ::V1_4::LogPriority::ERROR: p = 'E'; break;
153 case ::V1_4::LogPriority::FATAL: p = 'F'; break;
154 default: p = 'U'; break;
155 }
156 return p;
157}
158}
159
160template<typename T>
161std::string GetExceptionMessage(status_t err, const char *msg, const sp<T> &iface) {
162 String8 msg8;
163 if (msg) {
164 msg8 += msg;
165 msg8 += ": ";
166 }
167 auto errStr = StrCryptoError(err);
168 msg8 += errStr.c_str();
169
170 Vector<::V1_4::LogMessage> logs;
171 if (iface->getLogMessages(logs) != NO_ERROR) {
172 return msg8.c_str();
173 }
174
175 for (auto log: logs) {
176 time_t seconds = log.timeMs / 1000;
177 int ms = log.timeMs % 1000;
178 char buf[64] = {0};
179 std::string timeStr = "00-00 00:00:00";
180 if (strftime(buf, sizeof buf, "%m-%d %H:%M:%S", std::localtime(&seconds))) {
181 timeStr = buf;
182 }
183
184 char p = logPriorityToChar(log.priority);
185 msg8 += String8::format("\n%s.%03d %c %s",
186 timeStr.c_str(), ms, p, log.message.c_str());
187 }
188
189 return msg8.c_str();
190}
191
Robert Shih28c2ed32019-10-27 22:55:12 -0700192} // namespace DrmUtils
Robert Shih28c2ed32019-10-27 22:55:12 -0700193} // namespace android
Robert Shih28c2ed32019-10-27 22:55:12 -0700194#endif // ANDROID_DRMUTILS_H