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

Commit 310aec61 authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Merge changes I16a9f413,I153bd511,I76f52a44,I5d9b3860 am: bde4d599 am: 5009f4f7

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1692968

Change-Id: I7c4d5edd1e7d76d99c6b7ac3fa55166df12f70ef
parents 50859d9f 5009f4f7
Loading
Loading
Loading
Loading
+35 −9
Original line number Diff line number Diff line
@@ -1545,6 +1545,11 @@ public class DcTracker extends Handler {
        return isInEcm && !isInImsEcm;
    }

    private boolean isHandoverPending(@ApnType int apnType) {
        List<Message> messageList = mHandoverCompletionMsgs.get(apnType);
        return messageList != null && messageList.size() > 0;
    }

    private void trySetupData(ApnContext apnContext, @RequestNetworkType int requestType,
            @Nullable Message onHandoverCompleteMsg) {
        if (onHandoverCompleteMsg != null) {
@@ -1576,6 +1581,19 @@ public class DcTracker extends Handler {
                str.append("isDataEnabled() = false. " + mDataEnabledSettings);
            }

            // Check if it fails because of the existing data is still disconnecting.
            if (dataConnectionReasons.containsOnly(
                    DataDisallowedReasonType.DATA_IS_DISCONNECTING)
                    && isHandoverPending(apnContext.getApnTypeBitmask())) {
                // Normally we don't retry when isDataAllow() returns false, because that's consider
                // pre-condition not met, for example, data not enabled by the user, or airplane
                // mode is on. If we retry in those cases, there will be significant power impact.
                // DATA_IS_DISCONNECTING is a special case we want to retry, and for the handover
                // case only.
                log("Data is disconnecting. Will retry handover later.");
                return;
            }

            // If this is a data retry, we should set the APN state to FAILED so it won't stay
            // in RETRYING forever.
            if (apnContext.getState() == DctConstants.State.RETRYING) {
@@ -2338,9 +2356,10 @@ public class DcTracker extends Handler {
        sendMessageDelayed(msg, delay);

        if (DBG) {
            log("startReconnect: delay=" + delay + " apn="
                    + apnContext + "reason: " + apnContext.getReason()
                    + " subId=" + mPhone.getSubId() + " request type=" + requestType);
            log("startReconnect: delay=" + delay + ", apn="
                    + apnContext + ", reason=" + apnContext.getReason()
                    + ", subId=" + mPhone.getSubId() + ", request type="
                    + requestTypeToString(requestType));
        }
    }

@@ -2653,7 +2672,6 @@ public class DcTracker extends Handler {
            switch(state) {
                case CONNECTING:
                case CONNECTED:
                case DISCONNECTING:
                    if (DBG) log("onEnableApn: APN in " + state + " state. Exit now.");
                    if (onHandoverCompleteMsg != null) {
                        sendHandoverCompleteMsg(onHandoverCompleteMsg, false, mTransportType,
@@ -3262,12 +3280,20 @@ public class DcTracker extends Handler {
            // we're not tying up the RIL command channel.
            // This also helps in any external dependency to turn off the context.
            if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");

            // See if there are still handover request pending that we need to retry handover
            // after previous data gets disconnected.
            if (isHandoverPending(apnContext.getApnTypeBitmask())) {
                if (DBG) log("Handover request pending. Retry handover immediately.");
                startReconnect(0, apnContext, REQUEST_TYPE_HANDOVER);
            } else {
                long delay = apnContext.getRetryAfterDisconnectDelay();
                if (delay > 0) {
                    // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
                    // the waiting APN list, which will also reset/reconfigure the retry manager.
                    startReconnect(delay, apnContext, REQUEST_TYPE_NORMAL);
                }
            }
        } else {
            boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
                    com.android.internal.R.bool.config_restartRadioAfterProvisioning);
+55 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
import android.util.Pair;
import android.util.SparseArray;

import androidx.test.filters.FlakyTest;

@@ -101,6 +102,7 @@ import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

@@ -115,6 +117,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@@ -805,6 +808,18 @@ public class DcTrackerTest extends TelephonyTest {
        }
    }

    private boolean isHandoverPending(int apnType) {
        try {
            Method method = DcTracker.class.getDeclaredMethod("isHandoverPending",
                    int.class);
            method.setAccessible(true);
            return (boolean) method.invoke(mDct, apnType);
        } catch (Exception e) {
            fail(e.toString());
            return false;
        }
    }

    private void sendInitializationEvents() {
        sendCarrierConfigChanged("");

@@ -2610,4 +2625,44 @@ public class DcTrackerTest extends TelephonyTest {
        }
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
    }

    @Test
    public void testRetryHandoverWhenDisconnecting() throws Exception {
        initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
        setUpDataConnection();
        SparseArray<ApnContext> apnContextsByType = Mockito.mock(SparseArray.class);
        ConcurrentHashMap<String, ApnContext> apnContexts = Mockito.mock(ConcurrentHashMap.class);
        doReturn(mApnContext).when(apnContextsByType).get(eq(ApnSetting.TYPE_IMS));
        doReturn(mApnContext).when(apnContexts).get(eq(ApnSetting.TYPE_IMS_STRING));
        doReturn(false).when(mApnContext).isConnectable();
        doReturn(DctConstants.State.DISCONNECTING).when(mApnContext).getState();
        replaceInstance(DcTracker.class, "mApnContextsByType", mDct, apnContextsByType);
        replaceInstance(DcTracker.class, "mApnContexts", mDct, apnContexts);

        sendInitializationEvents();

        logd("Sending EVENT_ENABLE_APN");
        // APN id 0 is APN_TYPE_DEFAULT
        mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_HANDOVER,
                mDct.obtainMessage(12345));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        assertTrue(isHandoverPending(ApnSetting.TYPE_IMS));

        // Verify no handover request was sent
        verify(mDataConnection, never()).bringUp(any(ApnContext.class), anyInt(), anyInt(),
                any(Message.class), anyInt(), anyInt(), anyInt(), anyBoolean());

        doReturn(DctConstants.State.RETRYING).when(mApnContext).getState();
        // Data now is disconnected
        doReturn(true).when(mApnContext).isConnectable();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE,
                new AsyncResult(Pair.create(mApnContext, 0), null, null)));

        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mDataConnection).bringUp(any(ApnContext.class), anyInt(), anyInt(),
                any(Message.class), anyInt(), eq(DcTracker.REQUEST_TYPE_HANDOVER), anyInt(),
                anyBoolean());
    }
}