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

Commit 9f4843e4 authored by Jack Yu's avatar Jack Yu Committed by Android (Google) Code Review
Browse files

Merge "Fixed IWLAN handover issues" into sc-dev

parents 7580ee7c 3f903c03
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -2716,11 +2716,26 @@ public class DcTracker extends Handler {
            DctConstants.State state = apnContext.getState();
            switch(state) {
                case CONNECTING:
                    if (onHandoverCompleteMsg != null) {
                        if (DBG) {
                            log("onEnableApn: already in CONNECTING state. Handover request "
                                    + "will be responded after connected.");
                        }
                        addHandoverCompleteMsg(onHandoverCompleteMsg, apnType);
                    } else {
                        if (DBG) log("onEnableApn: in CONNECTING state. Exit now.");
                    }
                    return;
                case CONNECTED:
                    if (DBG) log("onEnableApn: APN in " + state + " state. Exit now.");
                    if (onHandoverCompleteMsg != null) {
                        sendHandoverCompleteMsg(onHandoverCompleteMsg, false, mTransportType,
                        sendHandoverCompleteMsg(onHandoverCompleteMsg, true, mTransportType,
                                false);
                        if (DBG) {
                            log("onEnableApn: already in CONNECTED state. Consider as handover "
                                    + "succeeded");
                        }
                    } else {
                        if (DBG) log("onEnableApn: APN in CONNECTED state. Exit now.");
                    }
                    return;
                case IDLE:
+18 −2
Original line number Diff line number Diff line
@@ -373,7 +373,8 @@ public class TelephonyNetworkFactory extends NetworkFactory {
                                targetTransport, onCompleteMsg);
                        log("Requested handover " + ApnSetting.getApnTypeString(apnType)
                                + " to "
                                + AccessNetworkConstants.transportTypeToString(targetTransport));
                                + AccessNetworkConstants.transportTypeToString(targetTransport)
                                + ". " + networkRequest);
                        handoverPending = true;
                    } else {
                        // Request is there, but no actual data connection. In this case, just move
@@ -429,7 +430,22 @@ public class TelephonyNetworkFactory extends NetworkFactory {
                    // connection can be re-established on the other transport.
                    : DcTracker.RELEASE_TYPE_DETACH;
            releaseNetworkInternal(networkRequest, releaseType, originTransport);

            // Before updating the network request with the target transport, make sure the request
            // is still there because it's possible that connectivity service has already released
            // the network while handover is ongoing. If connectivity service already released
            // the network request, we need to tear down the just-handovered data connection on the
            // target transport.
            if (mNetworkRequests.containsKey(networkRequest)) {
                // Update it with the target transport.
                mNetworkRequests.put(networkRequest, targetTransport);
            } else {
                log("Network request was released before handover is completed. Now"
                        + " we need to release this network request. "
                        + networkRequest);
                releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
                        targetTransport);
            }
        } else {
            // If handover fails and requires to fallback, the context of target transport needs to
            // be released
+5 −3
Original line number Diff line number Diff line
@@ -320,10 +320,12 @@ public class TransportManager extends Handler {
     * @param transport The transport. Must be WWAN or WLAN.
     */
    private synchronized void setCurrentTransport(@ApnType int apnType, int transport) {
        mCurrentTransports.put(apnType, transport);
        Integer previousTransport = mCurrentTransports.put(apnType, transport);
        if (previousTransport == null || previousTransport != transport) {
            logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType)
                    + ", transport=" + AccessNetworkConstants.transportTypeToString(transport));
        }
    }

    private boolean isHandoverPending() {
        return mPendingHandoverApns.size() > 0;
+31 −0
Original line number Diff line number Diff line
@@ -2361,6 +2361,12 @@ public class DcTrackerTest extends TelephonyTest {
        return (boolean) field.get(mDct);
    }

    private Map<Integer, List<Message>> getHandoverCompletionMessages() throws Exception {
        Field field = DcTracker.class.getDeclaredField(("mHandoverCompletionMsgs"));
        field.setAccessible(true);
        return (Map<Integer, List<Message>>) field.get(mDct);
    }

    private void setUpTempNotMetered() {
        doReturn((int) TelephonyManager.NETWORK_TYPE_BITMASK_NR)
                .when(mPhone).getRadioAccessFamily();
@@ -2809,4 +2815,29 @@ public class DcTrackerTest extends TelephonyTest {
                eq(RetryManager.NO_SUGGESTED_RETRY_DELAY),
                eq(DcTracker.REQUEST_TYPE_NORMAL));
    }

    @Test
    public void testHandlingSecondHandoverRequest() 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.CONNECTING).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
        Message msg = mDct.obtainMessage(12345);
        mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_HANDOVER, msg);
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        Map<Integer, List<Message>> msgs = getHandoverCompletionMessages();
        // Make sure the messages was queued properly instead of fired right away.
        assertTrue(msgs.get(ApnSetting.TYPE_IMS).contains(msg));
    }
}
+54 −0
Original line number Diff line number Diff line
@@ -36,8 +36,10 @@ import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.AccessNetworkConstants;
import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;
@@ -64,6 +66,8 @@ import org.mockito.Mockito;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -84,6 +88,8 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {
    private final ArraySet<NetworkRequest> mAllNetworkRequestSet = new ArraySet<>();
    // List of requests active in DcTracker
    private final ArrayList<NetworkRequest> mNetworkRequestList = new ArrayList<>();
    // List of complete messages associated with the network requests
    private final Map<NetworkRequest, Message> mNetworkRequestMessageMap = new HashMap<>();

    private TelephonyNetworkFactory mTelephonyNetworkFactoryUT;
    private int mRequestId = 0;
@@ -162,8 +168,10 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {

        doAnswer(invocation -> {
            final NetworkRequest req = (NetworkRequest) invocation.getArguments()[0];
            final Message msg = (Message) invocation.getArguments()[2];
            mNetworkRequestList.add(req);
            mAllNetworkRequestSet.add(req);
            mNetworkRequestMessageMap.put(req, msg);
            return null;
        }).when(mDcTracker).requestNetwork(any(), anyInt(), any());

@@ -424,4 +432,50 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {
        verify(mDcTracker, times(1)).requestNetwork(any(), eq(1), any());
    }

    @Test
    @SmallTest
    public void testNetworkRequestReleasedDuringHandover() throws Exception {
        createMockedTelephonyComponents();
        doReturn(0).when(mSubscriptionController).getSubIdUsingPhoneId(0);
        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
                TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);

        activatePhoneInPhoneSwitcher(0, true);
        makeDefaultInternetRequest();

        NetworkRequest mmsNetworkRequest = makeSubSpecificMmsRequest(0);
        processAllMessages();

        Field f = TelephonyNetworkFactory.class.getDeclaredField("mInternalHandler");
        f.setAccessible(true);
        Handler h = (Handler) f.get(mTelephonyNetworkFactoryUT);

        HandoverCallback handoverCallback = mock(HandoverCallback.class);
        //Mockito.reset(mDcTracker);
        doReturn(mDataConnection).when(mDcTracker).getDataConnectionByApnType(anyString());
        doReturn(true).when(mDataConnection).isActive();

        HandoverParams hp = new HandoverParams(ApnSetting.TYPE_MMS,
                AccessNetworkConstants.TRANSPORT_TYPE_WLAN, handoverCallback);
        AsyncResult ar = new AsyncResult(null, hp, null);
        h.sendMessage(h.obtainMessage(5 /* EVENT_DATA_HANDOVER_NEEDED */, ar));
        processAllMessages();

        // Now release the network request while handover is still ongoing.
        mTelephonyNetworkFactoryUT.releaseNetworkFor(mmsNetworkRequest);
        processAllMessages();

        Message msg = mNetworkRequestMessageMap.get(mmsNetworkRequest);

        Bundle bundle = msg.getData();
        bundle.putParcelable("extra_network_request", mmsNetworkRequest);
        bundle.putBoolean("extra_success", true);
        bundle.putInt("extra_transport_type", AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
        bundle.putBoolean("extra_handover_failure_fallback", false);
        h.sendMessage(msg);
        processAllMessages();

        // Ensure the release is called one more time after the normal release
        verify(mDcTracker, times(2)).releaseNetwork(any(), eq(1));
    }
}