diff options
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.java | 119 |
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(""); + } +} + |