Snap for 12664851 from 6d5a6a84c3b28a46379589fdda77896004def277 to 25Q1-release

Change-Id: I882a0f38b7d34fa87ecfbabed302dfb86a2d6f3f
diff --git a/src/com/android/server/telecom/CallAudioRouteController.java b/src/com/android/server/telecom/CallAudioRouteController.java
index 7358be8..98adae9 100644
--- a/src/com/android/server/telecom/CallAudioRouteController.java
+++ b/src/com/android/server/telecom/CallAudioRouteController.java
@@ -879,24 +879,22 @@
         mFocusType = focus;
         switch (focus) {
             case NO_FOCUS -> {
-                if (mIsActive) {
-                    // Notify the CallAudioModeStateMachine that audio operations are complete so
-                    // that we can relinquish audio focus.
-                    mCallAudioManager.notifyAudioOperationsComplete();
-
-                    // Reset mute state after call ends.
-                    handleMuteChanged(false);
-                    // Ensure we reset call audio state at the end of the call (i.e. if we're on
-                    // speaker, route back to earpiece). If we're on BT, remain on BT if it's still
-                    // connected.
-                    AudioRoute route = mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()
-                            ? calculateBaselineRoute(false, true, null)
-                            : mCurrentRoute;
-                    routeTo(false, route);
-                    // Clear pending messages
-                    mPendingAudioRoute.clearPendingMessages();
-                    clearRingingBluetoothAddress();
-                }
+                // Notify the CallAudioModeStateMachine that audio operations are complete so
+                // that we can relinquish audio focus.
+                mCallAudioManager.notifyAudioOperationsComplete();
+                // Reset mute state after call ends. This should remain unaffected if audio routing
+                // never went active.
+                handleMuteChanged(false);
+                // Ensure we reset call audio state at the end of the call (i.e. if we're on
+                // speaker, route back to earpiece). If we're on BT, remain on BT if it's still
+                // connected.
+                AudioRoute route = mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()
+                        ? calculateBaselineRoute(false, true, null)
+                        : mCurrentRoute;
+                routeTo(false, route);
+                // Clear pending messages
+                mPendingAudioRoute.clearPendingMessages();
+                clearRingingBluetoothAddress();
             }
             case ACTIVE_FOCUS -> {
                 // Route to active baseline route (we may need to change audio route in the case
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 7ec2687..a662dde 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -892,8 +892,7 @@
                                             PhoneAccount.CAPABILITY_CONNECTION_MANAGER) ||
                                     account.hasCapabilities(
                                             PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
-                                throw new SecurityException("Self-managed ConnectionServices and "
-                                        + "transactional voip apps "
+                                throw new SecurityException("Self-managed ConnectionServices "
                                         + "cannot also be call capable, connection managers, or "
                                         + "SIM accounts.");
                             }
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java
index 330e84c..ba48c64 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java
@@ -1099,6 +1099,38 @@
                 any(CallAudioState.class), eq(expectedState));
     }
 
+    @Test
+    @SmallTest
+    public void testAbandonCallAudioFocusAfterCallEnd() {
+        // Make sure in-band ringing is disabled so that route never becomes active
+        when(mBluetoothRouteManager.isInbandRingEnabled(eq(BLUETOOTH_DEVICE_1))).thenReturn(false);
+
+        mController.initialize();
+        mController.sendMessageWithSessionInfo(BT_DEVICE_ADDED, AudioRoute.TYPE_BLUETOOTH_SCO,
+                BLUETOOTH_DEVICE_1);
+
+        CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
+                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH
+                        | CallAudioState.ROUTE_SPEAKER, BLUETOOTH_DEVICE_1, BLUETOOTH_DEVICES);
+        mController.sendMessageWithSessionInfo(BT_ACTIVE_DEVICE_PRESENT,
+                AudioRoute.TYPE_BLUETOOTH_SCO, BT_ADDRESS_1);
+        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
+                any(CallAudioState.class), eq(expectedState));
+        assertFalse(mController.isActive());
+
+        // Verify route never went active due to in-band ringing being disabled.
+        mController.sendMessageWithSessionInfo(SWITCH_FOCUS, RINGING_FOCUS, 0);
+        assertFalse(mController.isActive());
+
+        // Emulate scenario of rejecting an incoming call so that call focus is lost and verify
+        // that we abandon the call audio focus that was gained from when the call went to
+        // ringing state.
+        mController.sendMessageWithSessionInfo(SWITCH_FOCUS, NO_FOCUS, 0);
+        // Ensure we tell the CallAudioManager that audio operations are done so that we can ensure
+        // audio focus is relinquished.
+        verify(mCallAudioManager, timeout(TEST_TIMEOUT)).notifyAudioOperationsComplete();
+    }
+
     private void verifyConnectBluetoothDevice(int audioType) {
         mController.initialize();
         mController.setActive(true);