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

Commit 42e2819d authored by Jaesik Kong's avatar Jaesik Kong Committed by Android (Google) Code Review
Browse files

Merge "(APDS) Terminate selection when modem reset during domain selection" into main

parents 53618e8e 9bd0437e
Loading
Loading
Loading
Loading
+54 −2
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.IDomainSelector;
import com.android.internal.telephony.ITransportSelectorCallback;
import com.android.internal.telephony.ITransportSelectorResultCallback;
@@ -70,7 +71,9 @@ public class DomainSelectionConnection {
    protected static final int EVENT_SERVICE_CONNECTED = 3;
    protected static final int EVENT_SERVICE_BINDING_TIMEOUT = 4;
    protected static final int EVENT_RESET_NETWORK_SCAN_DONE = 5;
    protected static final int EVENT_LAST = EVENT_RESET_NETWORK_SCAN_DONE;
    protected static final int EVENT_TRIGGER_NETWORK_SCAN_DONE = 6;
    protected static final int EVENT_MODEM_RESET = 7;
    protected static final int EVENT_LAST = EVENT_MODEM_RESET;

    private static final int DEFAULT_BIND_RETRY_TIMEOUT_MS = 4 * 1000;

@@ -308,6 +311,23 @@ public class DomainSelectionConnection {
                                mPendingScanRequest.mScanType, false);
                    }
                    break;
                case EVENT_TRIGGER_NETWORK_SCAN_DONE:
                    synchronized (mLock) {
                        if (checkState(STATUS_DISPOSED) || !checkState(STATUS_WAIT_SCAN_RESULT)) {
                            return;
                        }
                        ar = (AsyncResult) msg.obj;
                        if (ar != null && ar.exception != null) {
                            onTriggerNetworkScanError((Integer) ar.userObj,
                                    ((CommandException) ar.exception).getCommandError());
                        }
                    }
                    break;
                case EVENT_MODEM_RESET:
                    synchronized (mLock) {
                        onModemReset();
                    }
                    break;
                default:
                    loge("handleMessage unexpected msg=" + msg.what);
                    break;
@@ -532,10 +552,13 @@ public class DomainSelectionConnection {
            if (!mRegisteredRegistrant) {
                mPhone.registerForEmergencyNetworkScan(mHandler,
                        EVENT_EMERGENCY_NETWORK_SCAN_RESULT, null);
                mPhone.mCi.registerForModemReset(mHandler, EVENT_MODEM_RESET, null);
                mRegisteredRegistrant = true;
            }
            setState(STATUS_WAIT_SCAN_RESULT);
            mPhone.triggerEmergencyNetworkScan(preferredNetworks, scanType, null);
            mPhone.triggerEmergencyNetworkScan(preferredNetworks, scanType,
                    mHandler.obtainMessage(EVENT_TRIGGER_NETWORK_SCAN_DONE,
                            Integer.valueOf(scanType)));
            mPendingScanRequest = null;
        }
    }
