blob: bc004c8b9c99472d4a760c02025d54ffdeb53610 [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>
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +053021#include <media/stagefright/foundation/AString.h>
22#include <media/stagefright/foundation/base64.h>
Sohail Nagaraj17d54db2022-12-29 10:00:59 +053023#include <mediadrm/DrmHal.h>
24#include <mediadrm/DrmMetricsLogger.h>
25#include <mediadrm/DrmUtils.h>
26
27namespace android {
28
29namespace {
30
31std::vector<uint8_t> toStdVec(Vector<uint8_t> const& sessionId) {
32 auto sessionKey = sessionId.array();
33 std::vector<uint8_t> vec(sessionKey, sessionKey + sessionId.size());
34 return vec;
35}
Robert Shih37c16992023-01-30 19:58:35 +000036
Sohail Nagaraj17d54db2022-12-29 10:00:59 +053037} // namespace
38
39DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +053040 : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonce(), mFrontend(frontend) {}
Sohail Nagaraj17d54db2022-12-29 10:00:59 +053041
42DrmMetricsLogger::~DrmMetricsLogger() {}
43
Sohail Nagaraj76c2f9e2023-03-06 13:07:31 +053044int MediaErrorToJavaError(status_t err) {
45#define STATUS_CASE(status) \
46 case status: \
47 return J##status
48
49 switch (err) {
50 STATUS_CASE(ERROR_DRM_UNKNOWN);
51 STATUS_CASE(ERROR_DRM_NO_LICENSE);
52 STATUS_CASE(ERROR_DRM_LICENSE_EXPIRED);
53 STATUS_CASE(ERROR_DRM_RESOURCE_BUSY);
54 STATUS_CASE(ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION);
55 STATUS_CASE(ERROR_DRM_SESSION_NOT_OPENED);
56 STATUS_CASE(ERROR_DRM_CANNOT_HANDLE);
57 STATUS_CASE(ERROR_DRM_INSUFFICIENT_SECURITY);
58 STATUS_CASE(ERROR_DRM_FRAME_TOO_LARGE);
59 STATUS_CASE(ERROR_DRM_SESSION_LOST_STATE);
60 STATUS_CASE(ERROR_DRM_CERTIFICATE_MALFORMED);
61 STATUS_CASE(ERROR_DRM_CERTIFICATE_MISSING);
62 STATUS_CASE(ERROR_DRM_CRYPTO_LIBRARY);
63 STATUS_CASE(ERROR_DRM_GENERIC_OEM);
64 STATUS_CASE(ERROR_DRM_GENERIC_PLUGIN);
65 STATUS_CASE(ERROR_DRM_INIT_DATA);
66 STATUS_CASE(ERROR_DRM_KEY_NOT_LOADED);
67 STATUS_CASE(ERROR_DRM_LICENSE_PARSE);
68 STATUS_CASE(ERROR_DRM_LICENSE_POLICY);
69 STATUS_CASE(ERROR_DRM_LICENSE_RELEASE);
70 STATUS_CASE(ERROR_DRM_LICENSE_REQUEST_REJECTED);
71 STATUS_CASE(ERROR_DRM_LICENSE_RESTORE);
72 STATUS_CASE(ERROR_DRM_LICENSE_STATE);
73 STATUS_CASE(ERROR_DRM_MEDIA_FRAMEWORK);
74 STATUS_CASE(ERROR_DRM_PROVISIONING_CERTIFICATE);
75 STATUS_CASE(ERROR_DRM_PROVISIONING_CONFIG);
76 STATUS_CASE(ERROR_DRM_PROVISIONING_PARSE);
77 STATUS_CASE(ERROR_DRM_PROVISIONING_REQUEST_REJECTED);
78 STATUS_CASE(ERROR_DRM_PROVISIONING_RETRY);
79 STATUS_CASE(ERROR_DRM_RESOURCE_CONTENTION);
80 STATUS_CASE(ERROR_DRM_SECURE_STOP_RELEASE);
81 STATUS_CASE(ERROR_DRM_STORAGE_READ);
82 STATUS_CASE(ERROR_DRM_STORAGE_WRITE);
83 STATUS_CASE(ERROR_DRM_ZERO_SUBSAMPLES);
84#undef STATUS_CASE
85 }
86 return static_cast<int>(err);
87}
88
89int DrmPluginSecurityLevelToJavaSecurityLevel(DrmPlugin::SecurityLevel securityLevel) {
90#define STATUS_CASE(status) \
91 case DrmPlugin::k##status: \
92 return J##status
93
94 switch (securityLevel) {
95 STATUS_CASE(SecurityLevelUnknown);
96 STATUS_CASE(SecurityLevelSwSecureCrypto);
97 STATUS_CASE(SecurityLevelSwSecureDecode);
98 STATUS_CASE(SecurityLevelHwSecureCrypto);
99 STATUS_CASE(SecurityLevelHwSecureDecode);
100 STATUS_CASE(SecurityLevelHwSecureAll);
101 STATUS_CASE(SecurityLevelMax);
102#undef STATUS_CASE
103 }
104 return static_cast<int>(securityLevel);
105}
106
107
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530108DrmStatus DrmMetricsLogger::initCheck() const {
109 DrmStatus status = mImpl->initCheck();
110 if (status != OK) {
111 reportMediaDrmErrored(status, __func__);
112 }
113 return status;
114}
115
Robert Shih37c16992023-01-30 19:58:35 +0000116DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[IDRM_UUID_SIZE],
117 const String8& mimeType,
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530118 DrmPlugin::SecurityLevel securityLevel,
119 bool* result) {
120 DrmStatus status = mImpl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
121 if (status != OK) {
122 reportMediaDrmErrored(status, __func__);
123 }
124 return status;
125}
126
Robert Shih37c16992023-01-30 19:58:35 +0000127DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[IDRM_UUID_SIZE],
128 const String8& appPackageName) {
129 std::memcpy(mUuid.data(), uuid, IDRM_UUID_SIZE);
Robert Shih7d5afd52023-02-22 07:45:36 +0000130 mUuid[0] = betoh64(mUuid[0]);
131 mUuid[1] = betoh64(mUuid[1]);
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530132 if (kUuidSchemeMap.count(mUuid)) {
133 mScheme = kUuidSchemeMap.at(mUuid);
134 } else {
135 mScheme = "Other";
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530136 }
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530137 if (generateNonce(&mObjNonce, kNonceSize, __func__) != OK) {
138 return ERROR_DRM_RESOURCE_BUSY;
139 }
140 DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
141 if (status == OK) {
Sohail Nagaraj8d2ed052023-02-28 11:45:43 +0530142 String8 version8;
143 if (getPropertyString(String8("version"), version8) == OK) {
144 mVersion = version8.string();
145 }
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530146 reportMediaDrmCreated();
147 } else {
148 reportMediaDrmErrored(status, __func__);
149 }
150 return status;
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530151}
152
153DrmStatus DrmMetricsLogger::destroyPlugin() {
154 DrmStatus status = mImpl->destroyPlugin();
155 if (status != OK) {
156 reportMediaDrmErrored(status, __func__);
157 }
158 return status;
159}
160
161DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
162 Vector<uint8_t>& sessionId) {
163 SessionContext ctx{};
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530164 if (generateNonce(&ctx.mNonce, kNonceSize, __func__) != OK) {
165 return ERROR_DRM_RESOURCE_BUSY;
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530166 }
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530167 DrmStatus status = mImpl->openSession(securityLevel, sessionId);
168 if (status == OK) {
169 std::vector<uint8_t> sessionKey = toStdVec(sessionId);
170 ctx.mTargetSecurityLevel = securityLevel;
171 if (getSecurityLevel(sessionId, &ctx.mActualSecurityLevel) != OK) {
172 ctx.mActualSecurityLevel = DrmPlugin::kSecurityLevelUnknown;
173 }
Sohail Nagaraj8d2ed052023-02-28 11:45:43 +0530174 if (!mVersion.empty()) {
175 ctx.mVersion = mVersion;
176 }
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530177 {
178 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
179 mSessionMap.insert({sessionKey, ctx});
180 }
181 reportMediaDrmSessionOpened(sessionKey);
182 } else {
183 reportMediaDrmErrored(status, __func__);
184 }
185 return status;
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530186}
187
188DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
189 std::vector<uint8_t> sid = toStdVec(sessionId);
190 {
191 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
192 mSessionMap.erase(sid);
193 }
194 DrmStatus status = mImpl->closeSession(sessionId);
195 if (status != OK) {
196 reportMediaDrmErrored(status, __func__, sid);
197 }
198 return status;
199}
200
201DrmStatus DrmMetricsLogger::getKeyRequest(Vector<uint8_t> const& sessionId,
202 Vector<uint8_t> const& initData, String8 const& mimeType,
203 DrmPlugin::KeyType keyType,
204 KeyedVector<String8, String8> const& optionalParameters,
205 Vector<uint8_t>& request, String8& defaultUrl,
206 DrmPlugin::KeyRequestType* keyRequestType) {
207 DrmStatus status =
208 mImpl->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters,
209 request, defaultUrl, keyRequestType);
210 if (status != OK) {
211 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
212 }
213 return status;
214}
215
216DrmStatus DrmMetricsLogger::provideKeyResponse(Vector<uint8_t> const& sessionId,
217 Vector<uint8_t> const& response,
218 Vector<uint8_t>& keySetId) {
219 DrmStatus status = mImpl->provideKeyResponse(sessionId, response, keySetId);
220 if (status != OK) {
221 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
222 }
223 return status;
224}
225
226DrmStatus DrmMetricsLogger::removeKeys(Vector<uint8_t> const& keySetId) {
227 DrmStatus status = mImpl->removeKeys(keySetId);
228 if (status != OK) {
229 reportMediaDrmErrored(status, __func__);
230 }
231 return status;
232}
233
234DrmStatus DrmMetricsLogger::restoreKeys(Vector<uint8_t> const& sessionId,
235 Vector<uint8_t> const& keySetId) {
236 DrmStatus status = mImpl->restoreKeys(sessionId, keySetId);
237 if (status != OK) {
238 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
239 }
240 return status;
241}
242
243DrmStatus DrmMetricsLogger::queryKeyStatus(Vector<uint8_t> const& sessionId,
244 KeyedVector<String8, String8>& infoMap) const {
245 DrmStatus status = mImpl->queryKeyStatus(sessionId, infoMap);
246 if (status != OK) {
247 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
248 }
249 return status;
250}
251
252DrmStatus DrmMetricsLogger::getProvisionRequest(String8 const& certType,
253 String8 const& certAuthority,
254 Vector<uint8_t>& request, String8& defaultUrl) {
255 DrmStatus status = mImpl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
256 if (status != OK) {
257 reportMediaDrmErrored(status, __func__);
258 }
259 return status;
260}
261
262DrmStatus DrmMetricsLogger::provideProvisionResponse(Vector<uint8_t> const& response,
263 Vector<uint8_t>& certificate,
264 Vector<uint8_t>& wrappedKey) {
265 DrmStatus status = mImpl->provideProvisionResponse(response, certificate, wrappedKey);
266 if (status != OK) {
267 reportMediaDrmErrored(status, __func__);
268 }
269 return status;
270}
271
272DrmStatus DrmMetricsLogger::getSecureStops(List<Vector<uint8_t>>& secureStops) {
273 DrmStatus status = mImpl->getSecureStops(secureStops);
274 if (status != OK) {
275 reportMediaDrmErrored(status, __func__);
276 }
277 return status;
278}
279
280DrmStatus DrmMetricsLogger::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
281 DrmStatus status = mImpl->getSecureStopIds(secureStopIds);
282 if (status != OK) {
283 reportMediaDrmErrored(status, __func__);
284 }
285 return status;
286}
287
288DrmStatus DrmMetricsLogger::getSecureStop(Vector<uint8_t> const& ssid,
289 Vector<uint8_t>& secureStop) {
290 DrmStatus status = mImpl->getSecureStop(ssid, secureStop);
291 if (status != OK) {
292 reportMediaDrmErrored(status, __func__);
293 }
294 return status;
295}
296
297DrmStatus DrmMetricsLogger::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
298 DrmStatus status = mImpl->releaseSecureStops(ssRelease);
299 if (status != OK) {
300 reportMediaDrmErrored(status, __func__);
301 }
302 return status;
303}
304
305DrmStatus DrmMetricsLogger::removeSecureStop(Vector<uint8_t> const& ssid) {
306 DrmStatus status = mImpl->removeSecureStop(ssid);
307 if (status != OK) {
308 reportMediaDrmErrored(status, __func__);
309 }
310 return status;
311}
312
313DrmStatus DrmMetricsLogger::removeAllSecureStops() {
314 DrmStatus status = mImpl->removeAllSecureStops();
315 if (status != OK) {
316 reportMediaDrmErrored(status, __func__);
317 }
318 return status;
319}
320
321DrmStatus DrmMetricsLogger::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
322 DrmPlugin::HdcpLevel* maxLevel) const {
323 DrmStatus status = mImpl->getHdcpLevels(connectedLevel, maxLevel);
324 if (status != OK) {
325 reportMediaDrmErrored(status, __func__);
326 }
327 return status;
328}
329
330DrmStatus DrmMetricsLogger::getNumberOfSessions(uint32_t* currentSessions,
331 uint32_t* maxSessions) const {
332 DrmStatus status = mImpl->getNumberOfSessions(currentSessions, maxSessions);
333 if (status != OK) {
334 reportMediaDrmErrored(status, __func__);
335 }
336 return status;
337}
338
339DrmStatus DrmMetricsLogger::getSecurityLevel(Vector<uint8_t> const& sessionId,
340 DrmPlugin::SecurityLevel* level) const {
341 DrmStatus status = mImpl->getSecurityLevel(sessionId, level);
342 if (status != OK) {
343 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
344 }
345 return status;
346}
347
348DrmStatus DrmMetricsLogger::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
349 DrmStatus status = mImpl->getOfflineLicenseKeySetIds(keySetIds);
350 if (status != OK) {
351 reportMediaDrmErrored(status, __func__);
352 }
353 return status;
354}
355
356DrmStatus DrmMetricsLogger::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
357 DrmStatus status = mImpl->removeOfflineLicense(keySetId);
358 if (status != OK) {
359 reportMediaDrmErrored(status, __func__);
360 }
361 return status;
362}
363
364DrmStatus DrmMetricsLogger::getOfflineLicenseState(
365 Vector<uint8_t> const& keySetId, DrmPlugin::OfflineLicenseState* licenseState) const {
366 DrmStatus status = mImpl->getOfflineLicenseState(keySetId, licenseState);
367 if (status != OK) {
368 reportMediaDrmErrored(status, __func__);
369 }
370 return status;
371}
372
373DrmStatus DrmMetricsLogger::getPropertyString(String8 const& name, String8& value) const {
374 DrmStatus status = mImpl->getPropertyString(name, value);
375 if (status != OK) {
376 reportMediaDrmErrored(status, __func__);
377 }
378 return status;
379}
380
381DrmStatus DrmMetricsLogger::getPropertyByteArray(String8 const& name,
382 Vector<uint8_t>& value) const {
383 DrmStatus status = mImpl->getPropertyByteArray(name, value);
384 if (status != OK) {
385 reportMediaDrmErrored(status, __func__);
386 }
387 return status;
388}
389
390DrmStatus DrmMetricsLogger::setPropertyString(String8 const& name, String8 const& value) const {
391 DrmStatus status = mImpl->setPropertyString(name, value);
392 if (status != OK) {
393 reportMediaDrmErrored(status, __func__);
394 }
395 return status;
396}
397
398DrmStatus DrmMetricsLogger::setPropertyByteArray(String8 const& name,
399 Vector<uint8_t> const& value) const {
400 DrmStatus status = mImpl->setPropertyByteArray(name, value);
401 if (status != OK) {
402 reportMediaDrmErrored(status, __func__);
403 }
404 return status;
405}
406
407DrmStatus DrmMetricsLogger::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
408 DrmStatus status = mImpl->getMetrics(consumer);
409 if (status != OK) {
410 reportMediaDrmErrored(status, __func__);
411 }
412 return status;
413}
414
415DrmStatus DrmMetricsLogger::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
416 String8 const& algorithm) {
417 DrmStatus status = mImpl->setCipherAlgorithm(sessionId, algorithm);
418 if (status != OK) {
419 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
420 }
421 return status;
422}
423
424DrmStatus DrmMetricsLogger::setMacAlgorithm(Vector<uint8_t> const& sessionId,
425 String8 const& algorithm) {
426 DrmStatus status = mImpl->setMacAlgorithm(sessionId, algorithm);
427 if (status != OK) {
428 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
429 }
430 return status;
431}
432
433DrmStatus DrmMetricsLogger::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
434 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
435 Vector<uint8_t>& output) {
436 DrmStatus status = mImpl->encrypt(sessionId, keyId, input, iv, output);
437 if (status != OK) {
438 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
439 }
440 return status;
441}
442
443DrmStatus DrmMetricsLogger::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
444 Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
445 Vector<uint8_t>& output) {
446 DrmStatus status = mImpl->decrypt(sessionId, keyId, input, iv, output);
447 if (status != OK) {
448 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
449 }
450 return status;
451}
452
453DrmStatus DrmMetricsLogger::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
454 Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
455 DrmStatus status = mImpl->sign(sessionId, keyId, message, signature);
456 if (status != OK) {
457 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
458 }
459 return status;
460}
461
462DrmStatus DrmMetricsLogger::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
463 Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
464 bool& match) {
465 DrmStatus status = mImpl->verify(sessionId, keyId, message, signature, match);
466 if (status != OK) {
467 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
468 }
469 return status;
470}
471
472DrmStatus DrmMetricsLogger::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
473 Vector<uint8_t> const& message,
474 Vector<uint8_t> const& wrappedKey, Vector<uint8_t>& signature) {
475 DrmStatus status = mImpl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
476 if (status != OK) {
477 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
478 }
479 return status;
480}
481
482DrmStatus DrmMetricsLogger::setListener(const sp<IDrmClient>& listener) {
483 DrmStatus status = mImpl->setListener(listener);
484 if (status != OK) {
485 reportMediaDrmErrored(status, __func__);
486 }
487 return status;
488}
489
490DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime, bool* required) const {
491 DrmStatus status = mImpl->requiresSecureDecoder(mime, required);
492 if (status != OK) {
493 reportMediaDrmErrored(status, __func__);
494 }
495 return status;
496}
497
498DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
499 DrmPlugin::SecurityLevel securityLevel,
500 bool* required) const {
501 DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
502 if (status != OK) {
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530503 reportMediaDrmErrored(status, "requiresSecureDecoderLevel");
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530504 }
505 return status;
506}
507
508DrmStatus DrmMetricsLogger::setPlaybackId(Vector<uint8_t> const& sessionId,
509 const char* playbackId) {
510 DrmStatus status = mImpl->setPlaybackId(sessionId, playbackId);
511 if (status != OK) {
512 reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
513 }
514 return status;
515}
516
517DrmStatus DrmMetricsLogger::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
518 DrmStatus status = mImpl->getLogMessages(logs);
519 if (status != OK) {
520 reportMediaDrmErrored(status, __func__);
521 }
522 return status;
523}
524
525DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
526 DrmStatus status = mImpl->getSupportedSchemes(schemes);
527 if (status != OK) {
528 reportMediaDrmErrored(status, __func__);
529 }
530 return status;
531}
532
533void DrmMetricsLogger::reportMediaDrmCreated() const {
534 mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530535 mediametrics_setCString(handle, "scheme", mScheme.c_str());
Robert Shih7d5afd52023-02-22 07:45:36 +0000536 mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
537 mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530538 mediametrics_setInt32(handle, "frontend", mFrontend);
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530539 mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
Sohail Nagaraj8d2ed052023-02-28 11:45:43 +0530540 mediametrics_setCString(handle, "version", mVersion.c_str());
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530541 mediametrics_selfRecord(handle);
542 mediametrics_delete(handle);
543}
544
Sohail Nagarajdef1b732023-01-12 21:22:12 +0530545void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530546 mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530547 mediametrics_setCString(handle, "scheme", mScheme.c_str());
Robert Shih7d5afd52023-02-22 07:45:36 +0000548 mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
549 mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530550 mediametrics_setInt32(handle, "frontend", mFrontend);
Sohail Nagaraj8d2ed052023-02-28 11:45:43 +0530551 mediametrics_setCString(handle, "version", mVersion.c_str());
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530552 mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530553 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
554 auto it = mSessionMap.find(sessionId);
555 if (it != mSessionMap.end()) {
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530556 mediametrics_setCString(handle, "session_nonce", it->second.mNonce.c_str());
Sohail Nagaraj76c2f9e2023-03-06 13:07:31 +0530557 mediametrics_setInt32(handle, "requested_security_level",
558 DrmPluginSecurityLevelToJavaSecurityLevel(it->second.mTargetSecurityLevel));
559 mediametrics_setInt32(handle, "opened_security_level",
560 DrmPluginSecurityLevelToJavaSecurityLevel(it->second.mActualSecurityLevel));
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530561 }
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530562 mediametrics_selfRecord(handle);
563 mediametrics_delete(handle);
564}
565
Sohail Nagarajdef1b732023-01-12 21:22:12 +0530566void DrmMetricsLogger::reportMediaDrmErrored(const DrmStatus& error_code, const char* api,
567 const std::vector<uint8_t>& sessionId) const {
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530568 mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530569 mediametrics_setCString(handle, "scheme", mScheme.c_str());
Robert Shih7d5afd52023-02-22 07:45:36 +0000570 mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
571 mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530572 mediametrics_setInt32(handle, "frontend", mFrontend);
Sohail Nagaraj8d2ed052023-02-28 11:45:43 +0530573 mediametrics_setCString(handle, "version", mVersion.c_str());
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530574 mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530575 if (!sessionId.empty()) {
576 const std::lock_guard<std::mutex> lock(mSessionMapMutex);
577 auto it = mSessionMap.find(sessionId);
578 if (it != mSessionMap.end()) {
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530579 mediametrics_setCString(handle, "session_nonce", it->second.mNonce.c_str());
Sohail Nagaraj76c2f9e2023-03-06 13:07:31 +0530580 mediametrics_setInt32(handle, "security_level",
581 DrmPluginSecurityLevelToJavaSecurityLevel(it->second.mActualSecurityLevel));
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530582 }
583 }
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530584 mediametrics_setCString(handle, "api", api);
Sohail Nagaraj76c2f9e2023-03-06 13:07:31 +0530585 mediametrics_setInt32(handle, "error_code", MediaErrorToJavaError(error_code));
Sohail Nagarajdef1b732023-01-12 21:22:12 +0530586 mediametrics_setInt32(handle, "cdm_err", error_code.getCdmErr());
587 mediametrics_setInt32(handle, "oem_err", error_code.getOemErr());
588 mediametrics_setInt32(handle, "error_context", error_code.getContext());
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530589 mediametrics_selfRecord(handle);
590 mediametrics_delete(handle);
591}
592
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530593DrmStatus DrmMetricsLogger::generateNonce(std::string* out, size_t size, const char* api) {
594 std::vector<uint8_t> buf(size);
595 ssize_t bytes = getrandom(buf.data(), size, GRND_NONBLOCK);
596 if (bytes < size) {
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530597 ALOGE("getrandom failed: %d", errno);
598 reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
599 return ERROR_DRM_RESOURCE_BUSY;
600 }
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530601 android::AString tmp;
602 encodeBase64(buf.data(), size, &tmp);
603 out->assign(tmp.c_str());
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530604 return OK;
605}
606
Sohail Nagaraj2ae39ca2023-01-19 18:12:07 +0530607const std::map<std::array<int64_t, 2>, std::string> DrmMetricsLogger::kUuidSchemeMap {
608 {{(int64_t)0x6DD8B3C345F44A68, (int64_t)0xBF3A64168D01A4A6}, "ABV DRM (MoDRM)"},
609 {{(int64_t)0xF239E769EFA34850, (int64_t)0x9C16A903C6932EFB},
610 "Adobe Primetime DRM version 4"},
611 {{(int64_t)0x616C746963617374, (int64_t)0x2D50726F74656374}, "Alticast"},
612 {{(int64_t)0x94CE86FB07FF4F43, (int64_t)0xADB893D2FA968CA2}, "Apple FairPlay"},
613 {{(int64_t)0x279FE473512C48FE, (int64_t)0xADE8D176FEE6B40F}, "Arris Titanium"},
614 {{(int64_t)0x3D5E6D359B9A41E8, (int64_t)0xB843DD3C6E72C42C}, "ChinaDRM"},
615 {{(int64_t)0x3EA8778F77424BF9, (int64_t)0xB18BE834B2ACBD47}, "Clear Key AES-128"},
616 {{(int64_t)0xBE58615B19C44684, (int64_t)0x88B3C8C57E99E957}, "Clear Key SAMPLE-AES"},
617 {{(int64_t)0xE2719D58A985B3C9, (int64_t)0x781AB030AF78D30E}, "Clear Key DASH-IF"},
618 {{(int64_t)0x644FE7B5260F4FAD, (int64_t)0x949A0762FFB054B4}, "CMLA (OMA DRM)"},
619 {{(int64_t)0x37C332587B994C7E, (int64_t)0xB15D19AF74482154}, "Commscope Titanium V3"},
620 {{(int64_t)0x45D481CB8FE049C0, (int64_t)0xADA9AB2D2455B2F2}, "CoreCrypt"},
621 {{(int64_t)0xDCF4E3E362F15818, (int64_t)0x7BA60A6FE33FF3DD}, "DigiCAP SmartXess"},
622 {{(int64_t)0x35BF197B530E42D7, (int64_t)0x8B651B4BF415070F}, "DivX DRM Series 5"},
623 {{(int64_t)0x80A6BE7E14484C37, (int64_t)0x9E70D5AEBE04C8D2}, "Irdeto Content Protection"},
624 {{(int64_t)0x5E629AF538DA4063, (int64_t)0x897797FFBD9902D4},
625 "Marlin Adaptive Streaming Simple Profile V1.0"},
626 {{(int64_t)0x9A04F07998404286, (int64_t)0xAB92E65BE0885F95}, "Microsoft PlayReady"},
627 {{(int64_t)0x6A99532D869F5922, (int64_t)0x9A91113AB7B1E2F3}, "MobiTV DRM"},
628 {{(int64_t)0xADB41C242DBF4A6D, (int64_t)0x958B4457C0D27B95}, "Nagra MediaAccess PRM 3.0"},
629 {{(int64_t)0x1F83E1E86EE94F0D, (int64_t)0xBA2F5EC4E3ED1A66}, "SecureMedia"},
630 {{(int64_t)0x992C46E6C4374899, (int64_t)0xB6A050FA91AD0E39}, "SecureMedia SteelKnot"},
631 {{(int64_t)0xA68129D3575B4F1A, (int64_t)0x9CBA3223846CF7C3},
632 "Synamedia/Cisco/NDS VideoGuard DRM"},
633 {{(int64_t)0xAA11967FCC014A4A, (int64_t)0x8E99C5D3DDDFEA2D}, "Unitend DRM (UDRM)"},
634 {{(int64_t)0x9A27DD82FDE24725, (int64_t)0x8CBC4234AA06EC09}, "Verimatrix VCAS"},
635 {{(int64_t)0xB4413586C58CFFB0, (int64_t)0x94A5D4896C1AF6C3}, "Viaccess-Orca DRM (VODRM)"},
636 {{(int64_t)0x793B79569F944946, (int64_t)0xA94223E7EF7E44B4}, "VisionCrypt"},
637 {{(int64_t)0x1077EFECC0B24D02, (int64_t)0xACE33C1E52E2FB4B}, "W3C Common PSSH box"},
638 {{(int64_t)0xEDEF8BA979D64ACE, (int64_t)0xA3C827DCD51D21ED}, "Widevine Content Protection"},
639};
640
Sohail Nagaraj17d54db2022-12-29 10:00:59 +0530641} // namespace android