Update internal audio state before updating ICS.

In the case that an ICS is bound during a system audio update (for
instance, when entering a new audio route), it's possible for that ICS
to receive an incorrect audio state because the internal call audio
state hasn't been updated yet. InCallController#onConnected will
retrieve the current call audio state from CallAudioRouteStateMachine to
send an audio update to the ICS.

By updating the internal call audio state beforehand, we will ensure
that the ICS receives the updated call state. This handles 3 different
scenarios depending on when the ICS is bound:

(1) ICS bound before internal audio update.
(2) ICS bound after internal audio update and before system audio update
(which sends audio update to ICS and CS).
(3) ICS bound after system audio update.

Bug: 335538831
Test: atest CallAudioRouteControllerTest (with flag enabled locally in
setUp)
Test: atest CallAudioRouteTransitionTests (with flag enabled locally in
setUp)

Change-Id: I610106f96a3d4283979fe8e682513e69dfb84fac
diff --git a/flags/telecom_callaudioroutestatemachine_flags.aconfig b/flags/telecom_callaudioroutestatemachine_flags.aconfig
index 6cca8f9..33bccba 100644
--- a/flags/telecom_callaudioroutestatemachine_flags.aconfig
+++ b/flags/telecom_callaudioroutestatemachine_flags.aconfig
@@ -88,3 +88,14 @@
   description: "Update switching bt devices based on arbitrary device chosen if no device is specified."
   bug: "333751408"
 }
+
+# OWNER=pmadapurmath TARGET=24Q3
+flag {
+  name: "early_update_internal_call_audio_state"
+  namespace: "telecom"
+  description: "Update internal call audio state before sending updated state to ICS"
+  bug: "335538831"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 04dae5f..74d23a9 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -288,8 +288,13 @@
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE,
                     mAvailableRoutes, null,
                     mBluetoothRouteManager.getConnectedDevices());
-            setSystemAudioState(newState, true);
-            updateInternalCallAudioState();
+            if (mFeatureFlags.earlyUpdateInternalCallAudioState()) {
+                updateInternalCallAudioState();
+                setSystemAudioState(newState, true);
+            } else {
+                setSystemAudioState(newState, true);
+                updateInternalCallAudioState();
+            }
         }
 
         @Override
@@ -511,8 +516,13 @@
             }
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_WIRED_HEADSET,
                     mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
-            setSystemAudioState(newState, true);
-            updateInternalCallAudioState();
+            if (mFeatureFlags.earlyUpdateInternalCallAudioState()) {
+                updateInternalCallAudioState();
+                setSystemAudioState(newState, true);
+            } else {
+                setSystemAudioState(newState, true);
+                updateInternalCallAudioState();
+            }
         }
 
         @Override
@@ -749,8 +759,13 @@
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_BLUETOOTH,
                     mAvailableRoutes, mBluetoothRouteManager.getBluetoothAudioConnectedDevice(),
                     mBluetoothRouteManager.getConnectedDevices());
-            setSystemAudioState(newState, true);
-            updateInternalCallAudioState();
+            if (mFeatureFlags.earlyUpdateInternalCallAudioState()) {
+                updateInternalCallAudioState();
+                setSystemAudioState(newState, true);
+            } else {
+                setSystemAudioState(newState, true);
+                updateInternalCallAudioState();
+            }
             // Do not send RINGER_MODE_CHANGE if no Bluetooth SCO audio device is available
             if (mBluetoothRouteManager.getBluetoothAudioConnectedDevice() != null) {
                 mCallAudioManager.onRingerModeChange();
@@ -898,8 +913,13 @@
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_BLUETOOTH,
                     mAvailableRoutes, mBluetoothRouteManager.getBluetoothAudioConnectedDevice(),
                     mBluetoothRouteManager.getConnectedDevices());
-            setSystemAudioState(newState);
-            updateInternalCallAudioState();
+            if (mFeatureFlags.earlyUpdateInternalCallAudioState()) {
+                updateInternalCallAudioState();
+                setSystemAudioState(newState, true);
+            } else {
+                setSystemAudioState(newState, true);
+                updateInternalCallAudioState();
+            }
         }
 
         @Override
@@ -1122,8 +1142,13 @@
             mWasOnSpeaker = true;
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER,
                     mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
-            setSystemAudioState(newState, true);
-            updateInternalCallAudioState();
+            if (mFeatureFlags.earlyUpdateInternalCallAudioState()) {
+                updateInternalCallAudioState();
+                setSystemAudioState(newState, true);
+            } else {
+                setSystemAudioState(newState, true);
+                updateInternalCallAudioState();
+            }
         }
 
         @Override