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

Commit 193f97c7 authored by SongFerngWang's avatar SongFerngWang
Browse files

Network selection add NGRAN when device support SA

Bug: 187148937
Test: build pass.
atest NetworkScanHelperTest (pass)

Change-Id: I1ed3eae3bda39eb702bc135b0c698f8df7c280d7
parent 29da5abc
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -21,11 +21,14 @@ import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.CellInfo;
import android.telephony.NetworkScan;
import android.telephony.NetworkScanRequest;
import android.telephony.PhoneCapability;
import android.telephony.RadioAccessSpecifier;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyScanManager;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.internal.telephony.CellNetworkScanResult;

import com.google.common.util.concurrent.FutureCallback;
@@ -37,6 +40,7 @@ import com.google.common.util.concurrent.SettableFuture;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
@@ -111,10 +115,14 @@ public class NetworkScanHelper {
    public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2;

    /** The constants below are used in the async network scan. */
    private static final boolean INCREMENTAL_RESULTS = true;
    private static final int SEARCH_PERIODICITY_SEC = 5;
    private static final int MAX_SEARCH_TIME_SEC = 300;
    private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
    @VisibleForTesting
    static final boolean INCREMENTAL_RESULTS = true;
    @VisibleForTesting
    static final int SEARCH_PERIODICITY_SEC = 5;
    @VisibleForTesting
    static final int MAX_SEARCH_TIME_SEC = 300;
    @VisibleForTesting
    static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;

    private final NetworkScanCallback mNetworkScanCallback;
    private final TelephonyManager mTelephonyManager;
@@ -133,7 +141,8 @@ public class NetworkScanHelper {
        mExecutor = executor;
    }

    private NetworkScanRequest createNetworkScanForPreferredAccessNetworks() {
    @VisibleForTesting
    NetworkScanRequest createNetworkScanForPreferredAccessNetworks() {
        long networkTypeBitmap3gpp = mTelephonyManager.getPreferredNetworkTypeBitmask()
                & TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP;

@@ -161,14 +170,13 @@ public class NetworkScanHelper {
        // a 5G network, which means that it shouldn't scan for 5G at the expense of battery as
        // part of the manual network selection process.
        //
        // FIXME(b/151119451): re-enable this code once there is a way to distinguish SA from NSA
        // support in the modem.
        //
        // if (networkTypeBitmap3gpp == 0
        //        || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_5G) != 0) {
        //    radioAccessSpecifiers.add(
        //            new RadioAccessSpecifier(AccessNetworkType.NGRAN, null, null));
        // }
        if (networkTypeBitmap3gpp == 0
                || (hasNrSaCapability()
                && (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_5G) != 0)) {
            radioAccessSpecifiers.add(
                    new RadioAccessSpecifier(AccessNetworkType.NGRAN, null, null));
            Log.d(TAG, "radioAccessSpecifiers add NGRAN.");
        }

        return new NetworkScanRequest(
                NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
@@ -253,6 +261,12 @@ public class NetworkScanHelper {
        mNetworkScanCallback.onError(errCode);
    }

    private boolean hasNrSaCapability() {
        return Arrays.stream(
                mTelephonyManager.getPhoneCapability().getDeviceNrCapabilities())
                .anyMatch(i -> i == PhoneCapability.DEVICE_NR_CAPABILITY_SA);
    }

    /**
     * Converts the status code of {@link CellNetworkScanResult} to one of the
     * {@link NetworkScan.ScanErrorCode}.
+92 −6
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 * Copyright (C) 2021 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.
@@ -18,6 +18,7 @@ package com.android.settings.network.telephony;

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

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
@@ -27,12 +28,18 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.telephony.AccessNetworkConstants;
import android.telephony.CellInfo;
import android.telephony.ModemInfo;
import android.telephony.NetworkScan;
import android.telephony.NetworkScanRequest;
import android.telephony.PhoneCapability;
import android.telephony.RadioAccessSpecifier;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyScanManager;

import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -41,22 +48,20 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RunWith(RobolectricTestRunner.class)
@RunWith(AndroidJUnit4.class)
public class NetworkScanHelperTest {

    @Mock
    private TelephonyManager mTelephonyManager;

    @Mock
    private List<CellInfo> mCellInfos;

    @Mock
    private NetworkScanHelper.NetworkScanCallback mNetworkScanCallback;

@@ -70,7 +75,7 @@ public class NetworkScanHelperTest {

    private NetworkScan mNetworkScan;

    private class NetworkScanMock extends NetworkScan {
    public class NetworkScanMock extends NetworkScan {
        NetworkScanMock(int scanId, int subId) {
            super(scanId, subId);
        }
@@ -163,6 +168,87 @@ public class NetworkScanHelperTest {
        verify(mNetworkScan, times(1)).stopScan();
    }

    @Test
    public void createNetworkScanForPreferredAccessNetworks_deviceNoNrSa_noNgran() {
        int[] deviceNrCapabilities = new int[]{PhoneCapability.DEVICE_NR_CAPABILITY_NSA};
        PhoneCapability phoneCapability = createPhoneCapability(deviceNrCapabilities);
        doReturn(TelephonyManager.NETWORK_CLASS_BITMASK_2G
                | TelephonyManager.NETWORK_CLASS_BITMASK_3G
                | TelephonyManager.NETWORK_CLASS_BITMASK_4G
                | TelephonyManager.NETWORK_CLASS_BITMASK_5G).when(
                mTelephonyManager).getPreferredNetworkTypeBitmask();
        doReturn(phoneCapability).when(mTelephonyManager).getPhoneCapability();
        List<RadioAccessSpecifier> radioAccessSpecifiers = new ArrayList<>();
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.GERAN, null,
                        null));
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.UTRAN, null,
                        null));
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.EUTRAN, null,
                        null));
        NetworkScanRequest expectedNetworkScanRequest = createNetworkScanRequest(
                radioAccessSpecifiers);

        assertEquals(expectedNetworkScanRequest,
                mNetworkScanHelper.createNetworkScanForPreferredAccessNetworks());
    }

    @Test
    public void createNetworkScanForPreferredAccessNetworks_deviceHasNrSa_hasNgran() {
        int[] deviceNrCapabilities = new int[]{PhoneCapability.DEVICE_NR_CAPABILITY_NSA,
                PhoneCapability.DEVICE_NR_CAPABILITY_SA};
        PhoneCapability phoneCapability = createPhoneCapability(deviceNrCapabilities);
        doReturn(TelephonyManager.NETWORK_CLASS_BITMASK_2G
                | TelephonyManager.NETWORK_CLASS_BITMASK_3G
                | TelephonyManager.NETWORK_CLASS_BITMASK_4G
                | TelephonyManager.NETWORK_CLASS_BITMASK_5G).when(
                mTelephonyManager).getPreferredNetworkTypeBitmask();
        doReturn(phoneCapability).when(mTelephonyManager).getPhoneCapability();
        List<RadioAccessSpecifier> radioAccessSpecifiers = new ArrayList<>();
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.GERAN, null,
                        null));
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.UTRAN, null,
                        null));
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.EUTRAN, null,
                        null));
        radioAccessSpecifiers.add(
                new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.NGRAN, null,
                        null));
        NetworkScanRequest expectedNetworkScanRequest = createNetworkScanRequest(
                radioAccessSpecifiers);

        assertEquals(expectedNetworkScanRequest,
                mNetworkScanHelper.createNetworkScanForPreferredAccessNetworks());
    }

    private PhoneCapability createPhoneCapability(int[] deviceNrCapabilities) {
        int maxActiveVoiceCalls = 1;
        int maxActiveData = 2;
        ModemInfo modemInfo = new ModemInfo(1, 2, true, false);
        List<ModemInfo> logicalModemList = new ArrayList<>();
        logicalModemList.add(modemInfo);
        return new PhoneCapability(maxActiveVoiceCalls, maxActiveData,
                logicalModemList, false, deviceNrCapabilities);
    }

    private NetworkScanRequest createNetworkScanRequest(
            List<RadioAccessSpecifier> radioAccessSpecifiers) {
        return new NetworkScanRequest(
                NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
                radioAccessSpecifiers.toArray(
                        new RadioAccessSpecifier[radioAccessSpecifiers.size()]),
                mNetworkScanHelper.SEARCH_PERIODICITY_SEC,
                mNetworkScanHelper.MAX_SEARCH_TIME_SEC,
                mNetworkScanHelper.INCREMENTAL_RESULTS,
                mNetworkScanHelper.INCREMENTAL_RESULTS_PERIODICITY_SEC,
                null /* List of PLMN ids (MCC-MNC) */);
    }

    private void startNetworkScan_incremental(boolean waitForCompletion) {
        mNetworkScanHelper.startNetworkScan(
                NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS);