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
Merged-In: Idb22ce6714fa240b2b4b3b8637b16d3a51228fa1
Change-Id: Idb22ce6714fa240b2b4b3b8637b16d3a51228fa1
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 2c40fbb..19d1d1a 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1075,6 +1075,40 @@
     return mOriginalSampleRate;
 }
 
+status_t AudioTrack::setDualMonoMode(audio_dual_mono_mode_t mode)
+{
+    AutoMutex lock(mLock);
+    return setDualMonoMode_l(mode);
+}
+
+status_t AudioTrack::setDualMonoMode_l(audio_dual_mono_mode_t mode)
+{
+    return mAudioTrack->setDualMonoMode(mode);
+}
+
+status_t AudioTrack::getDualMonoMode(audio_dual_mono_mode_t* mode) const
+{
+    AutoMutex lock(mLock);
+    return mAudioTrack->getDualMonoMode(mode);
+}
+
+status_t AudioTrack::setAudioDescriptionMixLevel(float leveldB)
+{
+    AutoMutex lock(mLock);
+    return setAudioDescriptionMixLevel_l(leveldB);
+}
+
+status_t AudioTrack::setAudioDescriptionMixLevel_l(float leveldB)
+{
+    return mAudioTrack->setAudioDescriptionMixLevel(leveldB);
+}
+
+status_t AudioTrack::getAudioDescriptionMixLevel(float* leveldB) const
+{
+    AutoMutex lock(mLock);
+    return mAudioTrack->getAudioDescriptionMixLevel(leveldB);
+}
+
 status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
 {
     AutoMutex lock(mLock);
@@ -1082,7 +1116,11 @@
         return NO_ERROR;
     }
     if (isOffloadedOrDirect_l()) {
-        return INVALID_OPERATION;
+        status_t status = mAudioTrack->setPlaybackRateParameters(playbackRate);
+        if (status == NO_ERROR) {
+            mPlaybackRate = playbackRate;
+        }
+        return status;
     }
     if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
         return INVALID_OPERATION;
@@ -1147,9 +1185,16 @@
     return NO_ERROR;
 }
 
-const AudioPlaybackRate& AudioTrack::getPlaybackRate() const
+const AudioPlaybackRate& AudioTrack::getPlaybackRate()
 {
     AutoMutex lock(mLock);
+    if (isOffloadedOrDirect_l()) {
+        audio_playback_rate_t playbackRateTemp;
+        const status_t status = mAudioTrack->getPlaybackRateParameters(&playbackRateTemp);
+        if (status == NO_ERROR) { // update local version if changed.
+            mPlaybackRate = playbackRateTemp;
+        }
+    }
     return mPlaybackRate;
 }
 
@@ -1745,6 +1790,13 @@
     mProxy->setPlaybackRate(playbackRateTemp);
     mProxy->setMinimum(mNotificationFramesAct);
 
+    if (mDualMonoMode != AUDIO_DUAL_MONO_MODE_OFF) {
+        setDualMonoMode_l(mDualMonoMode);
+    }
+    if (mAudioDescriptionMixLeveldB != -std::numeric_limits<float>::infinity()) {
+        setAudioDescriptionMixLevel_l(mAudioDescriptionMixLeveldB);
+    }
+
     mDeathNotifier = new DeathNotifier(this);
     IInterface::asBinder(mAudioTrack)->linkToDeath(mDeathNotifier, this);