Loading src/com/android/server/telecom/Call.java +13 −2 Original line number Diff line number Diff line Loading @@ -318,6 +318,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, */ private long mCreationTimeMillis; /** * The elapsed realtime millis when this call was created; this can be used to determine how * long has elapsed since the call was first created. */ private long mCreationElapsedRealtimeMillis; /** The time this call was made active. */ private long mConnectTimeMillis = 0; Loading Loading @@ -822,6 +828,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, mClockProxy = clockProxy; mToastFactory = toastFactory; mCreationTimeMillis = mClockProxy.currentTimeMillis(); mCreationElapsedRealtimeMillis = mClockProxy.elapsedRealtime(); mMissedReason = MISSED_REASON_NOT_MISSED; mStartRingTime = 0; Loading Loading @@ -2051,8 +2058,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, return mCreationTimeMillis; } public void setCreationTimeMillis(long time) { mCreationTimeMillis = time; /** * @return The elapsed realtime millis when the call was created; ONLY useful for determining * how long has elapsed since the call was first created. */ public long getCreationElapsedRealtimeMillis() { return mCreationElapsedRealtimeMillis; } public long getConnectTimeMillis() { Loading src/com/android/server/telecom/CallsManager.java +12 −3 Original line number Diff line number Diff line Loading @@ -4881,9 +4881,18 @@ public class CallsManager extends Call.ListenerBase return true; } // If the live call is stuck in a connecting state, then we should disconnect it in favor // of the new outgoing call and prompt the user to generate a bugreport. if (liveCall.getState() == CallState.CONNECTING) { // If the live call is stuck in a connecting state for longer than the transitory timeout, // then we should disconnect it in favor of the new outgoing call and prompt the user to // generate a bugreport. // TODO: In the future we should let the CallAnomalyWatchDog do this disconnection of the // live call stuck in the connecting state. Unfortunately that code will get tripped up by // calls that have a longer than expected new outgoing call broadcast response time. This // mitigation is intended to catch calls stuck in a CONNECTING state for a long time that // block outgoing calls. However, if the user dials two calls in quick succession it will // result in both calls getting disconnected, which is not optimal. if (liveCall.getState() == CallState.CONNECTING && ((mClockProxy.elapsedRealtime() - liveCall.getCreationElapsedRealtimeMillis()) > mTimeoutsAdapter.getNonVoipCallTransitoryStateTimeoutMillis())) { mAnomalyReporter.reportAnomaly(LIVE_CALL_STUCK_CONNECTING_ERROR_UUID, LIVE_CALL_STUCK_CONNECTING_ERROR_MSG); liveCall.disconnect("Force disconnect CONNECTING call."); Loading tests/src/com/android/server/telecom/tests/CallsManagerTest.java +28 −1 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ import java.util.concurrent.TimeUnit; @RunWith(JUnit4.class) public class CallsManagerTest extends TelecomTestCase { private static final int TEST_TIMEOUT = 5000; // milliseconds private static final long STATE_TIMEOUT = 5000L; private static final int SECONDARY_USER_ID = 12; private static final PhoneAccountHandle SIM_1_HANDLE = new PhoneAccountHandle( ComponentName.unflattenFromString("com.foo/.Blah"), "Sim1"); Loading Loading @@ -275,6 +276,9 @@ public class CallsManagerTest extends TelecomTestCase { .thenReturn(mDisconnectedCallNotifier); when(mTimeoutsAdapter.getCallDiagnosticServiceTimeoutMillis(any(ContentResolver.class))) .thenReturn(2000L); when(mTimeoutsAdapter.getNonVoipCallTransitoryStateTimeoutMillis()) .thenReturn(STATE_TIMEOUT); when(mClockProxy.elapsedRealtime()).thenReturn(0L); mCallsManager = new CallsManager( mComponentContextFixture.getTestDouble().getApplicationContext(), mLock, Loading Loading @@ -1563,6 +1567,8 @@ public class CallsManagerTest extends TelecomTestCase { .thenReturn(false); newCall.setHandle(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); // Make sure enough time has passed that we'd drop the connecting call. when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT + 10L); assertTrue(mCallsManager.makeRoomForOutgoingCall(newCall)); verify(mAnomalyReporterAdapter).reportAnomaly( CallsManager.LIVE_CALL_STUCK_CONNECTING_ERROR_UUID, Loading @@ -1570,6 +1576,26 @@ public class CallsManagerTest extends TelecomTestCase { verify(ongoingCall).disconnect(anyLong(), anyString()); } /** * Verifies that we won't auto-disconnect an outgoing CONNECTING call unless it has timed out. */ @SmallTest @Test public void testDontDisconnectConnectingCallWhenNotTimedOut() { mCallsManager.setAnomalyReporterAdapter(mAnomalyReporterAdapter); Call ongoingCall = addSpyCall(SIM_2_HANDLE, CallState.CONNECTING); Call newCall = createCall(SIM_1_HANDLE, CallState.NEW); when(mComponentContextFixture.getTelephonyManager().isEmergencyNumber(any())) .thenReturn(false); newCall.setHandle(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); // Make sure it has been a short time so we don't try to disconnect the call when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT / 2); assertFalse(mCallsManager.makeRoomForOutgoingCall(newCall)); verify(ongoingCall, never()).disconnect(anyLong(), anyString()); } @SmallTest @Test public void testMakeRoomForEmergencyCallHasOutgoingCall() { Loading Loading @@ -1643,6 +1669,7 @@ public class CallsManagerTest extends TelecomTestCase { Call ongoingCall = addSpyCall(SIM_2_HANDLE, CallState.CONNECTING); Call newCall = createCall(SIM_1_HANDLE, CallState.NEW); when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT + 10L); assertTrue(mCallsManager.makeRoomForOutgoingCall(newCall)); verify(ongoingCall).disconnect(anyLong(), anyString()); } Loading @@ -1652,7 +1679,7 @@ public class CallsManagerTest extends TelecomTestCase { public void testMakeRoomForOutgoingCallForSameCall() { addSpyCall(SIM_2_HANDLE, CallState.CONNECTING); Call ongoingCall2 = addSpyCall(); when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT + 10L); assertTrue(mCallsManager.makeRoomForOutgoingCall(ongoingCall2)); } Loading Loading
src/com/android/server/telecom/Call.java +13 −2 Original line number Diff line number Diff line Loading @@ -318,6 +318,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, */ private long mCreationTimeMillis; /** * The elapsed realtime millis when this call was created; this can be used to determine how * long has elapsed since the call was first created. */ private long mCreationElapsedRealtimeMillis; /** The time this call was made active. */ private long mConnectTimeMillis = 0; Loading Loading @@ -822,6 +828,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, mClockProxy = clockProxy; mToastFactory = toastFactory; mCreationTimeMillis = mClockProxy.currentTimeMillis(); mCreationElapsedRealtimeMillis = mClockProxy.elapsedRealtime(); mMissedReason = MISSED_REASON_NOT_MISSED; mStartRingTime = 0; Loading Loading @@ -2051,8 +2058,12 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, return mCreationTimeMillis; } public void setCreationTimeMillis(long time) { mCreationTimeMillis = time; /** * @return The elapsed realtime millis when the call was created; ONLY useful for determining * how long has elapsed since the call was first created. */ public long getCreationElapsedRealtimeMillis() { return mCreationElapsedRealtimeMillis; } public long getConnectTimeMillis() { Loading
src/com/android/server/telecom/CallsManager.java +12 −3 Original line number Diff line number Diff line Loading @@ -4881,9 +4881,18 @@ public class CallsManager extends Call.ListenerBase return true; } // If the live call is stuck in a connecting state, then we should disconnect it in favor // of the new outgoing call and prompt the user to generate a bugreport. if (liveCall.getState() == CallState.CONNECTING) { // If the live call is stuck in a connecting state for longer than the transitory timeout, // then we should disconnect it in favor of the new outgoing call and prompt the user to // generate a bugreport. // TODO: In the future we should let the CallAnomalyWatchDog do this disconnection of the // live call stuck in the connecting state. Unfortunately that code will get tripped up by // calls that have a longer than expected new outgoing call broadcast response time. This // mitigation is intended to catch calls stuck in a CONNECTING state for a long time that // block outgoing calls. However, if the user dials two calls in quick succession it will // result in both calls getting disconnected, which is not optimal. if (liveCall.getState() == CallState.CONNECTING && ((mClockProxy.elapsedRealtime() - liveCall.getCreationElapsedRealtimeMillis()) > mTimeoutsAdapter.getNonVoipCallTransitoryStateTimeoutMillis())) { mAnomalyReporter.reportAnomaly(LIVE_CALL_STUCK_CONNECTING_ERROR_UUID, LIVE_CALL_STUCK_CONNECTING_ERROR_MSG); liveCall.disconnect("Force disconnect CONNECTING call."); Loading
tests/src/com/android/server/telecom/tests/CallsManagerTest.java +28 −1 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ import java.util.concurrent.TimeUnit; @RunWith(JUnit4.class) public class CallsManagerTest extends TelecomTestCase { private static final int TEST_TIMEOUT = 5000; // milliseconds private static final long STATE_TIMEOUT = 5000L; private static final int SECONDARY_USER_ID = 12; private static final PhoneAccountHandle SIM_1_HANDLE = new PhoneAccountHandle( ComponentName.unflattenFromString("com.foo/.Blah"), "Sim1"); Loading Loading @@ -275,6 +276,9 @@ public class CallsManagerTest extends TelecomTestCase { .thenReturn(mDisconnectedCallNotifier); when(mTimeoutsAdapter.getCallDiagnosticServiceTimeoutMillis(any(ContentResolver.class))) .thenReturn(2000L); when(mTimeoutsAdapter.getNonVoipCallTransitoryStateTimeoutMillis()) .thenReturn(STATE_TIMEOUT); when(mClockProxy.elapsedRealtime()).thenReturn(0L); mCallsManager = new CallsManager( mComponentContextFixture.getTestDouble().getApplicationContext(), mLock, Loading Loading @@ -1563,6 +1567,8 @@ public class CallsManagerTest extends TelecomTestCase { .thenReturn(false); newCall.setHandle(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); // Make sure enough time has passed that we'd drop the connecting call. when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT + 10L); assertTrue(mCallsManager.makeRoomForOutgoingCall(newCall)); verify(mAnomalyReporterAdapter).reportAnomaly( CallsManager.LIVE_CALL_STUCK_CONNECTING_ERROR_UUID, Loading @@ -1570,6 +1576,26 @@ public class CallsManagerTest extends TelecomTestCase { verify(ongoingCall).disconnect(anyLong(), anyString()); } /** * Verifies that we won't auto-disconnect an outgoing CONNECTING call unless it has timed out. */ @SmallTest @Test public void testDontDisconnectConnectingCallWhenNotTimedOut() { mCallsManager.setAnomalyReporterAdapter(mAnomalyReporterAdapter); Call ongoingCall = addSpyCall(SIM_2_HANDLE, CallState.CONNECTING); Call newCall = createCall(SIM_1_HANDLE, CallState.NEW); when(mComponentContextFixture.getTelephonyManager().isEmergencyNumber(any())) .thenReturn(false); newCall.setHandle(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED); // Make sure it has been a short time so we don't try to disconnect the call when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT / 2); assertFalse(mCallsManager.makeRoomForOutgoingCall(newCall)); verify(ongoingCall, never()).disconnect(anyLong(), anyString()); } @SmallTest @Test public void testMakeRoomForEmergencyCallHasOutgoingCall() { Loading Loading @@ -1643,6 +1669,7 @@ public class CallsManagerTest extends TelecomTestCase { Call ongoingCall = addSpyCall(SIM_2_HANDLE, CallState.CONNECTING); Call newCall = createCall(SIM_1_HANDLE, CallState.NEW); when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT + 10L); assertTrue(mCallsManager.makeRoomForOutgoingCall(newCall)); verify(ongoingCall).disconnect(anyLong(), anyString()); } Loading @@ -1652,7 +1679,7 @@ public class CallsManagerTest extends TelecomTestCase { public void testMakeRoomForOutgoingCallForSameCall() { addSpyCall(SIM_2_HANDLE, CallState.CONNECTING); Call ongoingCall2 = addSpyCall(); when(mClockProxy.elapsedRealtime()).thenReturn(STATE_TIMEOUT + 10L); assertTrue(mCallsManager.makeRoomForOutgoingCall(ongoingCall2)); } Loading