Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d76fa7d authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Cleanup ongoing calls if ImsService disconnects from ImsPhoneCallTracker

If the ImsService disconnects from the ImsPhoneCallTracker, disconnect
all ongoing calls being tracked in the ImsPhoneCallTracker instead of
orphaning them.

Bug: 149315877
Test: atest FrameworksTelephonyTests:ImsPhoneCallTrackerTest
Change-Id: I649b98b641da83d4766ec550a9ed4725f2035e19
parent 17b05cb6
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -998,10 +998,32 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            }
            mImsManager.close();
        }
        hangupAllOrphanedConnections(DisconnectCause.LOST_SIGNAL);
        // For compatibility with apps that still use deprecated intent
        sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_DOWN);
    }

    /**
     * Hang up all ongoing connections in the case that the ImsService has been disconnected and the
     * existing calls have been orphaned. This method assumes that there is no connection to the
     * ImsService and DOES NOT try to terminate the connections on the service side before
     * disconnecting here, as it assumes they have already been disconnected when we lost the
     * connection to the ImsService.
     */
    @VisibleForTesting
    public void hangupAllOrphanedConnections(int disconnectCause) {
        Log.w(LOG_TAG, "hangupAllOngoingConnections called for cause " + disconnectCause);

        // Move connections to disconnected and notify the reason why.
        for (ImsPhoneConnection connection : mConnections) {
            connection.update(connection.getImsCall(), ImsPhoneCall.State.DISCONNECTED);
            connection.onDisconnect(disconnectCause);
            connection.getCall().detach(connection);
        }
        mConnections.clear();
        updatePhoneState();
    }

    private void sendImsServiceStateIntent(String intentAction) {
        Intent intent = new Intent(intentAction);
        intent.putExtra(ImsManager.EXTRA_PHONE_ID, mPhone.getPhoneId());
+42 −0
Original line number Diff line number Diff line
@@ -508,6 +508,48 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        assertEquals(Call.State.HOLDING, mCTUT.mBackgroundCall.getState());
    }

    @Test
    @SmallTest
    public void testImsMTActiveHoldServiceDisconnect() {
        testImsMTCallAccept();

        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
        assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
        // mock a new MT
        try {
            doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class),
                    any(ImsCall.Listener.class));
        } catch (Exception ex) {
            ex.printStackTrace();
            Assert.fail("unexpected exception thrown" + ex.getMessage());
        }
        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);

        verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any());
        verify(mImsPhone, times(2)).notifyIncomingRing();
        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
        assertEquals(ImsPhoneCall.State.WAITING, mCTUT.mRingingCall.getState());
        assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());

        //hold the foreground active call, accept the new ringing call
        try {
            mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
            verify(mImsCall, times(1)).hold();
        } catch (Exception ex) {
            ex.printStackTrace();
            Assert.fail("unexpected exception thrown" + ex.getMessage());
        }

        processAllMessages();
        assertEquals(Call.State.ACTIVE, mCTUT.mForegroundCall.getState());
        assertFalse(mCTUT.mRingingCall.isRinging());
        assertEquals(Call.State.HOLDING, mCTUT.mBackgroundCall.getState());

        // Now fake the ImsService crashing
        mCTUT.hangupAllOrphanedConnections(DisconnectCause.LOST_SIGNAL);
        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
    }

    /**
     * Ensures that the dial method will perform a shared preferences lookup using the correct
     * shared preference key to determine the CLIR mode.