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

Commit 59e2bce8 authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Fix empty network scan result" into main

parents 544f85c2 6e4ac4bd
Loading
Loading
Loading
Loading
+17 −75
Original line number Diff line number Diff line
@@ -48,13 +48,12 @@ import com.android.internal.telephony.flags.Flags;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.network.telephony.scan.NetworkScanRepository;
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanCellInfos;
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanComplete;
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanError;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.ThreadUtils;

import com.google.common.collect.ImmutableList;

import kotlin.Unit;

import java.util.ArrayList;
@@ -83,7 +82,8 @@ public class NetworkSelectSettings extends DashboardFragment {
    private View mProgressHeader;
    private Preference mStatusMessagePreference;
    @VisibleForTesting
    List<CellInfo> mCellInfoList;
    @NonNull
    List<CellInfo> mCellInfoList = ImmutableList.of();
    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private TelephonyManager mTelephonyManager;
    private SatelliteManager mSatelliteManager;
@@ -96,7 +96,6 @@ public class NetworkSelectSettings extends DashboardFragment {
    private AtomicBoolean mShouldFilterOutSatellitePlmn = new AtomicBoolean();

    private NetworkScanRepository mNetworkScanRepository;
    private boolean mUpdateScanResult = false;

    private NetworkSelectRepository mNetworkSelectRepository;

@@ -213,38 +212,16 @@ public class NetworkSelectSettings extends DashboardFragment {
    }

    private void launchNetworkScan() {
        setProgressBarVisible(true);
        mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), (networkScanResult) -> {
            if (!mUpdateScanResult) {
                // Not update UI if not in scan mode.
                return Unit.INSTANCE;
            }
            if (networkScanResult instanceof NetworkScanCellInfos networkScanCellInfos) {
                scanResultHandler(networkScanCellInfos.getCellInfos());
                return Unit.INSTANCE;
            }
            if (!isPreferenceScreenEnabled()) {
                clearPreferenceSummary();
                enablePreferenceScreen(true);
            } else if (networkScanResult instanceof NetworkScanComplete
                    && mCellInfoList == null) {
                // In case the scan timeout before getting any results
                addMessagePreference(R.string.empty_networks_list);
            } else if (networkScanResult instanceof NetworkScanError) {
                addMessagePreference(R.string.network_query_error);
            if (isPreferenceScreenEnabled()) {
                scanResultHandler(networkScanResult);
            }

            return Unit.INSTANCE;
        });
    }

    @Override
    public void onStart() {
        super.onStart();

        setProgressBarVisible(true);
        mUpdateScanResult = true;
    }

    /**
     * Update forbidden PLMNs from the USIM App
     */
@@ -268,8 +245,6 @@ public class NetworkSelectSettings extends DashboardFragment {
            return false;
        }

        mUpdateScanResult = false;

        // Refresh the last selected item in case users reselect network.
        clearPreferenceSummary();
        if (mSelectedPreference != null) {
@@ -380,27 +355,19 @@ public class NetworkSelectSettings extends DashboardFragment {
        }
    }

    @Keep
    @VisibleForTesting
    protected void scanResultHandler(List<CellInfo> results) {
        mCellInfoList = filterOutSatellitePlmn(results);
    protected void scanResultHandler(NetworkScanRepository.NetworkScanResult results) {
        mCellInfoList = filterOutSatellitePlmn(results.getCellInfos());
        Log.d(TAG, "CellInfoList: " + CellInfoUtil.cellInfoListToString(mCellInfoList));
        if (mCellInfoList != null && mCellInfoList.size() != 0) {
            final NetworkOperatorPreference connectedPref = updateAllPreferenceCategory();
            if (connectedPref != null) {
                // update selected preference instance into connected preference
                if (mSelectedPreference != null) {
                    mSelectedPreference = connectedPref;
                }
            } else if (!isPreferenceScreenEnabled()) {
                mSelectedPreference.setSummary(R.string.network_connecting);
            }
            enablePreferenceScreen(true);
        } else if (isPreferenceScreenEnabled()) {
        updateAllPreferenceCategory();
        NetworkScanRepository.NetworkScanState state = results.getState();
        if (state == NetworkScanRepository.NetworkScanState.ERROR) {
            addMessagePreference(R.string.network_query_error);
        } else if (mCellInfoList.isEmpty()) {
            addMessagePreference(R.string.empty_networks_list);
            // keep showing progress bar, it will be stopped when error or completed
            setProgressBarVisible(true);
        }
        // keep showing progress bar, it will be stopped when error or completed
        setProgressBarVisible(state == NetworkScanRepository.NetworkScanState.ACTIVE);
    }

    @Keep
@@ -417,11 +384,8 @@ public class NetworkSelectSettings extends DashboardFragment {

    /**
     * Update the content of network operators list.
     *
     * @return preference which shows connected
     */
    @Nullable
    private NetworkOperatorPreference updateAllPreferenceCategory() {
    private void updateAllPreferenceCategory() {
        int numberOfPreferences = mPreferenceCategory.getPreferenceCount();

        // remove unused preferences
@@ -432,7 +396,6 @@ public class NetworkSelectSettings extends DashboardFragment {
        }

        // update the content of preference
        NetworkOperatorPreference connectedPref = null;
        for (int index = 0; index < mCellInfoList.size(); index++) {
            final CellInfo cellInfo = mCellInfoList.get(index);

@@ -457,23 +420,10 @@ public class NetworkSelectSettings extends DashboardFragment {

            if (mCellInfoList.get(index).isRegistered()) {
                pref.setSummary(R.string.network_connected);
                connectedPref = pref;
            } else {
                pref.setSummary(null);
            }
        }

        // update selected preference instance by index
        for (int index = 0; index < mCellInfoList.size(); index++) {
            final CellInfo cellInfo = mCellInfoList.get(index);

            if ((mSelectedPreference != null) && mSelectedPreference.isSameCell(cellInfo)) {
                mSelectedPreference = (NetworkOperatorPreference)
                        (mPreferenceCategory.getPreference(index));
            }
        }

        return connectedPref;
    }

    /**
@@ -524,13 +474,6 @@ public class NetworkSelectSettings extends DashboardFragment {
        }
    }

    private boolean isProgressBarVisible() {
        if (mProgressHeader == null) {
            return false;
        }
        return (mProgressHeader.getVisibility() == View.VISIBLE);
    }

    protected void setProgressBarVisible(boolean visible) {
        if (mProgressHeader != null) {
            mProgressHeader.setVisibility(visible ? View.VISIBLE : View.GONE);
@@ -538,7 +481,6 @@ public class NetworkSelectSettings extends DashboardFragment {
    }

    private void addMessagePreference(int messageId) {
        setProgressBarVisible(false);
        mStatusMessagePreference.setTitle(messageId);
        mPreferenceCategory.removeAll();
        mPreferenceCategory.addPreference(mStatusMessagePreference);
+26 −16
Original line number Diff line number Diff line
@@ -27,25 +27,29 @@ import android.telephony.TelephonyScanManager
import android.util.Log
import androidx.lifecycle.LifecycleOwner
import com.android.settings.R
import com.android.settings.network.telephony.CellInfoUtil
import com.android.settings.network.telephony.CellInfoUtil.getNetworkTitle
import com.android.settings.network.telephony.telephonyManager
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.onEach

class NetworkScanRepository(private val context: Context, subId: Int) {
    sealed interface NetworkScanResult
    enum class NetworkScanState {
        ACTIVE, COMPLETE, ERROR
    }

    data class NetworkScanCellInfos(val cellInfos: List<CellInfo>) : NetworkScanResult
    data object NetworkScanComplete : NetworkScanResult
    data class NetworkScanError(val error: Int) : NetworkScanResult
    data class NetworkScanResult(
        val state: NetworkScanState,
        val cellInfos: List<CellInfo>,
    )

    private val telephonyManager =
        context.getSystemService(TelephonyManager::class.java)!!.createForSubscriptionId(subId)
    private val telephonyManager = context.telephonyManager(subId)

    /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
    fun launchNetworkScan(lifecycleOwner: LifecycleOwner, onResult: (NetworkScanResult) -> Unit) {
@@ -65,23 +69,29 @@ class NetworkScanRepository(private val context: Context, subId: Int) {
    }

    fun networkScanFlow(): Flow<NetworkScanResult> = callbackFlow {
        var state = NetworkScanState.ACTIVE
        var cellInfos: List<CellInfo> = emptyList()

        val callback = object : TelephonyScanManager.NetworkScanCallback() {
            override fun onResults(results: List<CellInfo>) {
                val cellInfos = results.distinctBy { CellInfoScanKey(it) }
                trySend(NetworkScanCellInfos(cellInfos))
                Log.d(TAG, "CellInfoList: ${CellInfoUtil.cellInfoListToString(cellInfos)}")
                cellInfos = results.distinctBy { CellInfoScanKey(it) }
                sendResult()
            }

            override fun onComplete() {
                trySend(NetworkScanComplete)
                close()
                Log.d(TAG, "onComplete")
                state = NetworkScanState.COMPLETE
                sendResult()
                // Don't call close() here since onComplete() could happens before onResults()
            }

            override fun onError(error: Int) {
                trySend(NetworkScanError(error))
                state = NetworkScanState.ERROR
                sendResult()
                close()
                Log.d(TAG, "onError: $error")
            }

            private fun sendResult() {
                trySend(NetworkScanResult(state, cellInfos))
            }
        }

@@ -92,7 +102,7 @@ class NetworkScanRepository(private val context: Context, subId: Int) {
        )

        awaitClose { networkScan.stopScan() }
    }.flowOn(Dispatchers.Default)
    }.conflate().onEach { Log.d(TAG, "networkScanFlow: $it") }.flowOn(Dispatchers.Default)

    /** Create network scan for allowed network types. */
    private fun createNetworkScan(): NetworkScanRequest {
+25 −11
Original line number Diff line number Diff line
@@ -32,9 +32,6 @@ import android.telephony.TelephonyManager.NETWORK_CLASS_BITMASK_5G
import android.telephony.TelephonyScanManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanCellInfos
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanComplete
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanError
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spa.testutils.toListWithTimeout
import com.google.common.truth.Truth.assertThat
@@ -88,7 +85,12 @@ class NetworkScanRepositoryTest {

        callback?.onResults(cellInfos)

        assertThat(listDeferred.await()).containsExactly(NetworkScanCellInfos(cellInfos))
        assertThat(listDeferred.await()).containsExactly(
            NetworkScanRepository.NetworkScanResult(
                state = NetworkScanRepository.NetworkScanState.ACTIVE,
                cellInfos = cellInfos,
            )
        )
    }

    @Test
@@ -100,7 +102,12 @@ class NetworkScanRepositoryTest {

        callback?.onComplete()

        assertThat(listDeferred.await()).containsExactly(NetworkScanComplete)
        assertThat(listDeferred.await()).containsExactly(
            NetworkScanRepository.NetworkScanResult(
                state = NetworkScanRepository.NetworkScanState.COMPLETE,
                cellInfos = emptyList(),
            )
        )
    }

    @Test
@@ -112,7 +119,12 @@ class NetworkScanRepositoryTest {

        callback?.onError(1)

        assertThat(listDeferred.await()).containsExactly(NetworkScanError(1))
        assertThat(listDeferred.await()).containsExactly(
            NetworkScanRepository.NetworkScanResult(
                state = NetworkScanRepository.NetworkScanState.ERROR,
                cellInfos = emptyList(),
            )
        )
    }

    @Test
@@ -133,12 +145,13 @@ class NetworkScanRepositoryTest {
        callback?.onResults(cellInfos)

        assertThat(listDeferred.await()).containsExactly(
            NetworkScanCellInfos(
                listOf(
            NetworkScanRepository.NetworkScanResult(
                state = NetworkScanRepository.NetworkScanState.ACTIVE,
                cellInfos = listOf(
                    createCellInfoLte("123", false),
                    createCellInfoLte("124", true),
                    createCellInfoGsm("123", false),
                )
                ),
            )
        )
    }
@@ -162,8 +175,9 @@ class NetworkScanRepositoryTest {
        callback?.onResults(cellInfos)

        assertThat(listDeferred.await()).containsExactly(
            NetworkScanCellInfos(
                listOf(
            NetworkScanRepository.NetworkScanResult(
                state = NetworkScanRepository.NetworkScanState.ACTIVE,
                cellInfos = listOf(
                    createCellInfoLte("123", false),
                    createCellInfoLte("123", true),
                    createCellInfoLte("124", false),
+11 −3
Original line number Diff line number Diff line
@@ -44,8 +44,12 @@ import androidx.preference.PreferenceManager;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;

import com.android.settings.network.telephony.scan.NetworkScanRepository;
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanResult;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

import com.google.common.collect.ImmutableList;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -163,8 +167,7 @@ public class NetworkSelectSettingsTest {
        }

        @Override
        protected NetworkOperatorPreference
                createNetworkOperatorPreference(CellInfo cellInfo) {
        protected NetworkOperatorPreference createNetworkOperatorPreference(CellInfo cellInfo) {
            NetworkOperatorPreference pref = super.createNetworkOperatorPreference(cellInfo);
            if (cellInfo == mTestEnv.mCellInfo1) {
                pref.updateCell(cellInfo, mTestEnv.mCellId1);
@@ -183,9 +186,14 @@ public class NetworkSelectSettingsTest {
    @Test
    @UiThreadTest
    public void updateAllPreferenceCategory_correctOrderingPreference() {
        NetworkScanResult result = new NetworkScanResult(
                NetworkScanRepository.NetworkScanState.COMPLETE,
                ImmutableList.of(mCellInfo1, mCellInfo2));
        mNetworkSelectSettings.onCreateInitialization();
        mNetworkSelectSettings.enablePreferenceScreen(true);
        mNetworkSelectSettings.scanResultHandler(Arrays.asList(mCellInfo1, mCellInfo2));

        mNetworkSelectSettings.scanResultHandler(result);

        assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
        final NetworkOperatorPreference preference =
                (NetworkOperatorPreference) mPreferenceCategory.getPreference(1);