Loading flags/telecom_callaudioroutestatemachine_flags.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -162,3 +162,14 @@ flag { purpose: PURPOSE_BUGFIX } } # OWNER=pmadapurmath TARGET=25Q2 flag { name: "default_speaker_on_wired_headset_disconnect" namespace: "telecom" description: "Maybe route back into speaker (if it was the previous route) when a wired headset disconnects" bug: "376364368" metadata { purpose: PURPOSE_BUGFIX } } src/com/android/server/telecom/CallAudioRouteController.java +10 −1 Original line number Diff line number Diff line Loading @@ -655,7 +655,16 @@ public class CallAudioRouteController implements CallAudioRouteAdapter { // Route to expected state if (mCurrentRoute.equals(wiredHeadsetRoute)) { routeTo(mIsActive, getBaseRoute(true, null)); // Preserve speaker routing if it was the last audio routing path when the wired headset // disconnects. Ignore this special cased routing when the route isn't active // (in other words, when we're not in a call). AudioRoute route = mFeatureFlags.defaultSpeakerOnWiredHeadsetDisconnect() && mIsActive && mPendingAudioRoute.getOrigRoute() != null && mPendingAudioRoute.getOrigRoute().getType() == TYPE_SPEAKER && mSpeakerDockRoute != null && mSpeakerDockRoute.getType() == AudioRoute.TYPE_SPEAKER ? mSpeakerDockRoute : getBaseRoute(true, null); routeTo(mIsActive, route); } } Loading tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -461,6 +461,28 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { any(CallAudioState.class), eq(expectedState)); } @SmallTest @Test public void testDefaultSpeakerOnWiredHeadsetDisconnect() { when(mFeatureFlags.defaultSpeakerOnWiredHeadsetDisconnect()).thenReturn(true); mController.initialize(); mController.setActive(true); verifyMaybeDefaultSpeakerOnDisconnectWiredHeadset( CallAudioState.ROUTE_SPEAKER /* expectedAudioType */); } @SmallTest @Test public void testIgnoreDefaultSpeakerOnWiredHeadsetDisconnect() { when(mFeatureFlags.defaultSpeakerOnWiredHeadsetDisconnect()).thenReturn(true); // Note here that the routing isn't active to represent that we're not in a call. If a wired // headset is disconnected and the last route was speaker, we shouldn't switch back to // speaker when we're not in a call. mController.initialize(); verifyMaybeDefaultSpeakerOnDisconnectWiredHeadset( CallAudioState.ROUTE_EARPIECE /* expectedAudioType */); } @SmallTest @Test public void testConnectAndDisconnectDock() { Loading Loading @@ -1332,4 +1354,31 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); } private void verifyMaybeDefaultSpeakerOnDisconnectWiredHeadset(int expectedAudioType) { // Ensure audio is routed to speaker initially mController.sendMessageWithSessionInfo(SPEAKER_ON); CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null, new HashSet<>()); verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); // Then simulate wired headset being connected after speaker was initially the audio route mController.sendMessageWithSessionInfo(CONNECT_WIRED_HEADSET); mController.sendMessageWithSessionInfo(SPEAKER_OFF); expectedState = new CallAudioState(false, CallAudioState.ROUTE_WIRED_HEADSET, CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER, null, new HashSet<>()); verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); // Verify that we route back into speaker once the wired headset disconnects mController.sendMessageWithSessionInfo(DISCONNECT_WIRED_HEADSET); expectedState = new CallAudioState(false, expectedAudioType, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null, new HashSet<>()); verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); } } Loading
flags/telecom_callaudioroutestatemachine_flags.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -162,3 +162,14 @@ flag { purpose: PURPOSE_BUGFIX } } # OWNER=pmadapurmath TARGET=25Q2 flag { name: "default_speaker_on_wired_headset_disconnect" namespace: "telecom" description: "Maybe route back into speaker (if it was the previous route) when a wired headset disconnects" bug: "376364368" metadata { purpose: PURPOSE_BUGFIX } }
src/com/android/server/telecom/CallAudioRouteController.java +10 −1 Original line number Diff line number Diff line Loading @@ -655,7 +655,16 @@ public class CallAudioRouteController implements CallAudioRouteAdapter { // Route to expected state if (mCurrentRoute.equals(wiredHeadsetRoute)) { routeTo(mIsActive, getBaseRoute(true, null)); // Preserve speaker routing if it was the last audio routing path when the wired headset // disconnects. Ignore this special cased routing when the route isn't active // (in other words, when we're not in a call). AudioRoute route = mFeatureFlags.defaultSpeakerOnWiredHeadsetDisconnect() && mIsActive && mPendingAudioRoute.getOrigRoute() != null && mPendingAudioRoute.getOrigRoute().getType() == TYPE_SPEAKER && mSpeakerDockRoute != null && mSpeakerDockRoute.getType() == AudioRoute.TYPE_SPEAKER ? mSpeakerDockRoute : getBaseRoute(true, null); routeTo(mIsActive, route); } } Loading
tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -461,6 +461,28 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { any(CallAudioState.class), eq(expectedState)); } @SmallTest @Test public void testDefaultSpeakerOnWiredHeadsetDisconnect() { when(mFeatureFlags.defaultSpeakerOnWiredHeadsetDisconnect()).thenReturn(true); mController.initialize(); mController.setActive(true); verifyMaybeDefaultSpeakerOnDisconnectWiredHeadset( CallAudioState.ROUTE_SPEAKER /* expectedAudioType */); } @SmallTest @Test public void testIgnoreDefaultSpeakerOnWiredHeadsetDisconnect() { when(mFeatureFlags.defaultSpeakerOnWiredHeadsetDisconnect()).thenReturn(true); // Note here that the routing isn't active to represent that we're not in a call. If a wired // headset is disconnected and the last route was speaker, we shouldn't switch back to // speaker when we're not in a call. mController.initialize(); verifyMaybeDefaultSpeakerOnDisconnectWiredHeadset( CallAudioState.ROUTE_EARPIECE /* expectedAudioType */); } @SmallTest @Test public void testConnectAndDisconnectDock() { Loading Loading @@ -1332,4 +1354,31 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); } private void verifyMaybeDefaultSpeakerOnDisconnectWiredHeadset(int expectedAudioType) { // Ensure audio is routed to speaker initially mController.sendMessageWithSessionInfo(SPEAKER_ON); CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null, new HashSet<>()); verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); // Then simulate wired headset being connected after speaker was initially the audio route mController.sendMessageWithSessionInfo(CONNECT_WIRED_HEADSET); mController.sendMessageWithSessionInfo(SPEAKER_OFF); expectedState = new CallAudioState(false, CallAudioState.ROUTE_WIRED_HEADSET, CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER, null, new HashSet<>()); verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); // Verify that we route back into speaker once the wired headset disconnects mController.sendMessageWithSessionInfo(DISCONNECT_WIRED_HEADSET); expectedState = new CallAudioState(false, expectedAudioType, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null, new HashSet<>()); verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); } }