Loading src/com/android/server/telecom/BluetoothPhoneServiceImpl.java +12 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ public class BluetoothPhoneServiceImpl { private static final int CALL_STATE_INCOMING = 4; private static final int CALL_STATE_WAITING = 5; private static final int CALL_STATE_IDLE = 6; private static final int CALL_STATE_DISCONNECTED = 7; // match up with bthf_call_state_t of bt_hf.h // Terminate all held or set UDUB("busy") to a waiting call Loading @@ -84,6 +85,7 @@ public class BluetoothPhoneServiceImpl { private String mRingingAddress = null; private int mRingingAddressType = 0; private Call mOldHeldCall = null; private boolean mIsDisconnectedTonePlaying = false; /** * Binder implementation of IBluetoothHeadsetPhone. Implements the command interface that the Loading Loading @@ -387,6 +389,12 @@ public class BluetoothPhoneServiceImpl { } updateHeadsetWithCallState(false /* force */); } @Override public void onDisconnectedTonePlaying(boolean isTonePlaying) { mIsDisconnectedTonePlaying = isTonePlaying; updateHeadsetWithCallState(false /* force */); } }; /** Loading Loading @@ -816,6 +824,7 @@ public class BluetoothPhoneServiceImpl { CallsManager callsManager = mCallsManager; Call ringingCall = mCallsManager.getRingingCall(); Call dialingCall = mCallsManager.getOutgoingCall(); boolean hasOnlyDisconnectedCalls = mCallsManager.hasOnlyDisconnectedCalls(); // // !! WARNING !! Loading @@ -831,6 +840,9 @@ public class BluetoothPhoneServiceImpl { bluetoothCallState = CALL_STATE_INCOMING; } else if (dialingCall != null) { bluetoothCallState = CALL_STATE_ALERTING; } else if (hasOnlyDisconnectedCalls || mIsDisconnectedTonePlaying) { // Keep the DISCONNECTED state until the disconnect tone's playback is done bluetoothCallState = CALL_STATE_DISCONNECTED; } return bluetoothCallState; } Loading src/com/android/server/telecom/CallAudioManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ public class CallAudioManager extends CallsManagerListenerBase { private Call mForegroundCall; private boolean mIsTonePlaying = false; private boolean mIsDisconnectedTonePlaying = false; private InCallTonePlayer mHoldTonePlayer; public CallAudioManager(CallAudioRouteStateMachine callAudioRouteStateMachine, Loading Loading @@ -519,6 +520,11 @@ public class CallAudioManager extends CallsManagerListenerBase { isTonePlaying ? CallAudioModeStateMachine.TONE_STARTED_PLAYING : CallAudioModeStateMachine.TONE_STOPPED_PLAYING, makeArgsForModeStateMachine()); if (!isTonePlaying && mIsDisconnectedTonePlaying) { mCallsManager.onDisconnectedTonePlaying(false); mIsDisconnectedTonePlaying = false; } } private void onCallLeavingState(Call call, int state) { Loading Loading @@ -699,6 +705,8 @@ public class CallAudioManager extends CallsManagerListenerBase { if (toneToPlay != InCallTonePlayer.TONE_INVALID) { mPlayerFactory.createPlayer(toneToPlay).startTone(); mCallsManager.onDisconnectedTonePlaying(true); mIsDisconnectedTonePlaying = true; } } } Loading src/com/android/server/telecom/CallsManager.java +20 −1 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ public class CallsManager extends Call.ListenerBase void onSessionModifyRequestReceived(Call call, VideoProfile videoProfile); void onHoldToneRequested(Call call); void onExternalCallChanged(Call call, boolean isExternalCall); void onDisconnectedTonePlaying(boolean isTonePlaying); } private static final String TAG = "CallsManager"; Loading Loading @@ -773,7 +774,11 @@ public class CallsManager extends Call.ListenerBase return false; } boolean hasOnlyDisconnectedCalls() { @VisibleForTesting public boolean hasOnlyDisconnectedCalls() { if (mCalls.size() == 0) { return false; } for (Call call : mCalls) { if (!call.isDisconnected()) { return false; Loading Loading @@ -1788,6 +1793,20 @@ public class CallsManager extends Call.ListenerBase } } /** * Called when disconnect tone is started or stopped, including any InCallTone * after disconnected call. * * @param isTonePlaying true if the disconnected tone is started, otherwise the disconnected * tone is stopped. */ void onDisconnectedTonePlaying(boolean isTonePlaying) { Log.v(this, "onDisconnectedTonePlaying, %s", isTonePlaying ? "started" : "stopped"); for (CallsManagerListener listener : mListeners) { listener.onDisconnectedTonePlaying(isTonePlaying); } } void markCallAsRinging(Call call) { setCallState(call, CallState.RINGING, "ringing set explicitly"); } Loading src/com/android/server/telecom/CallsManagerListenerBase.java +4 −0 Original line number Diff line number Diff line Loading @@ -88,4 +88,8 @@ public class CallsManagerListenerBase implements CallsManager.CallsManagerListen @Override public void onExternalCallChanged(Call call, boolean isExternalCall) { } @Override public void onDisconnectedTonePlaying(boolean isTonePlaying) { } } tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java +27 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { private static final int CALL_STATE_INCOMING = 4; private static final int CALL_STATE_WAITING = 5; private static final int CALL_STATE_IDLE = 6; private static final int CALL_STATE_DISCONNECTED = 7; // Terminate all held or set UDUB("busy") to a waiting call private static final int CHLD_TYPE_RELEASEHELD = 0; // Terminate all active calls and accepts a waiting/held call Loading Loading @@ -110,6 +111,7 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { doReturn(null).when(mMockCallsManager).getHeldCall(); doReturn(null).when(mMockCallsManager).getOutgoingCall(); doReturn(0).when(mMockCallsManager).getNumHeldCalls(); doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls(); mBluetoothPhoneService = new BluetoothPhoneServiceImpl(mContext, mLock, mMockCallsManager, mock(BluetoothAdapterProxy.class), mMockPhoneAccountRegistrar); Loading Loading @@ -816,6 +818,25 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { verify(mMockBluetoothHeadset).phoneStateChanged(0, 0, CALL_STATE_ALERTING, "", 128); } @MediumTest public void testOnCallStateChangedDisconnected() throws Exception { Call disconnectedCall = createDisconnectedCall(); doReturn(true).when(mMockCallsManager).hasOnlyDisconnectedCalls(); mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(disconnectedCall, CallState.DISCONNECTING, CallState.DISCONNECTED); verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED), eq(""), eq(128)); doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls(); mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(true); verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED), eq(""), eq(128)); mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(false); verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128)); } @MediumTest public void testOnCallStateChanged() throws Exception { Call ringingCall = createRingingCall(); Loading Loading @@ -929,6 +950,12 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { return call; } private Call createDisconnectedCall() { Call call = mock(Call.class); when(mMockCallsManager.getFirstCallWithState(CallState.DISCONNECTED)).thenReturn(call); return call; } private Call createForegroundCall() { Call call = mock(Call.class); when(mMockCallsManager.getForegroundCall()).thenReturn(call); Loading Loading
src/com/android/server/telecom/BluetoothPhoneServiceImpl.java +12 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ public class BluetoothPhoneServiceImpl { private static final int CALL_STATE_INCOMING = 4; private static final int CALL_STATE_WAITING = 5; private static final int CALL_STATE_IDLE = 6; private static final int CALL_STATE_DISCONNECTED = 7; // match up with bthf_call_state_t of bt_hf.h // Terminate all held or set UDUB("busy") to a waiting call Loading @@ -84,6 +85,7 @@ public class BluetoothPhoneServiceImpl { private String mRingingAddress = null; private int mRingingAddressType = 0; private Call mOldHeldCall = null; private boolean mIsDisconnectedTonePlaying = false; /** * Binder implementation of IBluetoothHeadsetPhone. Implements the command interface that the Loading Loading @@ -387,6 +389,12 @@ public class BluetoothPhoneServiceImpl { } updateHeadsetWithCallState(false /* force */); } @Override public void onDisconnectedTonePlaying(boolean isTonePlaying) { mIsDisconnectedTonePlaying = isTonePlaying; updateHeadsetWithCallState(false /* force */); } }; /** Loading Loading @@ -816,6 +824,7 @@ public class BluetoothPhoneServiceImpl { CallsManager callsManager = mCallsManager; Call ringingCall = mCallsManager.getRingingCall(); Call dialingCall = mCallsManager.getOutgoingCall(); boolean hasOnlyDisconnectedCalls = mCallsManager.hasOnlyDisconnectedCalls(); // // !! WARNING !! Loading @@ -831,6 +840,9 @@ public class BluetoothPhoneServiceImpl { bluetoothCallState = CALL_STATE_INCOMING; } else if (dialingCall != null) { bluetoothCallState = CALL_STATE_ALERTING; } else if (hasOnlyDisconnectedCalls || mIsDisconnectedTonePlaying) { // Keep the DISCONNECTED state until the disconnect tone's playback is done bluetoothCallState = CALL_STATE_DISCONNECTED; } return bluetoothCallState; } Loading
src/com/android/server/telecom/CallAudioManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ public class CallAudioManager extends CallsManagerListenerBase { private Call mForegroundCall; private boolean mIsTonePlaying = false; private boolean mIsDisconnectedTonePlaying = false; private InCallTonePlayer mHoldTonePlayer; public CallAudioManager(CallAudioRouteStateMachine callAudioRouteStateMachine, Loading Loading @@ -519,6 +520,11 @@ public class CallAudioManager extends CallsManagerListenerBase { isTonePlaying ? CallAudioModeStateMachine.TONE_STARTED_PLAYING : CallAudioModeStateMachine.TONE_STOPPED_PLAYING, makeArgsForModeStateMachine()); if (!isTonePlaying && mIsDisconnectedTonePlaying) { mCallsManager.onDisconnectedTonePlaying(false); mIsDisconnectedTonePlaying = false; } } private void onCallLeavingState(Call call, int state) { Loading Loading @@ -699,6 +705,8 @@ public class CallAudioManager extends CallsManagerListenerBase { if (toneToPlay != InCallTonePlayer.TONE_INVALID) { mPlayerFactory.createPlayer(toneToPlay).startTone(); mCallsManager.onDisconnectedTonePlaying(true); mIsDisconnectedTonePlaying = true; } } } Loading
src/com/android/server/telecom/CallsManager.java +20 −1 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ public class CallsManager extends Call.ListenerBase void onSessionModifyRequestReceived(Call call, VideoProfile videoProfile); void onHoldToneRequested(Call call); void onExternalCallChanged(Call call, boolean isExternalCall); void onDisconnectedTonePlaying(boolean isTonePlaying); } private static final String TAG = "CallsManager"; Loading Loading @@ -773,7 +774,11 @@ public class CallsManager extends Call.ListenerBase return false; } boolean hasOnlyDisconnectedCalls() { @VisibleForTesting public boolean hasOnlyDisconnectedCalls() { if (mCalls.size() == 0) { return false; } for (Call call : mCalls) { if (!call.isDisconnected()) { return false; Loading Loading @@ -1788,6 +1793,20 @@ public class CallsManager extends Call.ListenerBase } } /** * Called when disconnect tone is started or stopped, including any InCallTone * after disconnected call. * * @param isTonePlaying true if the disconnected tone is started, otherwise the disconnected * tone is stopped. */ void onDisconnectedTonePlaying(boolean isTonePlaying) { Log.v(this, "onDisconnectedTonePlaying, %s", isTonePlaying ? "started" : "stopped"); for (CallsManagerListener listener : mListeners) { listener.onDisconnectedTonePlaying(isTonePlaying); } } void markCallAsRinging(Call call) { setCallState(call, CallState.RINGING, "ringing set explicitly"); } Loading
src/com/android/server/telecom/CallsManagerListenerBase.java +4 −0 Original line number Diff line number Diff line Loading @@ -88,4 +88,8 @@ public class CallsManagerListenerBase implements CallsManager.CallsManagerListen @Override public void onExternalCallChanged(Call call, boolean isExternalCall) { } @Override public void onDisconnectedTonePlaying(boolean isTonePlaying) { } }
tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java +27 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { private static final int CALL_STATE_INCOMING = 4; private static final int CALL_STATE_WAITING = 5; private static final int CALL_STATE_IDLE = 6; private static final int CALL_STATE_DISCONNECTED = 7; // Terminate all held or set UDUB("busy") to a waiting call private static final int CHLD_TYPE_RELEASEHELD = 0; // Terminate all active calls and accepts a waiting/held call Loading Loading @@ -110,6 +111,7 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { doReturn(null).when(mMockCallsManager).getHeldCall(); doReturn(null).when(mMockCallsManager).getOutgoingCall(); doReturn(0).when(mMockCallsManager).getNumHeldCalls(); doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls(); mBluetoothPhoneService = new BluetoothPhoneServiceImpl(mContext, mLock, mMockCallsManager, mock(BluetoothAdapterProxy.class), mMockPhoneAccountRegistrar); Loading Loading @@ -816,6 +818,25 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { verify(mMockBluetoothHeadset).phoneStateChanged(0, 0, CALL_STATE_ALERTING, "", 128); } @MediumTest public void testOnCallStateChangedDisconnected() throws Exception { Call disconnectedCall = createDisconnectedCall(); doReturn(true).when(mMockCallsManager).hasOnlyDisconnectedCalls(); mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(disconnectedCall, CallState.DISCONNECTING, CallState.DISCONNECTED); verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED), eq(""), eq(128)); doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls(); mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(true); verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED), eq(""), eq(128)); mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(false); verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128)); } @MediumTest public void testOnCallStateChanged() throws Exception { Call ringingCall = createRingingCall(); Loading Loading @@ -929,6 +950,12 @@ public class BluetoothPhoneServiceTest extends TelecomTestCase { return call; } private Call createDisconnectedCall() { Call call = mock(Call.class); when(mMockCallsManager.getFirstCallWithState(CallState.DISCONNECTED)).thenReturn(call); return call; } private Call createForegroundCall() { Call call = mock(Call.class); when(mMockCallsManager.getForegroundCall()).thenReturn(call); Loading