audio: add implementation for TV related API

1. TunerConfiguration.
2. AudioDescriptionMixLevel getter/setter.
3. DualMonoMode getter/setter.
4. PlaybackRate getter/setter.

Test: TIS player with instrumented HAL
Test: atest AudioTrackTest#testTunerConfiguration
Test: atest AudioTrackTest#testDualMonoMode
Test: atest AudioTrackTest#testAudioDescriptionMixLevel
Test: atest AudioManagerTest#testGetAdditionalOutputDeviceDelay
Bug: 173482792
Change-Id: Idb22ce6714fa240b2b4b3b8637b16d3a51228fa1
diff --git a/media/libmediahelper/AudioParameter.cpp b/media/libmediahelper/AudioParameter.cpp
index fc8306c..382a920 100644
--- a/media/libmediahelper/AudioParameter.cpp
+++ b/media/libmediahelper/AudioParameter.cpp
@@ -57,6 +57,10 @@
 //        AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES;
 // const char * const AudioParameter::keyDeviceSupportedEncapsulationMetadataTypes =
 //        AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES;
+const char * const AudioParameter::keyAdditionalOutputDeviceDelay =
+        AUDIO_PARAMETER_DEVICE_ADDITIONAL_OUTPUT_DELAY;
+const char * const AudioParameter::keyMaxAdditionalOutputDeviceDelay =
+        AUDIO_PARAMETER_DEVICE_MAX_ADDITIONAL_OUTPUT_DELAY;
 
 AudioParameter::AudioParameter(const String8& keyValuePairs)
 {
diff --git a/media/libmediahelper/AudioValidator.cpp b/media/libmediahelper/AudioValidator.cpp
index e2fd8ae..7eddbe1 100644
--- a/media/libmediahelper/AudioValidator.cpp
+++ b/media/libmediahelper/AudioValidator.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <media/AudioValidator.h>
+#include <cmath>
 
 namespace android {
 
@@ -121,4 +122,62 @@
     return safetyNetLog(status, bugNumber);
 }
 
+/* static */
+status_t AudioValidator::validateAudioDescriptionMixLevel(float leveldB)
+{
+    constexpr float MAX_AUDIO_DESCRIPTION_MIX_LEVEL = 48.f;
+    return std::isnan(leveldB) || leveldB > MAX_AUDIO_DESCRIPTION_MIX_LEVEL ? BAD_VALUE : OK;
+}
+
+/* static */
+status_t AudioValidator::validateDualMonoMode(audio_dual_mono_mode_t dualMonoMode)
+{
+    switch (dualMonoMode) {
+        case AUDIO_DUAL_MONO_MODE_OFF:
+        case AUDIO_DUAL_MONO_MODE_LR:
+        case AUDIO_DUAL_MONO_MODE_LL:
+        case AUDIO_DUAL_MONO_MODE_RR:
+        return OK;
+    }
+    return BAD_VALUE;
+}
+
+/* static */
+status_t AudioValidator::validatePlaybackRateFallbackMode(
+        audio_timestretch_fallback_mode_t fallbackMode)
+{
+    switch (fallbackMode) {
+        case AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT:
+            // This is coarse sounding timestretching used for internal debugging,
+            // not intended for general use.
+            break; // warning if not listed.
+        case AUDIO_TIMESTRETCH_FALLBACK_DEFAULT:
+        case AUDIO_TIMESTRETCH_FALLBACK_MUTE:
+        case AUDIO_TIMESTRETCH_FALLBACK_FAIL:
+            return OK;
+    }
+    return BAD_VALUE;
+}
+
+/* static */
+status_t AudioValidator::validatePlaybackRateStretchMode(
+        audio_timestretch_stretch_mode_t stretchMode)
+{
+    switch (stretchMode) {
+        case AUDIO_TIMESTRETCH_STRETCH_DEFAULT:
+        case AUDIO_TIMESTRETCH_STRETCH_VOICE:
+            return OK;
+    }
+    return BAD_VALUE;
+}
+
+/* static */
+status_t AudioValidator::validatePlaybackRate(
+        const audio_playback_rate_t& playbackRate)
+{
+    if (playbackRate.mSpeed < 0.f || playbackRate.mPitch < 0.f) return BAD_VALUE;
+    return validatePlaybackRateFallbackMode(playbackRate.mFallbackMode) ?:
+            validatePlaybackRateStretchMode(playbackRate.mStretchMode);
+}
+
 }; // namespace android
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 66d8dfb..9a6ca8a 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -104,6 +104,9 @@
     // static const char * const keyDeviceSupportedEncapsulationModes;
     // static const char * const keyDeviceSupportedEncapsulationMetadataTypes;
 
+    static const char * const keyAdditionalOutputDeviceDelay;
+    static const char * const keyMaxAdditionalOutputDeviceDelay;
+
     String8 toString() const { return toStringImpl(true); }
     String8 keysToString() const { return toStringImpl(false); }
 
diff --git a/media/libmediahelper/include/media/AudioValidator.h b/media/libmediahelper/include/media/AudioValidator.h
index 008868e..56c2fa6 100644
--- a/media/libmediahelper/include/media/AudioValidator.h
+++ b/media/libmediahelper/include/media/AudioValidator.h
@@ -65,7 +65,7 @@
      * Otherwise, return BAD_VALUE.
      */
     static status_t validateAudioPort(
-            const struct audio_port_v7& port, std::string_view ugNumber = {});
+            const struct audio_port_v7& port, std::string_view bugNumber = {});
 
     /**
      * Return NO_ERROR only when there is no error with the given audio patch.
@@ -73,6 +73,36 @@
      */
     static status_t validateAudioPatch(
             const struct audio_patch& patch, std::string_view bugNumber = {});
+
+    /**
+     * Return NO_ERROR if leveldB is acceptable, otherwise BAD_VALUE.
+     */
+    static status_t validateAudioDescriptionMixLevel(float leveldB);
+
+    /**
+     * Return NO_ERROR if dualMonoMode is one of the enum values, otherwise BAD_VALUE.
+     */
+    static status_t validateDualMonoMode(audio_dual_mono_mode_t dualMonoMode);
+
+    /**
+     * Return NO_ERROR if fallbackMode is one of the enum values, otherwise BAD_VALUE.
+     */
+    static status_t validatePlaybackRateFallbackMode(
+            audio_timestretch_fallback_mode_t fallbackMode);
+
+    /**
+     * Return NO_ERROR if fallbackMode is one of the enum values, otherwise BAD_VALUE.
+     */
+    static status_t validatePlaybackRateStretchMode(audio_timestretch_stretch_mode_t stretchMode);
+
+    /**
+     * Return NO_ERROR if playbackRate is acceptable - the enums are correct and the
+     * rate and speed non-negative, otherwise BAD_VALUE.
+     *
+     * This is a basic bounds check - the system might have stricter requirements for
+     * playbackRate on a particular stream / device.
+     */
+    static status_t validatePlaybackRate(const audio_playback_rate_t& playbackRate);
 };
 
 }; // namespace android