@@ -725,6 +748,7 @@ public class DomainSelectionConnection {
        setState(STATUS_DISPOSED);
        if (mRegisteredRegistrant) {
            mPhone.unregisterForEmergencyNetworkScan(mHandler);
            mPhone.mCi.unregisterForModemReset(mHandler);
            mRegisteredRegistrant = false;
        }
        onCancel(true);
@@ -749,6 +773,34 @@ public class DomainSelectionConnection {
        }
    }

    private void onTriggerNetworkScanError(int scanType, CommandException.Error error) {
        loge("onTriggerNetworkScanError scanType=" + scanType + ", error=" + error);

        if (shouldTerminateCallOnRadioNotAvailable()
                && error == CommandException.Error.RADIO_NOT_AVAILABLE) {
            clearState(STATUS_WAIT_SCAN_RESULT);
            onSelectionTerminated(DisconnectCause.POWER_OFF);
            dispose();
            return;
        }
    }

    private void onModemReset() {
        loge("onModemReset status=" + mStatus);
        if (!shouldTerminateCallOnRadioNotAvailable()) {
            return;
        }
        if (checkState(STATUS_DISPOSED) || checkState(STATUS_DOMAIN_SELECTED)) {
            return;
        }
        onSelectionTerminated(DisconnectCause.POWER_OFF);
        dispose();
    }

    private boolean shouldTerminateCallOnRadioNotAvailable() {
        return mIsEmergency && mSelectorType == DomainSelectionService.SELECTOR_TYPE_CALLING;
    }

    /**
     * Get the  preferred transport.
     *
+277 −0
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@ package com.android.internal.telephony.domainselection;

import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
import static android.telephony.DomainSelectionService.SCAN_TYPE_FULL_SERVICE;
import static android.telephony.DomainSelectionService.SCAN_TYPE_NO_PREFERENCE;
import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
import static android.telephony.DomainSelectionService.SELECTOR_TYPE_SMS;

import static com.google.common.truth.Truth.assertThat;

@@ -46,6 +48,7 @@ import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.DisconnectCause;
import android.telephony.DomainSelectionService;
import android.telephony.EmergencyRegistrationResult;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PreciseDisconnectCause;
import android.telephony.data.ApnSetting;
import android.telephony.ims.ImsReasonInfo;
@@ -55,6 +58,8 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;

import com.android.internal.telephony.CallFailCause;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IDomainSelector;
import com.android.internal.telephony.ITransportSelectorCallback;
import com.android.internal.telephony.ITransportSelectorResultCallback;
@@ -83,6 +88,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

    private static final String TELECOM_CALL_ID1 = "TC1";

    private CommandsInterface mCi;
    private DomainSelectionController mDomainSelectionController;
    private DomainSelectionConnection.DomainSelectionConnectionCallback mConnectionCallback;
    private DomainSelectionConnection mDsc;
@@ -91,6 +97,9 @@ public class DomainSelectionConnectionTest extends TelephonyTest {
    public void setUp() throws Exception {
        super.setUp(this.getClass().getSimpleName());

        mCi = Mockito.mock(CommandsInterface.class);
        mPhone.mCi = mCi;

        mDomainSelectionController = Mockito.mock(DomainSelectionController.class);
        doReturn(true).when(mDomainSelectionController).selectDomain(any(), any());
        mConnectionCallback =
@@ -187,6 +196,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        verify(mPhone).registerForEmergencyNetworkScan(
                handlerCaptor.capture(), eventCaptor.capture(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

@@ -235,6 +245,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {
        processAllMessages();

        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());
        verify(mPhone).triggerEmergencyNetworkScan(any(), anyInt(), any());

        wwanCallback.onCancel();
@@ -280,6 +291,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {
        verify(mPhone).cancelEmergencyNetworkScan(eq(true), msgCaptor.capture());

        verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
        verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());

        Message msg = msgCaptor.getValue();
@@ -295,6 +307,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        verify(mPhone).registerForEmergencyNetworkScan(
                handlerCaptor.capture(), eventCaptor.capture(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

@@ -350,6 +363,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        verify(mPhone).cancelEmergencyNetworkScan(eq(true), msgCaptor.capture());
        verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
        verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());

        Message msg = msgCaptor.getValue();
@@ -363,6 +377,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        // Verify that scan is requested.
        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());
        verify(mPhone).triggerEmergencyNetworkScan(any(), anyInt(), any());

        // Cancele scan after reset completes.
@@ -410,6 +425,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        verify(mPhone).cancelEmergencyNetworkScan(eq(true), msgCaptor.capture());
        verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
        verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());

        Message msg = msgCaptor.getValue();
@@ -430,9 +446,268 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        // Verify there is no scan request after reset completes.
        verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
        verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());
    }

    @Test
    @SmallTest
    public void testWwanSelectorCallbackOnRequestEmergencyNetworkScanAndRadioNotAvailableError()
            throws Exception {
        mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
                mDomainSelectionController);

        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();

        assertNotNull(transportCallback);

        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
                false, 0, TELECOM_CALL_ID1, null, null, null);

        mDsc.selectDomain(attr);

        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
        transportCallback.onCreated(domainSelector);

        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);

        assertNotNull(wwanCallback);

        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
        int scanType = SCAN_TYPE_NO_PREFERENCE;
        IWwanSelectorResultCallback resultCallback =
                Mockito.mock(IWwanSelectorResultCallback.class);

        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType,
                false, resultCallback);
        processAllMessages();

        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);

        verify(mPhone).registerForEmergencyNetworkScan(handlerCaptor.capture(), anyInt(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());
        processAllMessages();

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
                eq(scanType), msgCaptor.capture());

        Handler handler = handlerCaptor.getValue();
        Message msg = msgCaptor.getValue();

        assertNotNull(handler);
        assertNotNull(msg);

        CommandException commandException =
                new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE);
        handler.sendMessage(handler.obtainMessage(msg.what,
                new AsyncResult((Integer) scanType, null, commandException)));
        processAllMessages();

        verify(resultCallback, times(0)).onComplete(any());
        verify(mPhone).unregisterForEmergencyNetworkScan(any());
        verify(mCi).unregisterForModemReset(any());
        verify(mPhone, times(0)).cancelEmergencyNetworkScan(anyBoolean(), any());
        verify(mDomainSelectionController).removeConnection(eq(mDsc));
    }

    @Test
    @SmallTest
    public void testModemResetOnRequestEmergencyNetworkDuringNetworkScan()
            throws Exception {
        mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
                mDomainSelectionController);

        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();

        assertNotNull(transportCallback);

        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
                false, 0, TELECOM_CALL_ID1, null, null, null);

        mDsc.selectDomain(attr);

        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
        transportCallback.onCreated(domainSelector);

        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);

        assertNotNull(wwanCallback);

        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
        int scanType = SCAN_TYPE_FULL_SERVICE;
        IWwanSelectorResultCallback resultCallback =
                Mockito.mock(IWwanSelectorResultCallback.class);

        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, false,
                resultCallback);
        processAllMessages();

        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
        ArgumentCaptor<Integer> eventCaptor = ArgumentCaptor.forClass(Integer.class);

        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi).registerForModemReset(handlerCaptor.capture(), eventCaptor.capture(),
                any());
        processAllMessages();

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
                eq(scanType), any());

        Handler handler = handlerCaptor.getValue();
        Integer event = eventCaptor.getValue();

        assertNotNull(handler);
        assertNotNull(event);

        handler.sendMessage(handler.obtainMessage(event.intValue(),
                new AsyncResult(null, null, null)));
        processAllMessages();

        verify(resultCallback, times(0)).onComplete(any());
        verify(mPhone).unregisterForEmergencyNetworkScan(any());
        verify(mCi).unregisterForModemReset(any());
        verify(mPhone).cancelEmergencyNetworkScan(anyBoolean(), any());
    }

    @Test
    @SmallTest
    public void testModemResetOnRequestEmergencyNetworkDuringNetworkScanForSms()
            throws Exception {
        mDsc = createConnection(mPhone, SELECTOR_TYPE_SMS, true,
                mDomainSelectionController);

        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();

        assertNotNull(transportCallback);

        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_SMS, true,
                false, 0, TELECOM_CALL_ID1, null, null, null);

        mDsc.selectDomain(attr);

        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
        transportCallback.onCreated(domainSelector);

        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);

        assertNotNull(wwanCallback);

        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
        int scanType = SCAN_TYPE_FULL_SERVICE;
        IWwanSelectorResultCallback resultCallback =
                Mockito.mock(IWwanSelectorResultCallback.class);

        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, false,
                resultCallback);
        processAllMessages();

        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
        ArgumentCaptor<Integer> eventCaptor = ArgumentCaptor.forClass(Integer.class);

        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
        verify(mCi).registerForModemReset(handlerCaptor.capture(), eventCaptor.capture(),
                any());
        processAllMessages();

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
                eq(scanType), any());

        Handler handler = handlerCaptor.getValue();
        Integer event = eventCaptor.getValue();

        assertNotNull(handler);
        assertNotNull(event);

        handler.sendMessage(handler.obtainMessage(event.intValue(),
                new AsyncResult(null, null, null)));
        processAllMessages();

        verify(mPhone, times(0)).unregisterForEmergencyNetworkScan(any());
        verify(mCi, times(0)).unregisterForModemReset(any());
        verify(mPhone, times(0)).cancelEmergencyNetworkScan(anyBoolean(), any());
    }

    @Test
    @SmallTest
    public void testModemResetOnRequestEmergencyNetworkAfterNetworkScanDone()
            throws Exception {
        mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
                mDomainSelectionController);

        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();

        assertNotNull(transportCallback);

        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
                false, 0, TELECOM_CALL_ID1, null, null, null);

        mDsc.selectDomain(attr);

        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
        transportCallback.onCreated(domainSelector);

        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);

        assertNotNull(wwanCallback);

        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
        int scanType = SCAN_TYPE_FULL_SERVICE;
        IWwanSelectorResultCallback resultCallback =
                Mockito.mock(IWwanSelectorResultCallback.class);

        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, false,
                resultCallback);
        processAllMessages();

        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
        ArgumentCaptor<Integer> scanEventCaptor = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> resetEventCaptor = ArgumentCaptor.forClass(Integer.class);

        verify(mPhone).registerForEmergencyNetworkScan(any(), scanEventCaptor.capture(), any());
        verify(mCi).registerForModemReset(handlerCaptor.capture(),
                resetEventCaptor.capture(), any());
        processAllMessages();

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
                eq(scanType), any());

        Handler handler = handlerCaptor.getValue();
        Integer scanEvent = scanEventCaptor.getValue();
        Integer resetEvent = resetEventCaptor.getValue();

        assertNotNull(handler);
        assertNotNull(scanEvent);
        assertNotNull(resetEvent);

        EmergencyRegistrationResult regResult =
                new EmergencyRegistrationResult(UTRAN, 0, 0, true, false, 0, 0, "", "", "");
        handler.sendMessage(handler.obtainMessage(scanEvent,
                new AsyncResult(null, regResult, null)));
        processAllMessages();
        wwanCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS_PS, true);

        handler.sendMessage(handler.obtainMessage(resetEvent, new AsyncResult(null, null, null)));
        processAllMessages();

        verify(resultCallback).onComplete(any());
        verify(mPhone, times(0)).unregisterForEmergencyNetworkScan(any());
        verify(mCi, times(0)).unregisterForModemReset(any());
        verify(mPhone, times(0)).cancelEmergencyNetworkScan(anyBoolean(), any());
    }

    @Test
    @SmallTest
    public void testDomainSelectorCancelSelection() throws Exception {
@@ -601,6 +876,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        verify(mPhone).registerForEmergencyNetworkScan(
                handlerCaptor.capture(), eventCaptor.capture(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };

@@ -686,6 +962,7 @@ public class DomainSelectionConnectionTest extends TelephonyTest {

        verify(mPhone).registerForEmergencyNetworkScan(
                handlerCaptor.capture(), eventCaptor.capture(), any());
        verify(mCi).registerForModemReset(any(), anyInt(), any());

        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };