blob: bcdfadf257953071964c164ec80d65edda12b3d7 [file] [log] [blame]
Sohail Nagaraj17d54db2022-12-29 10:00:59 +05301/*
2 * Copyright (C) 2022 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 "DrmMetricsLogger"
19
20#include <media/MediaMetrics.h>
21#include <mediadrm/DrmHal.h>
22#include <mediadrm/DrmMetricsLogger.h>
23#include <mediadrm/DrmUtils.h>
24
25namespace android {
26
27namespace {
28
29std::vector<uint8_t> toStdVec(Vector<uint8_t> const& sessionId) {
30 auto sessionKey = sessionId.array();
31 std::vector<uint8_t> vec(sessionKey, sessionKey + sessionId.size());
32 return vec;
33}
34} // namespace
35
36DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
37 : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonceMsb(0), mObjNonceLsb(0), mFrontend(frontend) {}
38
39DrmMetricsLogger::~DrmMetricsLogger() {}
40
41DrmStatus DrmMetricsLogger::initCheck() const {
42 DrmStatus status = mImpl->initCheck();
43 if (status != OK) {
44 reportMediaDrmErrored(status, __func__);
45 }
46 return status;
47}
48
49DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
50 DrmPlugin::SecurityLevel securityLevel,
51 bool* result) {
52 DrmStatus status = mImpl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
53 if (status != OK) {
54 reportMediaDrmErrored(status, __func__);
55 }
56 return status;
57}
58
59DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
60 std::memcpy(mUuid, uuid, sizeof(mUuid));
61 if (checkGetRandom(&mObjNonceMsb, __func__) == OK &&
62 checkGetRandom(&mObjNonceLsb, __func__) == OK) {
63 DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
64 if (status == OK) {
65 reportMediaDrmCreated();
66 } else {
67 reportMediaDrmErrored(status, __func__);
68 }
69 return status;
70 }
71 return ERROR_DRM_RESOURCE_BUSY;
72}
73
74DrmStatus DrmMetricsLogger::destroyPlugin() {
75 DrmStatus status = mImpl->destroyPlugin();
76 if (status != OK) {
77 reportMediaDrmErrored(status, __func__);
78 }
79 return status;
80}
81
82DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
83 Vector<uint8_t>& sessionId) {
84 SessionContext ctx{};
85 if (checkGetRandom(&ctx.mNonceMsb, __func__) == OK &&
86 checkGetRandom(&ctx.mNonceLsb, __func__) == OK) {
87 DrmStatus status = mImpl->openSession(securityLevel, sessionId);
88 if (status == OK) {
89 std::vector<uint8_t> sessionKey = toStdVec(sessionId);
90 ctx.mTargetSecurityLevel = securityLevel;
91 if (getSecurityLevel(sessionId, &ctx.mActualSecurityLevel) != OK) {
92 ctx.mActualSecurityLevel = DrmPlugin::kSecurityLevelUnknown;
93 }
94 {
95 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
96 mSessionMap.insert({sessionKey, ctx});
97 }
98 reportMediaDrmSessionOpened(sessionKey);
99 } else {
100 reportMediaDrmErrored(status, __func__);
101 }
102 return status;
103 }
104 return ERROR_DRM_RESOURCE_BUSY;
105}
106
107DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
108 std::vector<uint8_t> sid = toStdVec(sessionId);
109 {
110 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
111 mSessionMap.erase(sid);
112 }
113 DrmStatus status = mImpl->closeSession(sessionId);
114 if (status != OK) {
115 reportMediaDrmErrored(status, __func__, sid);
116 }
117 return status;
118}
119
120DrmStatus DrmMetricsLogger::getKeyRequest(Vector<uint8_t> const& sessionId,
121 Vector<uint8_t> const& initData, String8 const& mimeType,
122 DrmPlugin::KeyType keyType,
123 KeyedVector<String8, String8> const& optionalParameters,
124 Vector<uint8_t>& request, String8& defaultUrl,
125 DrmPlugin::KeyRequestType* keyRequestType) {
126 DrmStatus status =
127 mImpl->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters,
128 request, defaultUrl, keyRequestType);
129 if (status != OK) {
130 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
131 }
132 return status;
133}
134
135DrmStatus DrmMetricsLogger::provideKeyResponse(Vector<uint8_t> const& sessionId,
136 Vector<uint8_t> const& response,
137 Vector<uint8_t>& keySetId) {
138 DrmStatus status = mImpl->provideKeyResponse(sessionId, response, keySetId);
139 if (status != OK) {
140 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
141 }
142 return status;
143}
144
145DrmStatus DrmMetricsLogger::removeKeys(Vector<uint8_t> const& keySetId) {
146 DrmStatus status = mImpl->removeKeys(keySetId);
147 if (status != OK) {
148 reportMediaDrmErrored(status, __func__);
149 }
150 return status;
151}
152
153DrmStatus DrmMetricsLogger::restoreKeys(Vector<uint8_t> const& sessionId,
154 Vector<uint8_t> const& keySetId) {
155 DrmStatus status = mImpl->restoreKeys(sessionId, keySetId);
156 if (status != OK) {
157 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
158 }
159 return status;
160}
161
162DrmStatus DrmMetricsLogger::queryKeyStatus(Vector<uint8_t> const& sessionId,
163 KeyedVector<String8, String8>& infoMap) const {
164 DrmStatus status = mImpl->queryKeyStatus(sessionId, infoMap);
165 if (status != OK) {
166 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
167 }
168 return status;
169}
170
171DrmStatus DrmMetricsLogger::getProvisionRequest(String8 const& certType,
172 String8 const& certAuthority,
173 Vector<uint8_t>& request, String8& defaultUrl) {
174 DrmStatus status = mImpl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
175 if (status != OK) {
176 reportMediaDrmErrored(status, __func__);
177 }
178 return status;
179}
180
181DrmStatus DrmMetricsLogger::provideProvisionResponse(Vector<uint8_t> const& response,
182 Vector<uint8_t>& certificate,
183 Vector<uint8_t>& wrappedKey) {
184 DrmStatus status = mImpl->provideProvisionResponse(response, certificate, wrappedKey);
185 if (status != OK) {
186 reportMediaDrmErrored(status, __func__);
187 }
188 return status;
189}
190
191DrmStatus DrmMetricsLogger::getSecureStops(List<Vector<uint8_t>>& secureStops) {
192 DrmStatus status = mImpl->getSecureStops(secureStops);
193 if (status != OK) {
194 reportMediaDrmErrored(status, __func__);
195 }
196 return status;
197}
198
199DrmStatus DrmMetricsLogger::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
200 DrmStatus status = mImpl->getSecureStopIds(secureStopIds);
201 if (status != OK) {
202 reportMediaDrmErrored(status, __func__);
203 }
204 return status;
205}
206
207DrmStatus DrmMetricsLogger::getSecureStop(Vector<uint8_t> const& ssid,
208 Vector<uint8_t>& secureStop) {
209 DrmStatus status = mImpl->getSecureStop(ssid, secureStop);
210 if (status != OK) {
211 reportMediaDrmErrored(status, __func__);
212 }
213 return status;
214}
215
216DrmStatus DrmMetricsLogger::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
217 DrmStatus status = mImpl->releaseSecureStops(ssRelease);
218 if (status != OK) {
219 reportMediaDrmErrored(status, __func__);
220 }
221 return status;
222}
223
224DrmStatus DrmMetricsLogger::removeSecureStop(Vector<uint8_t> const& ssid) {
225 DrmStatus status = mImpl->removeSecureStop(ssid);
226 if (status != OK) {
227 reportMediaDrmErrored(status, __func__);
228 }
229 return status;
230}
231
232DrmStatus DrmMetricsLogger::removeAllSecureStops() {
233 DrmStatus status = mImpl->removeAllSecureStops();
234 if (status != OK) {
235 reportMediaDrmErrored(status, __func__);
236 }
237 return status;
238}
239
240DrmStatus DrmMetricsLogger::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
241 DrmPlugin::HdcpLevel* maxLevel) const {
242 DrmStatus status = mImpl->getHdcpLevels(connectedLevel, maxLevel);
243 if (status != OK) {
244 reportMediaDrmErrored(status, __func__);
245 }
246 return status;
247}
248
249DrmStatus DrmMetricsLogger::getNumberOfSessions(uint32_t* currentSessions,
250 uint32_t* maxSessions) const {
251 DrmStatus status = mImpl->getNumberOfSessions(currentSessions, maxSessions);
252 if (status != OK) {
253 reportMediaDrmErrored(status, __func__);
254 }
255 return status;
256}
257
258DrmStatus DrmMetricsLogger::getSecurityLevel(Vector<uint8_t> const& sessionId,
259 DrmPlugin::SecurityLevel* level) const {
260 DrmStatus status = mImpl->getSecurityLevel(sessionId, level);
261 if (status != OK) {
262 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
263 }
264 return status;
265}
266
267DrmStatus DrmMetricsLogger::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
268 DrmStatus status = mImpl->getOfflineLicenseKeySetIds(keySetIds);
269 if (status != OK) {
270 reportMediaDrmErrored(status, __func__);
271 }
272 return status;
273}
274
275DrmStatus DrmMetricsLogger::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
276 DrmStatus status = mImpl->removeOfflineLicense(keySetId);
277 if (status != OK) {
278 reportMediaDrmErrored(status, __func__);
279 }
280 return status;
281}
282
283DrmStatus DrmMetricsLogger::getOfflineLicenseState(
284 Vector<uint8_t> const& keySetId, DrmPlugin::OfflineLicenseState* licenseState) const {
285 DrmStatus status = mImpl->getOfflineLicenseState(keySetId, licenseState);
286 if (status != OK) {
287 reportMediaDrmErrored(status, __func__);
288 }
289 return status;
290}
291
292DrmStatus DrmMetricsLogger::getPropertyString(String8 const& name, String8& value) const {
293 DrmStatus status = mImpl->getPropertyString(name, value);
294 if (status != OK) {
295 reportMediaDrmErrored(status, __func__);
296 }
297 return status;
298}
299
300DrmStatus DrmMetricsLogger::getPropertyByteArray(String8 const& name,
301 Vector<uint8_t>& value) const {
302 DrmStatus status = mImpl->getPropertyByteArray(name, value);
303 if (status != OK) {
304 reportMediaDrmErrored(status, __func__);
305 }
306 return status;
307}
308
309DrmStatus DrmMetricsLogger::setPropertyString(String8 const& name, String8 const& value) const {
310 DrmStatus status = mImpl->setPropertyString(name, value);
311 if (status != OK) {
312 reportMediaDrmErrored(status, __func__);
313 }
314 return status;
315}
316
317DrmStatus DrmMetricsLogger::setPropertyByteArray(String8 const& name,
318 Vector<uint8_t> const& value) const {
319 DrmStatus status = mImpl->setPropertyByteArray(name, value);
320 if (status != OK) {
321 reportMediaDrmErrored(status, __func__);
322 }
323 return status;
324}
325
326DrmStatus DrmMetricsLogger::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
327 DrmStatus status = mImpl->getMetrics(consumer);
328 if (status != OK) {
329 reportMediaDrmErrored(status, __func__);
330 }
331 return status;
332}
333
334DrmStatus DrmMetricsLogger::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
335 String8 const& algorithm) {
336 DrmStatus status = mImpl->setCipherAlgorithm(sessionId, algorithm);
337 if (status != OK) {
338 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
339 }
340 return status;
341}
342
343DrmStatus DrmMetricsLogger::setMacAlgorithm(Vector<uint8_t> const& sessionId,
344 String8 const& algorithm) {
345 DrmStatus status = mImpl->setMacAlgorithm(sessionId, algorithm);
346 if (status != OK) {
347 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
348 }
349 return status;
350}
351
352DrmStatus DrmMetricsLogger::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
353 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
354 Vector<uint8_t>& output) {
355 DrmStatus status = mImpl->encrypt(sessionId, keyId, input, iv, output);
356 if (status != OK) {
357 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
358 }
359 return status;
360}
361
362DrmStatus DrmMetricsLogger::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
363 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
364 Vector<uint8_t>& output) {
365 DrmStatus status = mImpl->decrypt(sessionId, keyId, input, iv, output);
366 if (status != OK) {
367 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
368 }
369 return status;
370}
371
372DrmStatus DrmMetricsLogger::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
373 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
374 DrmStatus status = mImpl->sign(sessionId, keyId, message, signature);
375 if (status != OK) {
376 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
377 }
378 return status;
379}
380
381DrmStatus DrmMetricsLogger::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
382 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
383 bool& match) {
384 DrmStatus status = mImpl->verify(sessionId, keyId, message, signature, match);
385 if (status != OK) {
386 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
387 }
388 return status;
389}
390
391DrmStatus DrmMetricsLogger::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
392 Vector<uint8_t> const& message,
393 Vector<uint8_t> const& wrappedKey, Vector<uint8_t>& signature) {
394 DrmStatus status = mImpl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
395 if (status != OK) {
396 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
397 }
398 return status;
399}
400
401DrmStatus DrmMetricsLogger::setListener(const sp<IDrmClient>& listener) {
402 DrmStatus status = mImpl->setListener(listener);
403 if (status != OK) {
404 reportMediaDrmErrored(status, __func__);
405 }
406 return status;
407}
408
409DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime, bool* required) const {
410 DrmStatus status = mImpl->requiresSecureDecoder(mime, required);
411 if (status != OK) {
412 reportMediaDrmErrored(status, __func__);
413 }
414 return status;
415}
416
417DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
418 DrmPlugin::SecurityLevel securityLevel,
419 bool* required) const {
420 DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
421 if (status != OK) {
422 reportMediaDrmErrored(status, __func__);
423 }
424 return status;
425}
426
427DrmStatus DrmMetricsLogger::setPlaybackId(Vector<uint8_t> const& sessionId,
428 const char* playbackId) {
429 DrmStatus status = mImpl->setPlaybackId(sessionId, playbackId);
430 if (status != OK) {
431 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
432 }
433 return status;
434}
435
436DrmStatus DrmMetricsLogger::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
437 DrmStatus status = mImpl->getLogMessages(logs);
438 if (status != OK) {
439 reportMediaDrmErrored(status, __func__);
440 }
441 return status;
442}
443
444DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
445 DrmStatus status = mImpl->getSupportedSchemes(schemes);
446 if (status != OK) {
447 reportMediaDrmErrored(status, __func__);
448 }
449 return status;
450}
451
452void DrmMetricsLogger::reportMediaDrmCreated() const {
453 mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
454 mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
455 mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
456 mediametrics_setInt32(handle, "frontend", mFrontend);
457 mediametrics_selfRecord(handle);
458 mediametrics_delete(handle);
459}
460
461void DrmMetricsLogger::reportMediaDrmSessionOpened(std::vector<uint8_t> sessionId) const {
462 mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
463 mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
464 mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
465 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
466 auto it = mSessionMap.find(sessionId);
467 if (it != mSessionMap.end()) {
468 mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
469 mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
470 mediametrics_setInt64(handle, "target_seucrity_level", it->second.mTargetSecurityLevel);
471 mediametrics_setInt64(handle, "actual_seucrity_level", it->second.mActualSecurityLevel);
472 }
473 mediametrics_setInt32(handle, "frontend", mFrontend);
474 mediametrics_selfRecord(handle);
475 mediametrics_delete(handle);
476}
477
478void DrmMetricsLogger::reportMediaDrmErrored(DrmStatus error_code, const char* api,
479 std::vector<uint8_t> sessionId) const {
480 mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
481 mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
482 mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
483 if (!sessionId.empty()) {
484 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
485 auto it = mSessionMap.find(sessionId);
486 if (it != mSessionMap.end()) {
487 mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
488 mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
489 }
490 }
491 mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
492 mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
493 mediametrics_setInt32(handle, "error_code", error_code);
494 mediametrics_setCString(handle, "api", api);
495 mediametrics_setInt32(handle, "frontend", mFrontend);
496 mediametrics_selfRecord(handle);
497 mediametrics_delete(handle);
498}
499
500DrmStatus DrmMetricsLogger::checkGetRandom(int64_t* nonce, const char* api) {
501 ssize_t bytes = getrandom(nonce, sizeof(int64_t), GRND_NONBLOCK);
502 if (bytes < sizeof(int64_t)) {
503 ALOGE("getrandom failed: %d", errno);
504 reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
505 return ERROR_DRM_RESOURCE_BUSY;
506 }
507 return OK;
508}
509
510} // namespace android