Loading src/com/android/server/telecom/CallAudioManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ public class CallAudioManager extends CallsManagerListenerBase { mPlayerFactory.setCallAudioManager(this); mCallAudioModeStateMachine.setCallAudioManager(this); mCallAudioRouteStateMachine.setCallAudioManager(this); } @Override Loading Loading @@ -385,6 +386,11 @@ public class CallAudioManager extends CallsManagerListenerBase { CallAudioRouteStateMachine.TOGGLE_MUTE); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void onRingerModeChange() { mCallAudioModeStateMachine.sendMessage(CallAudioModeStateMachine.RINGER_MODE_CHANGE); } @VisibleForTesting public void mute(boolean shouldMute) { Log.v(this, "mute, shouldMute: %b", shouldMute); Loading src/com/android/server/telecom/CallAudioModeStateMachine.java +17 −5 Original line number Diff line number Diff line Loading @@ -87,6 +87,8 @@ public class CallAudioModeStateMachine extends StateMachine { public static final int FOREGROUND_VOIP_MODE_CHANGE = 4001; public static final int RINGER_MODE_CHANGE = 5001; public static final int RUN_RUNNABLE = 9001; private static final SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{ Loading @@ -105,6 +107,7 @@ public class CallAudioModeStateMachine extends StateMachine { put(TONE_STARTED_PLAYING, "TONE_STARTED_PLAYING"); put(TONE_STOPPED_PLAYING, "TONE_STOPPED_PLAYING"); put(FOREGROUND_VOIP_MODE_CHANGE, "FOREGROUND_VOIP_MODE_CHANGE"); put(RINGER_MODE_CHANGE, "RINGER_MODE_CHANGE"); put(RUN_RUNNABLE, "RUN_RUNNABLE"); }}; Loading Loading @@ -202,18 +205,22 @@ public class CallAudioModeStateMachine extends StateMachine { } private class RingingFocusState extends BaseState { @Override public void enter() { Log.i(LOG_TAG, "Audio focus entering RINGING state"); private void tryStartRinging() { if (mCallAudioManager.startRinging()) { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); mAudioManager.setMode(AudioManager.MODE_RINGTONE); mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.RINGING_FOCUS); mCallAudioManager.setCallAudioRouteFocusState( CallAudioRouteStateMachine.RINGING_FOCUS); } else { Log.i(LOG_TAG, "Entering RINGING but not acquiring focus -- silent ringtone"); Log.i(LOG_TAG, "RINGING state, try start ringing but not acquiring audio focus"); } } @Override public void enter() { Log.i(LOG_TAG, "Audio focus entering RINGING state"); tryStartRinging(); mCallAudioManager.stopCallWaiting(); } Loading Loading @@ -275,6 +282,11 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(args.foregroundCallIsVoip ? mVoipCallFocusState : mSimCallFocusState); return HANDLED; case RINGER_MODE_CHANGE: { Log.i(LOG_TAG, "RINGING state, received RINGER_MODE_CHANGE"); tryStartRinging(); return HANDLED; } default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +13 −1 Original line number Diff line number Diff line Loading @@ -745,6 +745,10 @@ public class CallAudioRouteStateMachine extends StateMachine { mBluetoothRouteManager.getConnectedDevices()); setSystemAudioState(newState, true); updateInternalCallAudioState(); // Do not send RINGER_MODE_CHANGE if no Bluetooth SCO audio device is available if (mBluetoothRouteManager.getBluetoothAudioConnectedDevice() != null) { mCallAudioManager.onRingerModeChange(); } } @Override Loading @@ -770,7 +774,9 @@ public class CallAudioRouteStateMachine extends StateMachine { } return HANDLED; case BT_AUDIO_CONNECTED: // Nothing to do // Send ringer mode change because we transit to ActiveBluetoothState even // when HFP is connecting mCallAudioManager.onRingerModeChange(); return HANDLED; case SWITCH_BLUETOOTH: case USER_SWITCH_BLUETOOTH: Loading Loading @@ -1276,6 +1282,8 @@ public class CallAudioRouteStateMachine extends StateMachine { private CallAudioState mCurrentCallAudioState; private CallAudioState mLastKnownCallAudioState; private CallAudioManager mCallAudioManager; public CallAudioRouteStateMachine( Context context, CallsManager callsManager, Loading Loading @@ -1332,6 +1340,10 @@ public class CallAudioRouteStateMachine extends StateMachine { mRouteCodeToQuiescentState.put(ROUTE_WIRED_HEADSET, mQuiescentHeadsetRoute); } public void setCallAudioManager(CallAudioManager callAudioManager) { mCallAudioManager = callAudioManager; } /** * Initializes the state machine with info on initial audio route, supported audio routes, * and mute status. Loading src/com/android/server/telecom/CallsManager.java +20 −3 Original line number Diff line number Diff line Loading @@ -1460,8 +1460,21 @@ public class CallsManager extends Call.ListenerBase Call activeCall = (Call) mConnectionSvrFocusMgr.getCurrentFocusCall(); Log.d(this, "Incoming call = %s Ongoing call %s", call, activeCall); if (activeCall != null && activeCall != call) { // Hold the telephony call even if it doesn't have the hold capability. if (canHold(activeCall)) { // We purposely don't check if the active call CAN current hold, but rather we check // whether it CAN support hold. Consider this scenario: // Call A - Active (CAPABILITY_SUPPORT_HOLD, but not CAPABILITY_HOLD) // Call B - Held (CAPABILITY_SUPPORT_HOLD, but not CAPABILITY_HOLD) // Call C - Incoming call // In this scenario we are going to first disconnect the held call (Call B), which // will mean that the active call (Call A) will now support hold. if (supportsHold(activeCall)) { Call heldCall = getHeldCall(); if (heldCall != null) { Log.i(this, "Disconnecting held call %s before holding active call.", heldCall); heldCall.disconnect(); } Log.d(this, "Answer %s, hold %s", call, activeCall); activeCall.hold(); } else { Loading Loading @@ -3436,7 +3449,7 @@ public class CallsManager extends Call.ListenerBase // Send an error back if there are any ongoing emergency calls. if (hasEmergencyCall()) { handoverFromCall.onHandoverFailed( android.telecom.Call.Callback.HANDOVER_FAILURE_ONGOING_EMERG_CALL); android.telecom.Call.Callback.HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL); return; } Loading Loading @@ -3733,6 +3746,10 @@ public class CallsManager extends Call.ListenerBase return call.can(Connection.CAPABILITY_HOLD); } private boolean supportsHold(Call call) { return call.can(Connection.CAPABILITY_SUPPORT_HOLD); } private final class ActionSetCallState implements PendingAction { private final Call mCall; Loading tests/AndroidTest.xml +4 −2 Original line number Diff line number Diff line Loading @@ -14,11 +14,13 @@ limitations under the License. --> <configuration description="Runs Telecom Test Cases."> <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-instrumentation" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="TelecomUnitTests.apk" /> </target_preparer> <option name="test-suite-tag" value="apct" /> <option name="test-tag" value="TelecomUnitTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.server.telecom.tests" /> Loading Loading
src/com/android/server/telecom/CallAudioManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ public class CallAudioManager extends CallsManagerListenerBase { mPlayerFactory.setCallAudioManager(this); mCallAudioModeStateMachine.setCallAudioManager(this); mCallAudioRouteStateMachine.setCallAudioManager(this); } @Override Loading Loading @@ -385,6 +386,11 @@ public class CallAudioManager extends CallsManagerListenerBase { CallAudioRouteStateMachine.TOGGLE_MUTE); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void onRingerModeChange() { mCallAudioModeStateMachine.sendMessage(CallAudioModeStateMachine.RINGER_MODE_CHANGE); } @VisibleForTesting public void mute(boolean shouldMute) { Log.v(this, "mute, shouldMute: %b", shouldMute); Loading
src/com/android/server/telecom/CallAudioModeStateMachine.java +17 −5 Original line number Diff line number Diff line Loading @@ -87,6 +87,8 @@ public class CallAudioModeStateMachine extends StateMachine { public static final int FOREGROUND_VOIP_MODE_CHANGE = 4001; public static final int RINGER_MODE_CHANGE = 5001; public static final int RUN_RUNNABLE = 9001; private static final SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{ Loading @@ -105,6 +107,7 @@ public class CallAudioModeStateMachine extends StateMachine { put(TONE_STARTED_PLAYING, "TONE_STARTED_PLAYING"); put(TONE_STOPPED_PLAYING, "TONE_STOPPED_PLAYING"); put(FOREGROUND_VOIP_MODE_CHANGE, "FOREGROUND_VOIP_MODE_CHANGE"); put(RINGER_MODE_CHANGE, "RINGER_MODE_CHANGE"); put(RUN_RUNNABLE, "RUN_RUNNABLE"); }}; Loading Loading @@ -202,18 +205,22 @@ public class CallAudioModeStateMachine extends StateMachine { } private class RingingFocusState extends BaseState { @Override public void enter() { Log.i(LOG_TAG, "Audio focus entering RINGING state"); private void tryStartRinging() { if (mCallAudioManager.startRinging()) { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); mAudioManager.setMode(AudioManager.MODE_RINGTONE); mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.RINGING_FOCUS); mCallAudioManager.setCallAudioRouteFocusState( CallAudioRouteStateMachine.RINGING_FOCUS); } else { Log.i(LOG_TAG, "Entering RINGING but not acquiring focus -- silent ringtone"); Log.i(LOG_TAG, "RINGING state, try start ringing but not acquiring audio focus"); } } @Override public void enter() { Log.i(LOG_TAG, "Audio focus entering RINGING state"); tryStartRinging(); mCallAudioManager.stopCallWaiting(); } Loading Loading @@ -275,6 +282,11 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(args.foregroundCallIsVoip ? mVoipCallFocusState : mSimCallFocusState); return HANDLED; case RINGER_MODE_CHANGE: { Log.i(LOG_TAG, "RINGING state, received RINGER_MODE_CHANGE"); tryStartRinging(); return HANDLED; } default: // The forced focus switch commands are handled by BaseState. return NOT_HANDLED; Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +13 −1 Original line number Diff line number Diff line Loading @@ -745,6 +745,10 @@ public class CallAudioRouteStateMachine extends StateMachine { mBluetoothRouteManager.getConnectedDevices()); setSystemAudioState(newState, true); updateInternalCallAudioState(); // Do not send RINGER_MODE_CHANGE if no Bluetooth SCO audio device is available if (mBluetoothRouteManager.getBluetoothAudioConnectedDevice() != null) { mCallAudioManager.onRingerModeChange(); } } @Override Loading @@ -770,7 +774,9 @@ public class CallAudioRouteStateMachine extends StateMachine { } return HANDLED; case BT_AUDIO_CONNECTED: // Nothing to do // Send ringer mode change because we transit to ActiveBluetoothState even // when HFP is connecting mCallAudioManager.onRingerModeChange(); return HANDLED; case SWITCH_BLUETOOTH: case USER_SWITCH_BLUETOOTH: Loading Loading @@ -1276,6 +1282,8 @@ public class CallAudioRouteStateMachine extends StateMachine { private CallAudioState mCurrentCallAudioState; private CallAudioState mLastKnownCallAudioState; private CallAudioManager mCallAudioManager; public CallAudioRouteStateMachine( Context context, CallsManager callsManager, Loading Loading @@ -1332,6 +1340,10 @@ public class CallAudioRouteStateMachine extends StateMachine { mRouteCodeToQuiescentState.put(ROUTE_WIRED_HEADSET, mQuiescentHeadsetRoute); } public void setCallAudioManager(CallAudioManager callAudioManager) { mCallAudioManager = callAudioManager; } /** * Initializes the state machine with info on initial audio route, supported audio routes, * and mute status. Loading
src/com/android/server/telecom/CallsManager.java +20 −3 Original line number Diff line number Diff line Loading @@ -1460,8 +1460,21 @@ public class CallsManager extends Call.ListenerBase Call activeCall = (Call) mConnectionSvrFocusMgr.getCurrentFocusCall(); Log.d(this, "Incoming call = %s Ongoing call %s", call, activeCall); if (activeCall != null && activeCall != call) { // Hold the telephony call even if it doesn't have the hold capability. if (canHold(activeCall)) { // We purposely don't check if the active call CAN current hold, but rather we check // whether it CAN support hold. Consider this scenario: // Call A - Active (CAPABILITY_SUPPORT_HOLD, but not CAPABILITY_HOLD) // Call B - Held (CAPABILITY_SUPPORT_HOLD, but not CAPABILITY_HOLD) // Call C - Incoming call // In this scenario we are going to first disconnect the held call (Call B), which // will mean that the active call (Call A) will now support hold. if (supportsHold(activeCall)) { Call heldCall = getHeldCall(); if (heldCall != null) { Log.i(this, "Disconnecting held call %s before holding active call.", heldCall); heldCall.disconnect(); } Log.d(this, "Answer %s, hold %s", call, activeCall); activeCall.hold(); } else { Loading Loading @@ -3436,7 +3449,7 @@ public class CallsManager extends Call.ListenerBase // Send an error back if there are any ongoing emergency calls. if (hasEmergencyCall()) { handoverFromCall.onHandoverFailed( android.telecom.Call.Callback.HANDOVER_FAILURE_ONGOING_EMERG_CALL); android.telecom.Call.Callback.HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL); return; } Loading Loading @@ -3733,6 +3746,10 @@ public class CallsManager extends Call.ListenerBase return call.can(Connection.CAPABILITY_HOLD); } private boolean supportsHold(Call call) { return call.can(Connection.CAPABILITY_SUPPORT_HOLD); } private final class ActionSetCallState implements PendingAction { private final Call mCall; Loading
tests/AndroidTest.xml +4 −2 Original line number Diff line number Diff line Loading @@ -14,11 +14,13 @@ limitations under the License. --> <configuration description="Runs Telecom Test Cases."> <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-instrumentation" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="TelecomUnitTests.apk" /> </target_preparer> <option name="test-suite-tag" value="apct" /> <option name="test-tag" value="TelecomUnitTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.server.telecom.tests" /> Loading