summaryrefslogtreecommitdiff
path: root/Settings/src/com/android/tv/settings/system/development/audio/AudioMetrics.java
diff options
context:
space:
mode:
Diffstat (limited to 'Settings/src/com/android/tv/settings/system/development/audio/AudioMetrics.java')
-rw-r--r--Settings/src/com/android/tv/settings/system/development/audio/AudioMetrics.java119
1 files changed, 119 insertions, 0 deletions
diff --git a/Settings/src/com/android/tv/settings/system/development/audio/AudioMetrics.java b/Settings/src/com/android/tv/settings/system/development/audio/AudioMetrics.java
new file mode 100644
index 000000000..28dc59052
--- /dev/null
+++ b/Settings/src/com/android/tv/settings/system/development/audio/AudioMetrics.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.settings.system.development.audio;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import java.util.Optional;
+
+/** Stores audio recording metrics. Sends metrics updates through a callback. */
+public class AudioMetrics {
+
+ private static final String TAG = "AudioMetrics";
+
+ private Optional<Long> mStartTs = Optional.empty();
+
+ private Data mData = new Data();
+
+ private final UpdateMetricsCallback mCallback;
+
+ /** Contains data to be exposed via the callback. */
+ public static class Data {
+
+ public Optional<Long> timeToStartReadMs = Optional.empty();
+ public Optional<Long> timeToValidAudioMs = Optional.empty();
+ public Optional<Long> emptyAudioDurationMs = Optional.empty();
+
+ public Data() {
+ }
+
+ public Data(Data data) {
+ this.timeToStartReadMs = data.timeToStartReadMs;
+ this.timeToValidAudioMs = data.timeToValidAudioMs;
+ this.emptyAudioDurationMs = data.emptyAudioDurationMs;
+ }
+ }
+
+ /** Interface for receiving metrics updates. */
+ public interface UpdateMetricsCallback {
+ /** Callback for receiving metrics updates. */
+ void onUpdateMetrics(AudioMetrics.Data data);
+ }
+
+ /**
+ * @param callback Callback for updates.
+ */
+ public AudioMetrics(UpdateMetricsCallback callback) {
+ this.mCallback = callback;
+ }
+
+ /** Records the beginning of the audio recording process. */
+ public void start() {
+ mData = new Data();
+ mStartTs = Optional.of(System.currentTimeMillis());
+ updateMetrics();
+ }
+
+ /** Records that we have started monitoring a buffer for incoming audio data. */
+ public void startedReading() throws IllegalStateException {
+ long startTs = this.mStartTs
+ .orElseThrow(() -> new IllegalStateException(
+ "Started reading before recording started"));
+ long currentTs = System.currentTimeMillis();
+ mData = new Data(mData);
+ mData.timeToStartReadMs = Optional.of(currentTs - startTs);
+ updateMetrics();
+ }
+
+ /** Records that we have started receiving non-zero audio data */
+ public void receivedValidAudio() throws IllegalStateException {
+ long startTs = this.mStartTs
+ .orElseThrow(() -> new IllegalStateException(
+ "Received audio data before recording started"));
+ long currentTs = System.currentTimeMillis();
+ mData = new Data(mData);
+ mData.timeToValidAudioMs = Optional.of(currentTs - startTs);
+ updateMetrics();
+ }
+
+ /** Records the duration of empty audio received before valid audio */
+ public void setEmptyAudioDurationMs(long emptyAudioMs) {
+ mData = new Data(mData);
+ mData.emptyAudioDurationMs = Optional.of(emptyAudioMs);
+ updateMetrics();
+ }
+
+ /** Sends updated data through the callback */
+ private void updateMetrics() {
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+ mainHandler.post(() -> mCallback.onUpdateMetrics(mData));
+ Log.i(TAG, String.format("Time to start reading: %s",
+ msTimestampToString(mData.timeToStartReadMs)));
+ Log.i(TAG, String.format("Time to valid audio data: %s",
+ msTimestampToString(mData.timeToValidAudioMs)));
+ Log.i(TAG, String.format("Empty audio duration: %s",
+ msTimestampToString(mData.emptyAudioDurationMs)));
+ }
+
+ /** Converts a possible timestamp in milliseconds to its string representation. */
+ public static String msTimestampToString(Optional<Long> optL) {
+ return optL.map((Long l) -> String.format("%s ms", l)).orElse("");
+ }
+}
+