1 /*
2  * Copyright 2020, 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 #include <jni.h>
18 #include <media/MediaMetrics.h>
19 
20 #define JNI_FUNCTION(RETURN_TYPE, NAME, ...)                                               \
21     extern "C" {                                                                           \
22     JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \
23                                                                 ##__VA_ARGS__);            \
24     }                                                                                      \
25     JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \
26                                                                 ##__VA_ARGS__)
27 
28 namespace {
29 
30 constexpr char kMediaMetricsKey[] = "mediaparser";
31 
32 constexpr char kAttributeLogSessionId[] = "android.media.mediaparser.logSessionId";
33 constexpr char kAttributeParserName[] = "android.media.mediaparser.parserName";
34 constexpr char kAttributeCreatedByName[] = "android.media.mediaparser.createdByName";
35 constexpr char kAttributeParserPool[] = "android.media.mediaparser.parserPool";
36 constexpr char kAttributeLastException[] = "android.media.mediaparser.lastException";
37 constexpr char kAttributeResourceByteCount[] = "android.media.mediaparser.resourceByteCount";
38 constexpr char kAttributeDurationMillis[] = "android.media.mediaparser.durationMillis";
39 constexpr char kAttributeTrackMimeTypes[] = "android.media.mediaparser.trackMimeTypes";
40 constexpr char kAttributeTrackCodecs[] = "android.media.mediaparser.trackCodecs";
41 constexpr char kAttributeAlteredParameters[] = "android.media.mediaparser.alteredParameters";
42 constexpr char kAttributeVideoWidth[] = "android.media.mediaparser.videoWidth";
43 constexpr char kAttributeVideoHeight[] = "android.media.mediaparser.videoHeight";
44 
45 // Util class to handle string resource management.
46 class JstringHandle {
47 public:
JstringHandle(JNIEnv * env,jstring value)48     JstringHandle(JNIEnv* env, jstring value) : mEnv(env), mJstringValue(value) {
49         mCstringValue = env->GetStringUTFChars(value, /* isCopy= */ nullptr);
50     }
51 
~JstringHandle()52     ~JstringHandle() {
53         if (mCstringValue != nullptr) {
54             mEnv->ReleaseStringUTFChars(mJstringValue, mCstringValue);
55         }
56     }
57 
value() const58     [[nodiscard]] const char* value() const {
59         return mCstringValue != nullptr ? mCstringValue : "";
60     }
61 
62     JNIEnv* mEnv;
63     jstring mJstringValue;
64     const char* mCstringValue;
65 };
66 
67 } // namespace
68 
JNI_FUNCTION(void,nativeSubmitMetrics,jstring logSessionIdJstring,jstring parserNameJstring,jboolean createdByName,jstring parserPoolJstring,jstring lastExceptionJstring,jlong resourceByteCount,jlong durationMillis,jstring trackMimeTypesJstring,jstring trackCodecsJstring,jstring alteredParameters,jint videoWidth,jint videoHeight)69 JNI_FUNCTION(void, nativeSubmitMetrics, jstring logSessionIdJstring, jstring parserNameJstring,
70              jboolean createdByName, jstring parserPoolJstring, jstring lastExceptionJstring,
71              jlong resourceByteCount, jlong durationMillis, jstring trackMimeTypesJstring,
72              jstring trackCodecsJstring, jstring alteredParameters, jint videoWidth,
73              jint videoHeight) {
74     mediametrics_handle_t item(mediametrics_create(kMediaMetricsKey));
75     mediametrics_setCString(item, kAttributeLogSessionId,
76                             JstringHandle(env, logSessionIdJstring).value());
77     mediametrics_setCString(item, kAttributeParserName,
78                             JstringHandle(env, parserNameJstring).value());
79     mediametrics_setInt32(item, kAttributeCreatedByName, createdByName ? 1 : 0);
80     mediametrics_setCString(item, kAttributeParserPool,
81                             JstringHandle(env, parserPoolJstring).value());
82     mediametrics_setCString(item, kAttributeLastException,
83                             JstringHandle(env, lastExceptionJstring).value());
84     mediametrics_setInt64(item, kAttributeResourceByteCount, resourceByteCount);
85     mediametrics_setInt64(item, kAttributeDurationMillis, durationMillis);
86     mediametrics_setCString(item, kAttributeTrackMimeTypes,
87                             JstringHandle(env, trackMimeTypesJstring).value());
88     mediametrics_setCString(item, kAttributeTrackCodecs,
89                             JstringHandle(env, trackCodecsJstring).value());
90     mediametrics_setCString(item, kAttributeAlteredParameters,
91                             JstringHandle(env, alteredParameters).value());
92     mediametrics_setInt32(item, kAttributeVideoWidth, videoWidth);
93     mediametrics_setInt32(item, kAttributeVideoHeight, videoHeight);
94     mediametrics_selfRecord(item);
95     mediametrics_delete(item);
96 }
97