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

Commit 2f040002 authored by Jack Yu's avatar Jack Yu Committed by android-build-merger
Browse files

Merge "Fixed handover not working issue" am: 7d65a58b

am: 98015a44

Change-Id: Iee1422e24ed138d9032588492134dd190748e50e
parents f14052a1 98015a44
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.telephony.Rlog;
import android.telephony.data.ApnSetting;
import android.telephony.data.ApnSetting.ApnType;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.dataconnection.AccessNetworksManager.QualifiedNetworks;
import com.android.internal.util.ArrayUtils;
@@ -122,7 +123,11 @@ public class TransportManager extends Handler {
     */
    private final RegistrantList mHandoverNeededEventRegistrants;

    static final class HandoverParams {
    /**
     * Handover parameters
     */
    @VisibleForTesting
    public static final class HandoverParams {
        public final @ApnType int apnType;
        public final int targetTransport;
        HandoverParams(int apnType, int targetTransport) {
@@ -134,10 +139,6 @@ public class TransportManager extends Handler {
    public TransportManager(Phone phone) {
        mPhone = phone;
        mAccessNetworksManager = new AccessNetworksManager(phone);

        mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
                EVENT_QUALIFIED_NETWORKS_CHANGED);

        mCurrentAvailableNetworks = new ConcurrentHashMap<>();
        mCurrentTransports = new ConcurrentHashMap<>();
        mHandoverNeededEventRegistrants = new RegistrantList();
@@ -147,6 +148,8 @@ public class TransportManager extends Handler {
            // the IWLAN ones.
            mAvailableTransports = new int[]{TransportType.WWAN};
        } else {
            mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
                    EVENT_QUALIFIED_NETWORKS_CHANGED);
            mAvailableTransports = new int[]{TransportType.WWAN, TransportType.WLAN};
        }
    }
@@ -211,14 +214,17 @@ public class TransportManager extends Handler {
        log("updateAvailableNetworks: " + networksList);
        for (QualifiedNetworks networks : networksList) {
            if (areNetworksValid(networks)) {
                mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
                if (isHandoverNeeded(networks)) {
                    mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
                    // If handover is needed, perform the handover works. For now we only pick the
                    // first element because it's the most preferred. In the future we should also
                    // consider the rest in the list, for example, the first one violates
                    // carrier/user policy.
                    int targetTransport = ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(
                            networks.qualifiedNetworks[0]);
                    log("Handover needed for APN type: "
                            + ApnSetting.getApnTypeString(networks.apnType) + ", target transport: "
                            + TransportType.toString(targetTransport));
                    mHandoverNeededEventRegistrants.notifyResult(
                            new HandoverParams(networks.apnType, targetTransport));

@@ -227,6 +233,7 @@ public class TransportManager extends Handler {
                    // transport.
                    log("Handover not needed for APN type: "
                            + ApnSetting.getApnTypeString(networks.apnType));
                    mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
                    int transport = TransportType.WWAN;
                    if (!ArrayUtils.isEmpty(networks.qualifiedNetworks)
                            && ACCESS_NETWORK_TRANSPORT_TYPE_MAP.containsKey(
+22 −4
Original line number Diff line number Diff line
@@ -16,16 +16,17 @@

package com.android.internal.telephony.dataconnection;

import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -191,8 +192,7 @@ public class AccessNetworksManager {
            }

            if (!qualifiedNetworksList.isEmpty()) {
                mQualifiedNetworksChangedRegistrants.notifyRegistrants(
                        new AsyncResult(null, qualifiedNetworksList, null));
                mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList);
            }
        }
    }
@@ -290,6 +290,17 @@ public class AccessNetworksManager {
        return packageName;
    }


    private @NonNull List<QualifiedNetworks> getQualifiedNetworksList() {
        List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
        for (int i = 0; i < mAvailableNetworks.size(); i++) {
            qualifiedNetworksList.add(new QualifiedNetworks(mAvailableNetworks.keyAt(i),
                    mAvailableNetworks.valueAt(i)));
        }

        return qualifiedNetworksList;
    }

    /**
     * Register for qualified networks changed event.
     *
@@ -298,7 +309,14 @@ public class AccessNetworksManager {
     */
    public void registerForQualifiedNetworksChanged(Handler h, int what) {
        if (h != null) {
            mQualifiedNetworksChangedRegistrants.addUnique(h, what, null);
            Registrant r = new Registrant(h, what, null);
            mQualifiedNetworksChangedRegistrants.add(r);

            // Notify for the first time if there is already something in the available network
            // list.
            if (mAvailableNetworks.size() != 0) {
                r.notifyResult(getQualifiedNetworksList());
            }
        }
    }

+175 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.dataconnection;

import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.dataconnection.AccessNetworksManager.QualifiedNetworks;
import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TransportManagerTest extends TelephonyTest {
    private static final int EVENT_HANDOVER_NEEDED = 1;

    @Mock
    private Handler mTestHandler;

    private TransportManager mTransportManager;

    private TransportManagerTestHandler mTransportManagerTestHandler;

    private class TransportManagerTestHandler extends HandlerThread {

        private TransportManagerTestHandler(String name) {
            super(name);
        }

        @Override
        public void onLooperPrepared() {
            mTransportManager = new TransportManager(mPhone);
            setReady(true);
        }
    }

    @Before
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());
        mTransportManagerTestHandler = new TransportManagerTestHandler(TAG);
        mTransportManagerTestHandler.start();
        waitUntilReady();
    }

    @After
    public void tearDown() throws Exception {
        mTransportManagerTestHandler.quit();
        mTransportManagerTestHandler.join();
        super.tearDown();
    }

    @Test
    @SmallTest
    public void testHandoverNeeded() throws Exception {
        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);

        // Initial qualified networks
        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
                new QualifiedNetworks(ApnSetting.TYPE_IMS,
                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
                                AccessNetworkType.IWLAN})));
        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
                new AsyncResult(null, networkList, null)).sendToTarget();
        waitForMs(100);
        // Verify handover needed event was not sent
        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());

        // Now change the order of qualified networks by putting IWLAN first
        networkList = new ArrayList<>(Arrays.asList(
                new QualifiedNetworks(ApnSetting.TYPE_IMS,
                        new int[]{AccessNetworkType.IWLAN, AccessNetworkType.UTRAN,
                                AccessNetworkType.EUTRAN})));
        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
                new AsyncResult(null, networkList, null)).sendToTarget();
        waitForMs(100);

        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);

        // Verify handover needed event was sent and the the target transport is WLAN.
        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
                anyLong());
        Message message = messageArgumentCaptor.getValue();
        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
        AsyncResult ar = (AsyncResult) message.obj;
        HandoverParams params = (HandoverParams) ar.result;
        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
        assertEquals(TransportType.WLAN, params.targetTransport);

        // Now change the order of qualified networks by putting UTRAN first
        networkList = new ArrayList<>(Arrays.asList(
                new QualifiedNetworks(ApnSetting.TYPE_IMS,
                        new int[]{AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
                                AccessNetworkType.IWLAN})));
        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
                new AsyncResult(null, networkList, null)).sendToTarget();
        waitForMs(100);

        messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);

        // Verify handover needed event was sent and the the target transport is WWAN.
        verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
                anyLong());
        message = messageArgumentCaptor.getValue();
        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
        ar = (AsyncResult) message.obj;
        params = (HandoverParams) ar.result;
        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
        assertEquals(TransportType.WWAN, params.targetTransport);
    }

    @Test
    @SmallTest
    public void testHandoverNotNeeded() throws Exception {
        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);

        // Initial qualified networks
        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
                new QualifiedNetworks(ApnSetting.TYPE_IMS,
                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
                                AccessNetworkType.IWLAN})));
        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
                new AsyncResult(null, networkList, null)).sendToTarget();
        waitForMs(100);
        // Verify handover needed event was not sent
        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());

        // Now change the order of qualified networks by swapping EUTRAN and UTRAN.
        networkList = new ArrayList<>(Arrays.asList(
                new QualifiedNetworks(ApnSetting.TYPE_IMS,
                        new int[]{AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
                                AccessNetworkType.IWLAN})));
        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
                new AsyncResult(null, networkList, null)).sendToTarget();
        waitForMs(100);
        // Verify handover needed event was not sent
        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
    }
}