1 /*
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 <media/stagefright/foundation/AString.h>
22 #include <media/stagefright/foundation/base64.h>
23 #include <mediadrm/DrmHal.h>
24 #include <mediadrm/DrmMetricsLogger.h>
25 #include <mediadrm/DrmUtils.h>
26 
27 namespace android {
28 
29 namespace {
30 
toStdVec(Vector<uint8_t> const & sessionId)31 std::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 }
36 
37 }  // namespace
38 
DrmMetricsLogger(IDrmFrontend frontend)39 DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
40     : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonce(), mFrontend(frontend) {}
41 
~DrmMetricsLogger()42 DrmMetricsLogger::~DrmMetricsLogger() {}
43 
MediaErrorToEnum(status_t err)44 int MediaErrorToEnum(status_t err) {
45 #define ERROR_BAD_VALUE (BAD_VALUE)
46 #define ERROR_DEAD_OBJECT (DEAD_OBJECT)
47 #define STATUS_CASE(status) \
48     case ERROR_##status: \
49         return ENUM_##status
50 
51     switch (err) {
52         STATUS_CASE(DRM_UNKNOWN);
53         STATUS_CASE(DRM_NO_LICENSE);
54         STATUS_CASE(DRM_LICENSE_EXPIRED);
55         STATUS_CASE(DRM_RESOURCE_BUSY);
56         STATUS_CASE(DRM_INSUFFICIENT_OUTPUT_PROTECTION);
57         STATUS_CASE(DRM_SESSION_NOT_OPENED);
58         STATUS_CASE(DRM_CANNOT_HANDLE);
59         STATUS_CASE(DRM_INSUFFICIENT_SECURITY);
60         STATUS_CASE(DRM_FRAME_TOO_LARGE);
61         STATUS_CASE(DRM_SESSION_LOST_STATE);
62         STATUS_CASE(DRM_CERTIFICATE_MALFORMED);
63         STATUS_CASE(DRM_CERTIFICATE_MISSING);
64         STATUS_CASE(DRM_CRYPTO_LIBRARY);
65         STATUS_CASE(DRM_GENERIC_OEM);
66         STATUS_CASE(DRM_GENERIC_PLUGIN);
67         STATUS_CASE(DRM_INIT_DATA);
68         STATUS_CASE(DRM_KEY_NOT_LOADED);
69         STATUS_CASE(DRM_LICENSE_PARSE);
70         STATUS_CASE(DRM_LICENSE_POLICY);
71         STATUS_CASE(DRM_LICENSE_RELEASE);
72         STATUS_CASE(DRM_LICENSE_REQUEST_REJECTED);
73         STATUS_CASE(DRM_LICENSE_RESTORE);
74         STATUS_CASE(DRM_LICENSE_STATE);
75         STATUS_CASE(DRM_MEDIA_FRAMEWORK);
76         STATUS_CASE(DRM_PROVISIONING_CERTIFICATE);
77         STATUS_CASE(DRM_PROVISIONING_CONFIG);
78         STATUS_CASE(DRM_PROVISIONING_PARSE);
79         STATUS_CASE(DRM_PROVISIONING_REQUEST_REJECTED);
80         STATUS_CASE(DRM_PROVISIONING_RETRY);
81         STATUS_CASE(DRM_RESOURCE_CONTENTION);
82         STATUS_CASE(DRM_SECURE_STOP_RELEASE);
83         STATUS_CASE(DRM_STORAGE_READ);
84         STATUS_CASE(DRM_STORAGE_WRITE);
85         STATUS_CASE(DRM_ZERO_SUBSAMPLES);
86         STATUS_CASE(DRM_INVALID_STATE);
87         STATUS_CASE(BAD_VALUE);
88         STATUS_CASE(DRM_NOT_PROVISIONED);
89         STATUS_CASE(DRM_DEVICE_REVOKED);
90         STATUS_CASE(DRM_DECRYPT);
91         STATUS_CASE(DEAD_OBJECT);
92 #undef ERROR_BAD_VALUE
93 #undef ERROR_DEAD_OBJECT
94 #undef STATUS_CASE
95     }
96     return ENUM_DRM_UNKNOWN;
97 }
98 
DrmPluginSecurityLevelToJavaSecurityLevel(DrmPlugin::SecurityLevel securityLevel)99 int DrmPluginSecurityLevelToJavaSecurityLevel(DrmPlugin::SecurityLevel securityLevel) {
100 #define STATUS_CASE(status) \
101     case DrmPlugin::k##status: \
102         return J##status
103 
104     switch (securityLevel) {
105         STATUS_CASE(SecurityLevelUnknown);
106         STATUS_CASE(SecurityLevelSwSecureCrypto);
107         STATUS_CASE(SecurityLevelSwSecureDecode);
108         STATUS_CASE(SecurityLevelHwSecureCrypto);
109         STATUS_CASE(SecurityLevelHwSecureDecode);
110         STATUS_CASE(SecurityLevelHwSecureAll);
111         STATUS_CASE(SecurityLevelMax);
112 #undef STATUS_CASE
113     }
114     return static_cast<int>(securityLevel);
115 }
116 
117 
initCheck() const118 DrmStatus DrmMetricsLogger::initCheck() const {
119     DrmStatus status = mImpl->initCheck();
120     if (status != OK) {
121         reportMediaDrmErrored(status, __func__);
122     }
123     return status;
124 }
125 
isCryptoSchemeSupported(const uint8_t uuid[IDRM_UUID_SIZE],const String8 & mimeType,DrmPlugin::SecurityLevel securityLevel,bool * result)126 DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[IDRM_UUID_SIZE],
127                                                     const String8& mimeType,
128                                                     DrmPlugin::SecurityLevel securityLevel,
129                                                     bool* result) {
130     DrmStatus status = mImpl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
131     if (status != OK) {
132         reportMediaDrmErrored(status, __func__);
133     }
134     return status;
135 }
136 
createPlugin(const uint8_t uuid[IDRM_UUID_SIZE],const String8 & appPackageName)137 DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[IDRM_UUID_SIZE],
138                                          const String8& appPackageName) {
139     std::memcpy(mUuid.data(), uuid, IDRM_UUID_SIZE);
140     mUuid[0] = betoh64(mUuid[0]);
141     mUuid[1] = betoh64(mUuid[1]);
142     if (kUuidSchemeMap.count(mUuid)) {
143         mScheme = kUuidSchemeMap.at(mUuid);
144     } else {
145         mScheme = "Other";
146     }
147     if (generateNonce(&mObjNonce, kNonceSize, __func__) != OK) {
148         return ERROR_DRM_RESOURCE_BUSY;
149     }
150     DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
151     if (status == OK) {
152         String8 version8;
153         if (getPropertyString(String8("version"), version8) == OK) {
154             mVersion = version8.c_str();
155         }
156         reportMediaDrmCreated();
157     } else {
158         reportMediaDrmErrored(status, __func__);
159     }
160     return status;
161 }
162 
destroyPlugin()163 DrmStatus DrmMetricsLogger::destroyPlugin() {
164     DrmStatus status = mImpl->destroyPlugin();
165     if (status != OK) {
166         reportMediaDrmErrored(status, __func__);
167     }
168     return status;
169 }
170 
openSession(DrmPlugin::SecurityLevel securityLevel,Vector<uint8_t> & sessionId)171 DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
172                                         Vector<uint8_t>& sessionId) {
173     SessionContext ctx{};
174     if (generateNonce(&ctx.mNonce, kNonceSize, __func__) != OK) {
175         return ERROR_DRM_RESOURCE_BUSY;
176     }
177     DrmStatus status = mImpl->openSession(securityLevel, sessionId);
178     if (status == OK) {
179         std::vector<uint8_t> sessionKey = toStdVec(sessionId);
180         ctx.mTargetSecurityLevel = securityLevel;
181         if (getSecurityLevel(sessionId, &ctx.mActualSecurityLevel) != OK) {
182             ctx.mActualSecurityLevel = DrmPlugin::kSecurityLevelUnknown;
183         }
184         if (!mVersion.empty()) {
185             ctx.mVersion = mVersion;
186         }
187         {
188             const std::lock_guard<std::mutex> lock(mSessionMapMutex);
189             mSessionMap.insert({sessionKey, ctx});
190         }
191         reportMediaDrmSessionOpened(sessionKey);
192     } else {
193         reportMediaDrmErrored(status, __func__);
194     }
195     return status;
196 }
197 
closeSession(Vector<uint8_t> const & sessionId)198 DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
199     std::vector<uint8_t> sid = toStdVec(sessionId);
200     DrmStatus status = mImpl->closeSession(sessionId);
201     if (status == OK) {
202         const std::lock_guard<std::mutex> lock(mSessionMapMutex);
203         mSessionMap.erase(sid);
204     } else {
205         // TODO(b/275729711): reclaim sessions that failed to close
206         reportMediaDrmErrored(status, __func__, sid);
207     }
208     return status;
209 }
210 
getKeyRequest(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & initData,String8 const & mimeType,DrmPlugin::KeyType keyType,KeyedVector<String8,String8> const & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl,DrmPlugin::KeyRequestType * keyRequestType)211 DrmStatus DrmMetricsLogger::getKeyRequest(Vector<uint8_t> const& sessionId,
212                                           Vector<uint8_t> const& initData, String8 const& mimeType,
213                                           DrmPlugin::KeyType keyType,
214                                           KeyedVector<String8, String8> const& optionalParameters,
215                                           Vector<uint8_t>& request, String8& defaultUrl,
216                                           DrmPlugin::KeyRequestType* keyRequestType) {
217     DrmStatus status =
218             mImpl->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters,
219                                  request, defaultUrl, keyRequestType);
220     if (status != OK) {
221         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
222     }
223     return status;
224 }
225 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)226 DrmStatus DrmMetricsLogger::provideKeyResponse(Vector<uint8_t> const& sessionId,
227                                                Vector<uint8_t> const& response,
228                                                Vector<uint8_t>& keySetId) {
229     DrmStatus status = mImpl->provideKeyResponse(sessionId, response, keySetId);
230     if (status != OK) {
231         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
232     }
233     return status;
234 }
235 
removeKeys(Vector<uint8_t> const & keySetId)236 DrmStatus DrmMetricsLogger::removeKeys(Vector<uint8_t> const& keySetId) {
237     DrmStatus status = mImpl->removeKeys(keySetId);
238     if (status != OK) {
239         reportMediaDrmErrored(status, __func__);
240     }
241     return status;
242 }
243 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)244 DrmStatus DrmMetricsLogger::restoreKeys(Vector<uint8_t> const& sessionId,
245                                         Vector<uint8_t> const& keySetId) {
246     DrmStatus status = mImpl->restoreKeys(sessionId, keySetId);
247     if (status != OK) {
248         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
249     }
250     return status;
251 }
252 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const253 DrmStatus DrmMetricsLogger::queryKeyStatus(Vector<uint8_t> const& sessionId,
254                                            KeyedVector<String8, String8>& infoMap) const {
255     DrmStatus status = mImpl->queryKeyStatus(sessionId, infoMap);
256     if (status != OK) {
257         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
258     }
259     return status;
260 }
261 
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)262 DrmStatus DrmMetricsLogger::getProvisionRequest(String8 const& certType,
263                                                 String8 const& certAuthority,
264                                                 Vector<uint8_t>& request, String8& defaultUrl) {
265     DrmStatus status = mImpl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
266     if (status != OK) {
267         reportMediaDrmErrored(status, __func__);
268     }
269     return status;
270 }
271 
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)272 DrmStatus DrmMetricsLogger::provideProvisionResponse(Vector<uint8_t> const& response,
273                                                      Vector<uint8_t>& certificate,
274                                                      Vector<uint8_t>& wrappedKey) {
275     DrmStatus status = mImpl->provideProvisionResponse(response, certificate, wrappedKey);
276     if (status != OK) {
277         reportMediaDrmErrored(status, __func__);
278     }
279     return status;
280 }
281 
getSecureStops(List<Vector<uint8_t>> & secureStops)282 DrmStatus DrmMetricsLogger::getSecureStops(List<Vector<uint8_t>>& secureStops) {
283     DrmStatus status = mImpl->getSecureStops(secureStops);
284     if (status != OK) {
285         reportMediaDrmErrored(status, __func__);
286     }
287     return status;
288 }
289 
getSecureStopIds(List<Vector<uint8_t>> & secureStopIds)290 DrmStatus DrmMetricsLogger::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
291     DrmStatus status = mImpl->getSecureStopIds(secureStopIds);
292     if (status != OK) {
293         reportMediaDrmErrored(status, __func__);
294     }
295     return status;
296 }
297 
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)298 DrmStatus DrmMetricsLogger::getSecureStop(Vector<uint8_t> const& ssid,
299                                           Vector<uint8_t>& secureStop) {
300     DrmStatus status = mImpl->getSecureStop(ssid, secureStop);
301     if (status != OK) {
302         reportMediaDrmErrored(status, __func__);
303     }
304     return status;
305 }
306 
releaseSecureStops(Vector<uint8_t> const & ssRelease)307 DrmStatus DrmMetricsLogger::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
308     DrmStatus status = mImpl->releaseSecureStops(ssRelease);
309     if (status != OK) {
310         reportMediaDrmErrored(status, __func__);
311     }
312     return status;
313 }
314 
removeSecureStop(Vector<uint8_t> const & ssid)315 DrmStatus DrmMetricsLogger::removeSecureStop(Vector<uint8_t> const& ssid) {
316     DrmStatus status = mImpl->removeSecureStop(ssid);
317     if (status != OK) {
318         reportMediaDrmErrored(status, __func__);
319     }
320     return status;
321 }
322 
removeAllSecureStops()323 DrmStatus DrmMetricsLogger::removeAllSecureStops() {
324     DrmStatus status = mImpl->removeAllSecureStops();
325     if (status != OK) {
326         reportMediaDrmErrored(status, __func__);
327     }
328     return status;
329 }
330 
getHdcpLevels(DrmPlugin::HdcpLevel * connectedLevel,DrmPlugin::HdcpLevel * maxLevel) const331 DrmStatus DrmMetricsLogger::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
332                                           DrmPlugin::HdcpLevel* maxLevel) const {
333     DrmStatus status = mImpl->getHdcpLevels(connectedLevel, maxLevel);
334     if (status != OK) {
335         reportMediaDrmErrored(status, __func__);
336     }
337     return status;
338 }
339 
getNumberOfSessions(uint32_t * currentSessions,uint32_t * maxSessions) const340 DrmStatus DrmMetricsLogger::getNumberOfSessions(uint32_t* currentSessions,
341                                                 uint32_t* maxSessions) const {
342     DrmStatus status = mImpl->getNumberOfSessions(currentSessions, maxSessions);
343     if (status != OK) {
344         reportMediaDrmErrored(status, __func__);
345     }
346     return status;
347 }
348 
getSecurityLevel(Vector<uint8_t> const & sessionId,DrmPlugin::SecurityLevel * level) const349 DrmStatus DrmMetricsLogger::getSecurityLevel(Vector<uint8_t> const& sessionId,
350                                              DrmPlugin::SecurityLevel* level) const {
351     DrmStatus status = mImpl->getSecurityLevel(sessionId, level);
352     if (status != OK) {
353         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
354     }
355     return status;
356 }
357 
getOfflineLicenseKeySetIds(List<Vector<uint8_t>> & keySetIds) const358 DrmStatus DrmMetricsLogger::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
359     DrmStatus status = mImpl->getOfflineLicenseKeySetIds(keySetIds);
360     if (status != OK) {
361         reportMediaDrmErrored(status, __func__);
362     }
363     return status;
364 }
365 
removeOfflineLicense(Vector<uint8_t> const & keySetId)366 DrmStatus DrmMetricsLogger::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
367     DrmStatus status = mImpl->removeOfflineLicense(keySetId);
368     if (status != OK) {
369         reportMediaDrmErrored(status, __func__);
370     }
371     return status;
372 }
373 
getOfflineLicenseState(Vector<uint8_t> const & keySetId,DrmPlugin::OfflineLicenseState * licenseState) const374 DrmStatus DrmMetricsLogger::getOfflineLicenseState(
375         Vector<uint8_t> const& keySetId, DrmPlugin::OfflineLicenseState* licenseState) const {
376     DrmStatus status = mImpl->getOfflineLicenseState(keySetId, licenseState);
377     if (status != OK) {
378         reportMediaDrmErrored(status, __func__);
379     }
380     return status;
381 }
382 
getPropertyString(String8 const & name,String8 & value) const383 DrmStatus DrmMetricsLogger::getPropertyString(String8 const& name, String8& value) const {
384     DrmStatus status = mImpl->getPropertyString(name, value);
385     if (status != OK) {
386         reportMediaDrmErrored(status, __func__);
387     }
388     return status;
389 }
390 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const391 DrmStatus DrmMetricsLogger::getPropertyByteArray(String8 const& name,
392                                                  Vector<uint8_t>& value) const {
393     DrmStatus status = mImpl->getPropertyByteArray(name, value);
394     if (status != OK) {
395         reportMediaDrmErrored(status, __func__);
396     }
397     return status;
398 }
399 
setPropertyString(String8 const & name,String8 const & value) const400 DrmStatus DrmMetricsLogger::setPropertyString(String8 const& name, String8 const& value) const {
401     DrmStatus status = mImpl->setPropertyString(name, value);
402     if (status != OK) {
403         reportMediaDrmErrored(status, __func__);
404     }
405     return status;
406 }
407 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const408 DrmStatus DrmMetricsLogger::setPropertyByteArray(String8 const& name,
409                                                  Vector<uint8_t> const& value) const {
410     DrmStatus status = mImpl->setPropertyByteArray(name, value);
411     if (status != OK) {
412         reportMediaDrmErrored(status, __func__);
413     }
414     return status;
415 }
416 
getMetrics(const sp<IDrmMetricsConsumer> & consumer)417 DrmStatus DrmMetricsLogger::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
418     DrmStatus status = mImpl->getMetrics(consumer);
419     if (status != OK) {
420         reportMediaDrmErrored(status, __func__);
421     }
422     return status;
423 }
424 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)425 DrmStatus DrmMetricsLogger::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
426                                                String8 const& algorithm) {
427     DrmStatus status = mImpl->setCipherAlgorithm(sessionId, algorithm);
428     if (status != OK) {
429         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
430     }
431     return status;
432 }
433 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)434 DrmStatus DrmMetricsLogger::setMacAlgorithm(Vector<uint8_t> const& sessionId,
435                                             String8 const& algorithm) {
436     DrmStatus status = mImpl->setMacAlgorithm(sessionId, algorithm);
437     if (status != OK) {
438         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
439     }
440     return status;
441 }
442 
encrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)443 DrmStatus DrmMetricsLogger::encrypt(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->encrypt(sessionId, keyId, input, iv, output);
447     if (status != OK) {
448         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
449     }
450     return status;
451 }
452 
decrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)453 DrmStatus DrmMetricsLogger::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
454                                     Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
455                                     Vector<uint8_t>& output) {
456     DrmStatus status = mImpl->decrypt(sessionId, keyId, input, iv, output);
457     if (status != OK) {
458         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
459     }
460     return status;
461 }
462 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)463 DrmStatus DrmMetricsLogger::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
464                                  Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
465     DrmStatus status = mImpl->sign(sessionId, keyId, message, signature);
466     if (status != OK) {
467         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
468     }
469     return status;
470 }
471 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)472 DrmStatus DrmMetricsLogger::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
473                                    Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
474                                    bool& match) {
475     DrmStatus status = mImpl->verify(sessionId, keyId, message, signature, match);
476     if (status != OK) {
477         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
478     }
479     return status;
480 }
481 
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)482 DrmStatus DrmMetricsLogger::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
483                                     Vector<uint8_t> const& message,
484                                     Vector<uint8_t> const& wrappedKey, Vector<uint8_t>& signature) {
485     DrmStatus status = mImpl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
486     if (status != OK) {
487         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
488     }
489     return status;
490 }
491 
setListener(const sp<IDrmClient> & listener)492 DrmStatus DrmMetricsLogger::setListener(const sp<IDrmClient>& listener) {
493     DrmStatus status = mImpl->setListener(listener);
494     if (status != OK) {
495         reportMediaDrmErrored(status, __func__);
496     }
497     return status;
498 }
499 
requiresSecureDecoder(const char * mime,bool * required) const500 DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime, bool* required) const {
501     DrmStatus status = mImpl->requiresSecureDecoder(mime, required);
502     if (status != OK) {
503         reportMediaDrmErrored(status, __func__);
504     }
505     return status;
506 }
507 
requiresSecureDecoder(const char * mime,DrmPlugin::SecurityLevel securityLevel,bool * required) const508 DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
509                                                   DrmPlugin::SecurityLevel securityLevel,
510                                                   bool* required) const {
511     DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
512     if (status != OK) {
513         reportMediaDrmErrored(status, "requiresSecureDecoderLevel");
514     }
515     return status;
516 }
517 
setPlaybackId(Vector<uint8_t> const & sessionId,const char * playbackId)518 DrmStatus DrmMetricsLogger::setPlaybackId(Vector<uint8_t> const& sessionId,
519                                           const char* playbackId) {
520     DrmStatus status = mImpl->setPlaybackId(sessionId, playbackId);
521     if (status != OK) {
522         reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
523     }
524     return status;
525 }
526 
getLogMessages(Vector<drm::V1_4::LogMessage> & logs) const527 DrmStatus DrmMetricsLogger::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
528     DrmStatus status = mImpl->getLogMessages(logs);
529     if (status != OK) {
530         reportMediaDrmErrored(status, __func__);
531     }
532     return status;
533 }
534 
getSupportedSchemes(std::vector<uint8_t> & schemes) const535 DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
536     DrmStatus status = mImpl->getSupportedSchemes(schemes);
537     if (status != OK) {
538         reportMediaDrmErrored(status, __func__);
539     }
540     return status;
541 }
542 
reportMediaDrmCreated() const543 void DrmMetricsLogger::reportMediaDrmCreated() const {
544     mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
545     mediametrics_setCString(handle, "scheme", mScheme.c_str());
546     mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
547     mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
548     mediametrics_setInt32(handle, "frontend", mFrontend);
549     mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
550     mediametrics_setCString(handle, "version", mVersion.c_str());
551     mediametrics_selfRecord(handle);
552     mediametrics_delete(handle);
553 }
554 
reportMediaDrmSessionOpened(const std::vector<uint8_t> & sessionId) const555 void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
556     mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
557     mediametrics_setCString(handle, "scheme", mScheme.c_str());
558     mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
559     mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
560     mediametrics_setInt32(handle, "frontend", mFrontend);
561     mediametrics_setCString(handle, "version", mVersion.c_str());
562     mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
563     const std::lock_guard<std::mutex> lock(mSessionMapMutex);
564     auto it = mSessionMap.find(sessionId);
565     if (it != mSessionMap.end()) {
566         mediametrics_setCString(handle, "session_nonce", it->second.mNonce.c_str());
567         mediametrics_setInt32(handle, "requested_security_level",
568                     DrmPluginSecurityLevelToJavaSecurityLevel(it->second.mTargetSecurityLevel));
569         mediametrics_setInt32(handle, "opened_security_level",
570                     DrmPluginSecurityLevelToJavaSecurityLevel(it->second.mActualSecurityLevel));
571     }
572     mediametrics_selfRecord(handle);
573     mediametrics_delete(handle);
574 }
575 
reportMediaDrmErrored(const DrmStatus & error_code,const char * api,const std::vector<uint8_t> & sessionId) const576 void DrmMetricsLogger::reportMediaDrmErrored(const DrmStatus& error_code, const char* api,
577                                              const std::vector<uint8_t>& sessionId) const {
578     mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
579     mediametrics_setCString(handle, "scheme", mScheme.c_str());
580     mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
581     mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
582     mediametrics_setInt32(handle, "frontend", mFrontend);
583     mediametrics_setCString(handle, "version", mVersion.c_str());
584     mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
585     if (!sessionId.empty()) {
586         const std::lock_guard<std::mutex> lock(mSessionMapMutex);
587         auto it = mSessionMap.find(sessionId);
588         if (it != mSessionMap.end()) {
589             mediametrics_setCString(handle, "session_nonce", it->second.mNonce.c_str());
590             mediametrics_setInt32(handle, "security_level",
591                         DrmPluginSecurityLevelToJavaSecurityLevel(it->second.mActualSecurityLevel));
592         }
593     }
594     mediametrics_setCString(handle, "api", api);
595     mediametrics_setInt32(handle, "error_code", MediaErrorToEnum(error_code));
596     mediametrics_setInt32(handle, "cdm_err", error_code.getCdmErr());
597     mediametrics_setInt32(handle, "oem_err", error_code.getOemErr());
598     mediametrics_setInt32(handle, "error_context", error_code.getContext());
599     mediametrics_selfRecord(handle);
600     mediametrics_delete(handle);
601 }
602 
generateNonce(std::string * out,size_t size,const char * api)603 DrmStatus DrmMetricsLogger::generateNonce(std::string* out, size_t size, const char* api) {
604     std::vector<uint8_t> buf(size);
605     ssize_t bytes = getrandom(buf.data(), size, GRND_NONBLOCK);
606     if (bytes < size) {
607         ALOGE("getrandom failed: %d", errno);
608         reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
609         return ERROR_DRM_RESOURCE_BUSY;
610     }
611     android::AString tmp;
612     encodeBase64(buf.data(), size, &tmp);
613     out->assign(tmp.c_str());
614     return OK;
615 }
616 
617 const std::map<std::array<int64_t, 2>, std::string> DrmMetricsLogger::kUuidSchemeMap {
618         {{(int64_t)0x6DD8B3C345F44A68, (int64_t)0xBF3A64168D01A4A6}, "ABV DRM (MoDRM)"},
619         {{(int64_t)0xF239E769EFA34850, (int64_t)0x9C16A903C6932EFB},
620          "Adobe Primetime DRM version 4"},
621         {{(int64_t)0x616C746963617374, (int64_t)0x2D50726F74656374}, "Alticast"},
622         {{(int64_t)0x94CE86FB07FF4F43, (int64_t)0xADB893D2FA968CA2}, "Apple FairPlay"},
623         {{(int64_t)0x279FE473512C48FE, (int64_t)0xADE8D176FEE6B40F}, "Arris Titanium"},
624         {{(int64_t)0x3D5E6D359B9A41E8, (int64_t)0xB843DD3C6E72C42C}, "ChinaDRM"},
625         {{(int64_t)0x3EA8778F77424BF9, (int64_t)0xB18BE834B2ACBD47}, "Clear Key AES-128"},
626         {{(int64_t)0xBE58615B19C44684, (int64_t)0x88B3C8C57E99E957}, "Clear Key SAMPLE-AES"},
627         {{(int64_t)0xE2719D58A985B3C9, (int64_t)0x781AB030AF78D30E}, "Clear Key DASH-IF"},
628         {{(int64_t)0x644FE7B5260F4FAD, (int64_t)0x949A0762FFB054B4}, "CMLA (OMA DRM)"},
629         {{(int64_t)0x37C332587B994C7E, (int64_t)0xB15D19AF74482154}, "Commscope Titanium V3"},
630         {{(int64_t)0x45D481CB8FE049C0, (int64_t)0xADA9AB2D2455B2F2}, "CoreCrypt"},
631         {{(int64_t)0xDCF4E3E362F15818, (int64_t)0x7BA60A6FE33FF3DD}, "DigiCAP SmartXess"},
632         {{(int64_t)0x35BF197B530E42D7, (int64_t)0x8B651B4BF415070F}, "DivX DRM Series 5"},
633         {{(int64_t)0x80A6BE7E14484C37, (int64_t)0x9E70D5AEBE04C8D2}, "Irdeto Content Protection"},
634         {{(int64_t)0x5E629AF538DA4063, (int64_t)0x897797FFBD9902D4},
635          "Marlin Adaptive Streaming Simple Profile V1.0"},
636         {{(int64_t)0x9A04F07998404286, (int64_t)0xAB92E65BE0885F95}, "Microsoft PlayReady"},
637         {{(int64_t)0x6A99532D869F5922, (int64_t)0x9A91113AB7B1E2F3}, "MobiTV DRM"},
638         {{(int64_t)0xADB41C242DBF4A6D, (int64_t)0x958B4457C0D27B95}, "Nagra MediaAccess PRM 3.0"},
639         {{(int64_t)0x1F83E1E86EE94F0D, (int64_t)0xBA2F5EC4E3ED1A66}, "SecureMedia"},
640         {{(int64_t)0x992C46E6C4374899, (int64_t)0xB6A050FA91AD0E39}, "SecureMedia SteelKnot"},
641         {{(int64_t)0xA68129D3575B4F1A, (int64_t)0x9CBA3223846CF7C3},
642          "Synamedia/Cisco/NDS VideoGuard DRM"},
643         {{(int64_t)0xAA11967FCC014A4A, (int64_t)0x8E99C5D3DDDFEA2D}, "Unitend DRM (UDRM)"},
644         {{(int64_t)0x9A27DD82FDE24725, (int64_t)0x8CBC4234AA06EC09}, "Verimatrix VCAS"},
645         {{(int64_t)0xB4413586C58CFFB0, (int64_t)0x94A5D4896C1AF6C3}, "Viaccess-Orca DRM (VODRM)"},
646         {{(int64_t)0x793B79569F944946, (int64_t)0xA94223E7EF7E44B4}, "VisionCrypt"},
647         {{(int64_t)0x1077EFECC0B24D02, (int64_t)0xACE33C1E52E2FB4B}, "W3C Common PSSH box"},
648         {{(int64_t)0xEDEF8BA979D64ACE, (int64_t)0xA3C827DCD51D21ED}, "Widevine Content Protection"},
649 };
650 
651 }  // namespace android