Loading src/com/android/server/telecom/CallAudioManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,11 @@ public class CallAudioManager extends CallsManagerListenerBase { CallAudioRouteStateMachine.SWITCH_FOCUS, focusState); } public void notifyAudioOperationsComplete() { mCallAudioModeStateMachine.sendMessageWithArgs( CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE, makeArgsForModeStateMachine()); } @VisibleForTesting public CallAudioRouteStateMachine getCallAudioRouteStateMachine() { return mCallAudioRouteStateMachine; Loading src/com/android/server/telecom/CallAudioModeStateMachine.java +34 −8 Original line number Diff line number Diff line Loading @@ -151,6 +151,10 @@ public class CallAudioModeStateMachine extends StateMachine { public static final int RINGER_MODE_CHANGE = 5001; // Used to indicate that Telecom is done doing things to the AudioManager and that it's safe // to release focus for other apps to take over. public static final int AUDIO_OPERATIONS_COMPLETE = 6001; public static final int RUN_RUNNABLE = 9001; private static final SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{ Loading @@ -172,6 +176,7 @@ public class CallAudioModeStateMachine extends StateMachine { put(TONE_STOPPED_PLAYING, "TONE_STOPPED_PLAYING"); put(FOREGROUND_VOIP_MODE_CHANGE, "FOREGROUND_VOIP_MODE_CHANGE"); put(RINGER_MODE_CHANGE, "RINGER_MODE_CHANGE"); put(AUDIO_OPERATIONS_COMPLETE, "AUDIO_OPERATIONS_COMPLETE"); put(RUN_RUNNABLE, "RUN_RUNNABLE"); }}; Loading Loading @@ -223,12 +228,11 @@ public class CallAudioModeStateMachine extends StateMachine { @Override public void enter() { if (mIsInitialized) { Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED"); mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); mAudioManager.setMode(AudioManager.MODE_NORMAL); mAudioManager.abandonAudioFocusForCall(); mMostRecentMode = AudioManager.MODE_NORMAL; mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); // Don't release focus here -- wait until we get a signal that any other audio // operations triggered by this are done before releasing focus. } } Loading Loading @@ -272,6 +276,10 @@ public class CallAudioModeStateMachine extends StateMachine { Log.w(LOG_TAG, "Tone started playing unexpectedly. Args are: \n" + args.toString()); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED"); mAudioManager.abandonAudioFocusForCall(); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading @@ -283,12 +291,9 @@ public class CallAudioModeStateMachine extends StateMachine { @Override public void enter() { if (mIsInitialized) { Log.i(LOG_TAG, "Abandoning audio focus: now audio processing"); mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); mAudioManager.setMode(NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING); mAudioManager.abandonAudioFocusForCall(); mMostRecentMode = NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING; mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); } } Loading Loading @@ -336,6 +341,10 @@ public class CallAudioModeStateMachine extends StateMachine { Log.w(LOG_TAG, "Tone started playing unexpectedly. Args are: \n" + args.toString()); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now AUDIO_PROCESSING"); mAudioManager.abandonAudioFocusForCall(); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -416,6 +425,10 @@ public class CallAudioModeStateMachine extends StateMachine { tryStartRinging(); return HANDLED; } case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -493,6 +506,10 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(mVoipCallFocusState); } return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -563,6 +580,10 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(mSimCallFocusState); } return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -625,6 +646,11 @@ public class CallAudioModeStateMachine extends StateMachine { return HANDLED; case TONE_STOPPED_PLAYING: transitionTo(calculateProperStateFromArgs(args)); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: return NOT_HANDLED; } Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +5 −0 Original line number Diff line number Diff line Loading @@ -419,6 +419,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } return HANDLED; default: Loading Loading @@ -616,6 +617,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } return HANDLED; default: Loading Loading @@ -861,6 +863,7 @@ public class CallAudioRouteStateMachine extends StateMachine { // Only disconnect SCO audio here instead of routing away from BT entirely. mBluetoothRouteManager.disconnectSco(); reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } else if (msg.arg1 == RINGING_FOCUS && !mBluetoothRouteManager.isInbandRingingEnabled()) { setBluetoothOff(); Loading Loading @@ -952,6 +955,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } else if (msg.arg1 == ACTIVE_FOCUS) { setBluetoothOn(null); } Loading Loading @@ -1175,6 +1179,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } return HANDLED; default: Loading tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java +46 −0 Original line number Diff line number Diff line Loading @@ -140,6 +140,12 @@ public class CallAudioModeTransitionTests extends TelecomTestCase { sm.sendMessage(mParams.messageType, mParams.externalState); waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT); if (mParams.expectedFocus == FOCUS_OFF && mParams.messageType != CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE) { // If we expect the focus to turn off, we need to signal operations complete first sm.sendMessage(CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE); waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT); } assertEquals(mParams.expectedFinalStateName, sm.getCurrentStateName()); Loading Loading @@ -856,6 +862,46 @@ public class CallAudioModeTransitionTests extends TelecomTestCase { NO_CHANGE // expectedCallWaitingInteraction )); result.add(new ModeTestParameters( "No change to focus without signaling audio ops complete", CallAudioModeStateMachine.ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, // initialAudioS CallAudioModeStateMachine.TONE_STOPPED_PLAYING, // messageType new MessageArgs.Builder() .setHasActiveOrDialingCalls(false) .setHasRingingCalls(false) .setHasHoldingCalls(false) .setHasAudioProcessingCalls(false) .setIsTonePlaying(false) .setForegroundCallIsVoip(false) .setSession(null) .build(), CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName FOCUS_NO_CHANGE, // expectedFocus AudioManager.MODE_NORMAL, // expectedMode NO_CHANGE, // expectedRingingInteraction NO_CHANGE // expectedCallWaitingInteraction )); result.add(new ModeTestParameters( "Abandon focus once audio ops are complete", CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING, // initialAudioS CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE, // messageType new MessageArgs.Builder() .setHasActiveOrDialingCalls(false) .setHasRingingCalls(false) .setHasHoldingCalls(false) .setHasAudioProcessingCalls(false) .setIsTonePlaying(false) .setForegroundCallIsVoip(false) .setSession(null) .build(), CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName FOCUS_OFF, // expectedFocus NO_CHANGE, // expectedMode NO_CHANGE, // expectedRingingInteraction NO_CHANGE // expectedCallWaitingInteraction )); return result; } Loading Loading
src/com/android/server/telecom/CallAudioManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,11 @@ public class CallAudioManager extends CallsManagerListenerBase { CallAudioRouteStateMachine.SWITCH_FOCUS, focusState); } public void notifyAudioOperationsComplete() { mCallAudioModeStateMachine.sendMessageWithArgs( CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE, makeArgsForModeStateMachine()); } @VisibleForTesting public CallAudioRouteStateMachine getCallAudioRouteStateMachine() { return mCallAudioRouteStateMachine; Loading
src/com/android/server/telecom/CallAudioModeStateMachine.java +34 −8 Original line number Diff line number Diff line Loading @@ -151,6 +151,10 @@ public class CallAudioModeStateMachine extends StateMachine { public static final int RINGER_MODE_CHANGE = 5001; // Used to indicate that Telecom is done doing things to the AudioManager and that it's safe // to release focus for other apps to take over. public static final int AUDIO_OPERATIONS_COMPLETE = 6001; public static final int RUN_RUNNABLE = 9001; private static final SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{ Loading @@ -172,6 +176,7 @@ public class CallAudioModeStateMachine extends StateMachine { put(TONE_STOPPED_PLAYING, "TONE_STOPPED_PLAYING"); put(FOREGROUND_VOIP_MODE_CHANGE, "FOREGROUND_VOIP_MODE_CHANGE"); put(RINGER_MODE_CHANGE, "RINGER_MODE_CHANGE"); put(AUDIO_OPERATIONS_COMPLETE, "AUDIO_OPERATIONS_COMPLETE"); put(RUN_RUNNABLE, "RUN_RUNNABLE"); }}; Loading Loading @@ -223,12 +228,11 @@ public class CallAudioModeStateMachine extends StateMachine { @Override public void enter() { if (mIsInitialized) { Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED"); mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); mAudioManager.setMode(AudioManager.MODE_NORMAL); mAudioManager.abandonAudioFocusForCall(); mMostRecentMode = AudioManager.MODE_NORMAL; mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); // Don't release focus here -- wait until we get a signal that any other audio // operations triggered by this are done before releasing focus. } } Loading Loading @@ -272,6 +276,10 @@ public class CallAudioModeStateMachine extends StateMachine { Log.w(LOG_TAG, "Tone started playing unexpectedly. Args are: \n" + args.toString()); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED"); mAudioManager.abandonAudioFocusForCall(); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading @@ -283,12 +291,9 @@ public class CallAudioModeStateMachine extends StateMachine { @Override public void enter() { if (mIsInitialized) { Log.i(LOG_TAG, "Abandoning audio focus: now audio processing"); mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); mAudioManager.setMode(NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING); mAudioManager.abandonAudioFocusForCall(); mMostRecentMode = NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING; mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); } } Loading Loading @@ -336,6 +341,10 @@ public class CallAudioModeStateMachine extends StateMachine { Log.w(LOG_TAG, "Tone started playing unexpectedly. Args are: \n" + args.toString()); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now AUDIO_PROCESSING"); mAudioManager.abandonAudioFocusForCall(); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -416,6 +425,10 @@ public class CallAudioModeStateMachine extends StateMachine { tryStartRinging(); return HANDLED; } case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -493,6 +506,10 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(mVoipCallFocusState); } return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -563,6 +580,10 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(mSimCallFocusState); } return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading Loading @@ -625,6 +646,11 @@ public class CallAudioModeStateMachine extends StateMachine { return HANDLED; case TONE_STOPPED_PLAYING: transitionTo(calculateProperStateFromArgs(args)); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.w(LOG_TAG, "Should not be seeing AUDIO_OPERATIONS_COMPLETE in a focused" + " state"); return HANDLED; default: return NOT_HANDLED; } Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +5 −0 Original line number Diff line number Diff line Loading @@ -419,6 +419,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } return HANDLED; default: Loading Loading @@ -616,6 +617,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } return HANDLED; default: Loading Loading @@ -861,6 +863,7 @@ public class CallAudioRouteStateMachine extends StateMachine { // Only disconnect SCO audio here instead of routing away from BT entirely. mBluetoothRouteManager.disconnectSco(); reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } else if (msg.arg1 == RINGING_FOCUS && !mBluetoothRouteManager.isInbandRingingEnabled()) { setBluetoothOff(); Loading Loading @@ -952,6 +955,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } else if (msg.arg1 == ACTIVE_FOCUS) { setBluetoothOn(null); } Loading Loading @@ -1175,6 +1179,7 @@ public class CallAudioRouteStateMachine extends StateMachine { case SWITCH_FOCUS: if (msg.arg1 == NO_FOCUS) { reinitialize(); mCallAudioManager.notifyAudioOperationsComplete(); } return HANDLED; default: Loading
tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java +46 −0 Original line number Diff line number Diff line Loading @@ -140,6 +140,12 @@ public class CallAudioModeTransitionTests extends TelecomTestCase { sm.sendMessage(mParams.messageType, mParams.externalState); waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT); if (mParams.expectedFocus == FOCUS_OFF && mParams.messageType != CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE) { // If we expect the focus to turn off, we need to signal operations complete first sm.sendMessage(CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE); waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT); } assertEquals(mParams.expectedFinalStateName, sm.getCurrentStateName()); Loading Loading @@ -856,6 +862,46 @@ public class CallAudioModeTransitionTests extends TelecomTestCase { NO_CHANGE // expectedCallWaitingInteraction )); result.add(new ModeTestParameters( "No change to focus without signaling audio ops complete", CallAudioModeStateMachine.ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, // initialAudioS CallAudioModeStateMachine.TONE_STOPPED_PLAYING, // messageType new MessageArgs.Builder() .setHasActiveOrDialingCalls(false) .setHasRingingCalls(false) .setHasHoldingCalls(false) .setHasAudioProcessingCalls(false) .setIsTonePlaying(false) .setForegroundCallIsVoip(false) .setSession(null) .build(), CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName FOCUS_NO_CHANGE, // expectedFocus AudioManager.MODE_NORMAL, // expectedMode NO_CHANGE, // expectedRingingInteraction NO_CHANGE // expectedCallWaitingInteraction )); result.add(new ModeTestParameters( "Abandon focus once audio ops are complete", CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING, // initialAudioS CallAudioModeStateMachine.AUDIO_OPERATIONS_COMPLETE, // messageType new MessageArgs.Builder() .setHasActiveOrDialingCalls(false) .setHasRingingCalls(false) .setHasHoldingCalls(false) .setHasAudioProcessingCalls(false) .setIsTonePlaying(false) .setForegroundCallIsVoip(false) .setSession(null) .build(), CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName FOCUS_OFF, // expectedFocus NO_CHANGE, // expectedMode NO_CHANGE, // expectedRingingInteraction NO_CHANGE // expectedCallWaitingInteraction )); return result; } Loading