diff --git a/res/layout/face_enroll_button.xml b/res/layout/face_enroll_button.xml
index 6266650..73fbd77 100644
--- a/res/layout/face_enroll_button.xml
+++ b/res/layout/face_enroll_button.xml
@@ -27,6 +27,7 @@
         style="@style/SudGlifButton.Primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginStart="0dp"
         android:layout_gravity="start"
         android:text="@string/security_settings_face_settings_enroll"/>
 
diff --git a/res/layout/face_remove_button.xml b/res/layout/face_remove_button.xml
index 2c2497a..f281961 100644
--- a/res/layout/face_remove_button.xml
+++ b/res/layout/face_remove_button.xml
@@ -27,6 +27,7 @@
         style="@style/SudGlifButton.Primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginStart="0dp"
         android:layout_gravity="start"
         android:text="@string/security_settings_face_settings_remove_face_model"/>
 
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index ec63c9a..42379b4 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -59,9 +59,8 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mBatteryUsageProgressBarPref = screen.findPreference(getPreferenceKey());
-        // Set up loading text first to prevent layout flaky before info loaded.
-        mBatteryUsageProgressBarPref.setBottomSummary(
-                mContext.getString(R.string.settings_license_activity_loading));
+        // Set up empty space text first to prevent layout flaky before info loaded.
+        mBatteryUsageProgressBarPref.setBottomSummary(" ");
 
         if (com.android.settings.Utils.isBatteryPresent(mContext)) {
             quickUpdateHeaderPreference();
diff --git a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
index eb833b1..b56c1b9 100644
--- a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
@@ -31,6 +31,10 @@
         super(context, preferenceKey, lifecycle, lifecycleOwner);
     }
 
+    public CallsDefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
     @Override
     protected int getDefaultSubscriptionId() {
         int defaultCallSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
diff --git a/src/com/android/settings/network/telephony/CellInfoUtil.kt b/src/com/android/settings/network/telephony/CellInfoUtil.kt
index c7b6b24..51f60e7 100644
--- a/src/com/android/settings/network/telephony/CellInfoUtil.kt
+++ b/src/com/android/settings/network/telephony/CellInfoUtil.kt
@@ -82,7 +82,7 @@
      */
     @JvmStatic
     fun cellInfoListToString(cellInfos: List<CellInfo>): String =
-        cellInfos.joinToString { cellInfo -> cellInfo.readableString() }
+        cellInfos.joinToString(System.lineSeparator()) { cellInfo -> cellInfo.readableString() }
 
     /**
      * Convert [CellInfo] to a readable string without sensitive info.
diff --git a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
index 08e993b..21cceb5 100644
--- a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
@@ -69,15 +69,19 @@
 
     public ConvertToEsimPreferenceController(Context context, String key, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner, int subId) {
-        super(context, key);
+        this(context, key);
         mSubId = subId;
-        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mLifecycleOwner = lifecycleOwner;
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
     }
 
+    public ConvertToEsimPreferenceController(Context context, String key) {
+        super(context, key);
+        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+    }
+
     public void init(int subId, SubscriptionInfoEntity subInfoEntity) {
         mSubId = subId;
         mSubscriptionInfoEntity = subInfoEntity;
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index 96c39f2..e5a4b46 100644
--- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -64,16 +64,20 @@
 
     public DefaultSubscriptionController(Context context, String preferenceKey, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner) {
+        this(context, preferenceKey);
+        mLifecycleOwner = lifecycleOwner;
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    public DefaultSubscriptionController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mManager = context.getSystemService(SubscriptionManager.class);
         mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection()
                 == View.LAYOUT_DIRECTION_RTL;
         mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this);
-        mLifecycleOwner = lifecycleOwner;
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
     }
 
     /** @return the id of the default subscription for the service, or
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index bec7ee7..28c05c5 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -72,16 +72,20 @@
 
     public MobileDataPreferenceController(Context context, String key, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner, int subId) {
-        super(context, key);
+        this(context, key);
         mSubId = subId;
-        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
-        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mLifecycleOwner = lifecycleOwner;
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
     }
 
+    public MobileDataPreferenceController(Context context, String key) {
+        super(context, key);
+        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+    }
+
     @Override
     public int getAvailabilityStatus(int subId) {
         if (Flags.isDualSimOnboardingEnabled()) {
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 603d915..db95d70 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -708,12 +708,13 @@
         return tm.getNetworkOperatorName();
     }
 
-    private static int[] getActiveSubscriptionIdList(Context context) {
+    @VisibleForTesting
+    static int[] getActiveSubscriptionIdList(Context context) {
         final SubscriptionManager subscriptionManager = context.getSystemService(
                 SubscriptionManager.class).createForAllUserProfiles();
         final List<SubscriptionInfo> subInfoList =
-                subscriptionManager.getActiveSubscriptionInfoList();
-        if (subInfoList == null) {
+                SubscriptionUtil.getActiveSubscriptions(subscriptionManager);
+        if (subInfoList == null || subInfoList.isEmpty()) {
             return new int[0];
         }
         int[] activeSubIds = new int[subInfoList.size()];
diff --git a/src/com/android/settings/network/telephony/NetworkScanHelper.java b/src/com/android/settings/network/telephony/NetworkScanHelper.java
deleted file mode 100644
index 1961329..0000000
--- a/src/com/android/settings/network/telephony/NetworkScanHelper.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2018 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.settings.network.telephony;
-
-import android.annotation.IntDef;
-import android.content.Context;
-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.android.settings.R;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-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;
-import java.util.stream.Collectors;
-
-/**
- * A helper class that builds the common interface and performs the network scan for two different
- * network scan APIs.
- */
-public class NetworkScanHelper {
-    public static final String TAG = "NetworkScanHelper";
-
-    /**
-     * Callbacks interface to inform the network scan results.
-     */
-    public interface NetworkScanCallback {
-        /**
-         * Called when the results is returned from {@link TelephonyManager}. This method will be
-         * called at least one time if there is no error occurred during the network scan.
-         *
-         * <p> This method can be called multiple times in one network scan, until
-         * {@link #onComplete()} or {@link #onError(int)} is called.
-         *
-         * @param results
-         */
-        void onResults(List<CellInfo> results);
-
-        /**
-         * Called when the current network scan process is finished. No more
-         * {@link #onResults(List)} will be called for the current network scan after this method is
-         * called.
-         */
-        void onComplete();
-
-        /**
-         * Called when an error occurred during the network scan process.
-         *
-         * <p> There is no more result returned from {@link TelephonyManager} if an error occurred.
-         *
-         * <p> {@link #onComplete()} will not be called if an error occurred.
-         *
-         * @see {@link NetworkScan.ScanErrorCode}
-         */
-        void onError(int errorCode);
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS, NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS})
-    public @interface NetworkQueryType {}
-
-    /**
-     * Performs the network scan using {@link TelephonyManager#getAvailableNetworks()}. The network
-     * scan results won't be returned to the caller until the network scan is completed.
-     *
-     * <p> This is typically used when the modem doesn't support the new network scan api
-     * {@link TelephonyManager#requestNetworkScan(
-     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
-     */
-    public static final int NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS = 1;
-
-    /**
-     * Performs the network scan using {@link TelephonyManager#requestNetworkScan(
-     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan
-     * results will be returned to the caller periodically in a small time window until the network
-     * scan is completed. The complete results should be returned in the last called of
-     * {@link NetworkScanCallback#onResults(List)}.
-     *
-     * <p> This is recommended to be used if modem supports the new network scan api
-     * {@link TelephonyManager#requestNetworkScan(
-     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}
-     */
-    public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2;
-
-    /** The constants below are used in the async network scan. */
-    @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;
-    private final TelephonyScanManager.NetworkScanCallback mInternalNetworkScanCallback;
-    private final Executor mExecutor;
-
-    private int mMaxSearchTimeSec = MAX_SEARCH_TIME_SEC;
-    private NetworkScan mNetworkScanRequester;
-
-    /** Callbacks for sync network scan */
-    private ListenableFuture<List<CellInfo>> mNetworkScanFuture;
-
-    public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
-        mTelephonyManager = tm;
-        mNetworkScanCallback = callback;
-        mInternalNetworkScanCallback = new NetworkScanCallbackImpl();
-        mExecutor = executor;
-    }
-
-    public NetworkScanHelper(Context context, TelephonyManager tm, NetworkScanCallback callback,
-            Executor executor) {
-        this(tm, callback, executor);
-        mMaxSearchTimeSec = context.getResources().getInteger(
-                R.integer.config_network_scan_helper_max_search_time_sec);
-    }
-
-    @VisibleForTesting
-    NetworkScanRequest createNetworkScanForPreferredAccessNetworks() {
-        long networkTypeBitmap3gpp = mTelephonyManager.getPreferredNetworkTypeBitmask()
-                & TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP;
-
-        List<RadioAccessSpecifier> radioAccessSpecifiers = new ArrayList<>();
-        // If the allowed network types are unknown or if they are of the right class, scan for
-        // them; otherwise, skip them to save scan time and prevent users from being shown networks
-        // that they can't connect to.
-        if (networkTypeBitmap3gpp == 0
-                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_2G) != 0) {
-            radioAccessSpecifiers.add(
-                    new RadioAccessSpecifier(AccessNetworkType.GERAN, null, null));
-        }
-        if (networkTypeBitmap3gpp == 0
-                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_3G) != 0) {
-            radioAccessSpecifiers.add(
-                    new RadioAccessSpecifier(AccessNetworkType.UTRAN, null, null));
-        }
-        if (networkTypeBitmap3gpp == 0
-                || (networkTypeBitmap3gpp & TelephonyManager.NETWORK_CLASS_BITMASK_4G) != 0) {
-            radioAccessSpecifiers.add(
-                    new RadioAccessSpecifier(AccessNetworkType.EUTRAN, null, null));
-        }
-        // If a device supports 5G stand-alone then the code below should be re-enabled; however
-        // a device supporting only non-standalone mode cannot perform PLMN selection and camp on
-        // 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.
-        //
-        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,
-                radioAccessSpecifiers.toArray(
-                        new RadioAccessSpecifier[radioAccessSpecifiers.size()]),
-                SEARCH_PERIODICITY_SEC,
-                mMaxSearchTimeSec,
-                INCREMENTAL_RESULTS,
-                INCREMENTAL_RESULTS_PERIODICITY_SEC,
-                null /* List of PLMN ids (MCC-MNC) */);
-    }
-
-    /**
-     * Performs a network scan for the given type {@code type}.
-     * {@link #NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS} is recommended if modem supports
-     * {@link TelephonyManager#requestNetworkScan(
-     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
-     *
-     * @param type used to tell which network scan API should be used.
-     */
-    public void startNetworkScan(@NetworkQueryType int type) {
-        if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) {
-            mNetworkScanFuture = SettableFuture.create();
-            Futures.addCallback(mNetworkScanFuture, new FutureCallback<List<CellInfo>>() {
-                @Override
-                public void onSuccess(List<CellInfo> result) {
-                    onResults(result);
-                    onComplete();
-                }
-
-                @Override
-                public void onFailure(Throwable t) {
-                    if (t instanceof CancellationException) {
-                        return;
-                    }
-                    int errCode = Integer.parseInt(t.getMessage());
-                    onError(errCode);
-                }
-            }, MoreExecutors.directExecutor());
-            mExecutor.execute(new NetworkScanSyncTask(
-                    mTelephonyManager, (SettableFuture) mNetworkScanFuture));
-        } else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
-            if (mNetworkScanRequester != null) {
-                return;
-            }
-            mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
-                    createNetworkScanForPreferredAccessNetworks(),
-                    mExecutor,
-                    mInternalNetworkScanCallback);
-            if (mNetworkScanRequester == null) {
-                onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR);
-            }
-        }
-    }
-
-    /**
-     * The network scan of type {@link #NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS} can't be stopped,
-     * however, the result of the current network scan won't be returned to the callback after
-     * calling this method.
-     */
-    public void stopNetworkQuery() {
-        if (mNetworkScanRequester != null) {
-            mNetworkScanRequester.stopScan();
-            mNetworkScanRequester = null;
-        }
-
-        if (mNetworkScanFuture != null) {
-            mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */);
-            mNetworkScanFuture = null;
-        }
-    }
-
-    private void onResults(List<CellInfo> cellInfos) {
-        mNetworkScanCallback.onResults(cellInfos);
-    }
-
-    private void onComplete() {
-        mNetworkScanCallback.onComplete();
-    }
-
-    private void onError(int errCode) {
-        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}.
-     * @param errCode status code from {@link CellNetworkScanResult}.
-     *
-     * @return one of the scan error code from {@link NetworkScan.ScanErrorCode}.
-     */
-    private static int convertToScanErrorCode(int errCode) {
-        switch (errCode) {
-            case CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE:
-                return NetworkScan.ERROR_RADIO_INTERFACE_ERROR;
-            case CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE:
-            default:
-                return NetworkScan.ERROR_MODEM_ERROR;
-        }
-    }
-
-    private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
-        public void onResults(List<CellInfo> results) {
-            Log.d(TAG, "Async scan onResults() results = "
-                    + CellInfoUtil.cellInfoListToString(results));
-            NetworkScanHelper.this.onResults(results);
-        }
-
-        public void onComplete() {
-            Log.d(TAG, "async scan onComplete()");
-            NetworkScanHelper.this.onComplete();
-        }
-
-        public void onError(@NetworkScan.ScanErrorCode int errCode) {
-            Log.d(TAG, "async scan onError() errorCode = " + errCode);
-            NetworkScanHelper.this.onError(errCode);
-        }
-    }
-
-    private static final class NetworkScanSyncTask implements Runnable {
-        private final SettableFuture<List<CellInfo>> mCallback;
-        private final TelephonyManager mTelephonyManager;
-
-        NetworkScanSyncTask(
-                TelephonyManager telephonyManager, SettableFuture<List<CellInfo>> callback) {
-            mTelephonyManager = telephonyManager;
-            mCallback = callback;
-        }
-
-        @Override
-        public void run() {
-            final CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
-            if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
-                final List<CellInfo> cellInfos = result.getOperators()
-                        .stream()
-                        .map(operatorInfo
-                                -> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo))
-                        .collect(Collectors.toList());
-                Log.d(TAG, "Sync network scan completed, cellInfos = "
-                        + CellInfoUtil.cellInfoListToString(cellInfos));
-                mCallback.set(cellInfos);
-            } else {
-                final Throwable error = new Throwable(
-                        Integer.toString(convertToScanErrorCode(result.getStatus())));
-                mCallback.setException(error);
-                Log.d(TAG, "Sync network scan error, ex = " + error);
-            }
-        }
-    }
-}
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index c8617af..5995a13 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.network.telephony;
 
-import android.app.Activity;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
@@ -39,6 +38,7 @@
 import android.view.View;
 
 import androidx.annotation.Keep;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
@@ -49,14 +49,18 @@
 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.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;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -71,12 +75,8 @@
     private static final String TAG = "NetworkSelectSettings";
 
     private static final int EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE = 1;
-    private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
-    private static final int EVENT_NETWORK_SCAN_ERROR = 3;
-    private static final int EVENT_NETWORK_SCAN_COMPLETED = 4;
 
     private static final String PREF_KEY_NETWORK_OPERATORS = "network_operators_preference";
-    private static final int MIN_NUMBER_OF_SCAN_REQUIRED = 2;
 
     private PreferenceCategory mPreferenceCategory;
     @VisibleForTesting
@@ -84,25 +84,21 @@
     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;
     private CarrierConfigManager mCarrierConfigManager;
     private List<String> mForbiddenPlmns;
     private boolean mShow4GForLTE = false;
-    private NetworkScanHelper mNetworkScanHelper;
     private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
     private MetricsFeatureProvider mMetricsFeatureProvider;
-    private boolean mUseNewApi;
-    private long mRequestIdManualNetworkSelect;
-    private long mRequestIdManualNetworkScan;
-    private long mWaitingForNumberOfScanResults;
-    @VisibleForTesting
-    boolean mIsAggregationEnabled = false;
     private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
     private AtomicBoolean mShouldFilterOutSatellitePlmn = new AtomicBoolean();
 
+    private NetworkScanRepository mNetworkScanRepository;
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -114,7 +110,6 @@
     @Initializer
     protected void onCreateInitialization() {
         Context context = getContext();
-        mUseNewApi = enableNewAutoSelectNetworkUI(context);
         mSubId = getSubId();
 
         mPreferenceCategory = getPreferenceCategory(PREF_KEY_NETWORK_OPERATORS);
@@ -124,8 +119,6 @@
         mTelephonyManager = getTelephonyManager(context, mSubId);
         mSatelliteManager = getSatelliteManager(context);
         mCarrierConfigManager = getCarrierConfigManager(context);
-        mNetworkScanHelper = new NetworkScanHelper(
-                mTelephonyManager, mCallback, mNetworkScanExecutor);
         PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(mSubId,
                 CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL,
                 CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL);
@@ -136,30 +129,13 @@
                 true));
 
         mMetricsFeatureProvider = getMetricsFeatureProvider(context);
-        mIsAggregationEnabled = enableAggregation(context);
-        Log.d(TAG, "init: mUseNewApi:" + mUseNewApi
-                + " ,mIsAggregationEnabled:" + mIsAggregationEnabled + " ,mSubId:" + mSubId);
 
         mCarrierConfigChangeListener =
                 (slotIndex, subId, carrierId, specificCarrierId) -> handleCarrierConfigChanged(
                         subId);
         mCarrierConfigManager.registerCarrierConfigChangeListener(mNetworkScanExecutor,
                 mCarrierConfigChangeListener);
-
-    }
-
-    @Keep
-    @VisibleForTesting
-    protected boolean enableNewAutoSelectNetworkUI(Context context) {
-        return context.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
-    }
-
-    @Keep
-    @VisibleForTesting
-    protected boolean enableAggregation(Context context) {
-        return context.getResources().getBoolean(
-                R.bool.config_network_selection_list_aggregation_enabled);
+        mNetworkScanRepository = new NetworkScanRepository(context, mSubId);
     }
 
     @Keep
@@ -218,30 +194,25 @@
     }
 
     @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
 
-        final Activity activity = getActivity();
-        if (activity != null) {
-            mProgressHeader = setPinnedHeaderView(
-                    com.android.settingslib.widget.progressbar.R.layout.progress_header)
-                    .findViewById(com.android.settingslib.widget.progressbar.R.id.progress_bar_animation);
-            setProgressBarVisible(false);
-        }
+        mProgressHeader = setPinnedHeaderView(
+                com.android.settingslib.widget.progressbar.R.layout.progress_header
+        ).findViewById(com.android.settingslib.widget.progressbar.R.id.progress_bar_animation);
         forceUpdateConnectedPreferenceCategory();
+        launchNetworkScan();
     }
 
-    @Override
-    public void onStart() {
-        super.onStart();
+    private void launchNetworkScan() {
+        setProgressBarVisible(true);
+        mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), (networkScanResult) -> {
+            if (isPreferenceScreenEnabled()) {
+                scanResultHandler(networkScanResult);
+            }
 
-        updateForbiddenPlmns();
-        if (isProgressBarVisible()) {
-            return;
-        }
-        if (mWaitingForNumberOfScanResults <= 0) {
-            startNetworkQuery();
-        }
+            return Unit.INSTANCE;
+        });
     }
 
     /**
@@ -257,14 +228,6 @@
     }
 
     @Override
-    public void onStop() {
-        if (mWaitingForNumberOfScanResults <= 0) {
-            stopNetworkQuery();
-        }
-        super.onStop();
-    }
-
-    @Override
     public boolean onPreferenceTreeClick(Preference preference) {
         if (preference == mSelectedPreference) {
             Log.d(TAG, "onPreferenceTreeClick: preference is mSelectedPreference. Do nothing.");
@@ -275,8 +238,6 @@
             return false;
         }
 
-        stopNetworkQuery();
-
         // Refresh the last selected item in case users reselect network.
         clearPreferenceSummary();
         if (mSelectedPreference != null) {
@@ -294,8 +255,6 @@
         // Disable the screen until network is manually set
         enablePreferenceScreen(false);
 
-        mRequestIdManualNetworkSelect = getNewRequestId();
-        mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
         final OperatorInfo operator = mSelectedPreference.getOperatorInfo();
         ThreadUtils.postOnBackgroundThread(() -> {
             final Message msg = mHandler.obtainMessage(
@@ -329,7 +288,6 @@
             switch (msg.what) {
                 case EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE:
                     final boolean isSucceed = (boolean) msg.obj;
-                    stopNetworkQuery();
                     setProgressBarVisible(false);
                     enablePreferenceScreen(true);
 
@@ -341,86 +299,15 @@
                         Log.e(TAG, "No preference to update!");
                     }
                     break;
-                case EVENT_NETWORK_SCAN_RESULTS:
-                    scanResultHandler((List<CellInfo>) msg.obj);
-                    break;
-
-                case EVENT_NETWORK_SCAN_ERROR:
-                    stopNetworkQuery();
-                    Log.i(TAG, "Network scan failure " + msg.arg1 + ":"
-                            + " scan request 0x" + Long.toHexString(mRequestIdManualNetworkScan)
-                            + ", waiting for scan results = " + mWaitingForNumberOfScanResults
-                            + ", select request 0x"
-                            + Long.toHexString(mRequestIdManualNetworkSelect));
-                    if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
-                        break;
-                    }
-                    if (!isPreferenceScreenEnabled()) {
-                        clearPreferenceSummary();
-                        enablePreferenceScreen(true);
-                    } else {
-                        addMessagePreference(R.string.network_query_error);
-                    }
-                    break;
-
-                case EVENT_NETWORK_SCAN_COMPLETED:
-                    stopNetworkQuery();
-                    Log.d(TAG, "Network scan complete:"
-                            + " scan request 0x" + Long.toHexString(mRequestIdManualNetworkScan)
-                            + ", waiting for scan results = " + mWaitingForNumberOfScanResults
-                            + ", select request 0x"
-                            + Long.toHexString(mRequestIdManualNetworkSelect));
-                    if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
-                        break;
-                    }
-                    if (!isPreferenceScreenEnabled()) {
-                        clearPreferenceSummary();
-                        enablePreferenceScreen(true);
-                    } else if (mCellInfoList == null) {
-                        // In case the scan timeout before getting any results
-                        addMessagePreference(R.string.empty_networks_list);
-                    }
-                    break;
             }
-            return;
         }
     };
 
-    @VisibleForTesting
-    List<CellInfo> doAggregation(List<CellInfo> cellInfoListInput) {
-        if (!mIsAggregationEnabled) {
-            Log.d(TAG, "no aggregation");
-            return new ArrayList<>(cellInfoListInput);
-        }
-        ArrayList<CellInfo> aggregatedList = new ArrayList<>();
-        for (CellInfo cellInfo : cellInfoListInput) {
-            String plmn = CellInfoUtil.getNetworkTitle(cellInfo.getCellIdentity());
-            Class className = cellInfo.getClass();
-
-            Optional<CellInfo> itemInTheList = aggregatedList.stream().filter(
-                    item -> {
-                        String itemPlmn = CellInfoUtil.getNetworkTitle(item.getCellIdentity());
-                        return itemPlmn.equals(plmn) && item.getClass().equals(className);
-                    })
-                    .findFirst();
-            if (itemInTheList.isPresent()) {
-                if (cellInfo.isRegistered() && !itemInTheList.get().isRegistered()) {
-                    // Adding the registered cellinfo item into list. If there are two registered
-                    // cellinfo items, then select first one from source list.
-                    aggregatedList.set(aggregatedList.indexOf(itemInTheList.get()), cellInfo);
-                }
-                continue;
-            }
-            aggregatedList.add(cellInfo);
-        }
-
-        return filterOutSatellitePlmn(aggregatedList);
-    }
-
     /* We do not want to expose carrier satellite plmns to the user when manually scan the
        cellular network. Therefore, it is needed to filter out satellite plmns from current cell
        info list  */
-    private List<CellInfo> filterOutSatellitePlmn(List<CellInfo> cellInfoList) {
+    @VisibleForTesting
+    List<CellInfo> filterOutSatellitePlmn(List<CellInfo> cellInfoList) {
         List<String> aggregatedSatellitePlmn = getSatellitePlmnsForCarrierWrapper();
         if (!mShouldFilterOutSatellitePlmn.get() || aggregatedSatellitePlmn.isEmpty()) {
             return cellInfoList;
@@ -455,56 +342,19 @@
         }
     }
 
-    private final NetworkScanHelper.NetworkScanCallback mCallback =
-            new NetworkScanHelper.NetworkScanCallback() {
-                public void onResults(List<CellInfo> results) {
-                    final Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
-                    msg.sendToTarget();
-                }
-
-                public void onComplete() {
-                    final Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
-                    msg.sendToTarget();
-                }
-
-                public void onError(int error) {
-                    final Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR, error,
-                            0 /* arg2 */);
-                    msg.sendToTarget();
-                }
-            };
-
-    @Keep
     @VisibleForTesting
-    protected void scanResultHandler(List<CellInfo> results) {
-        if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
-            Log.d(TAG, "CellInfoList (drop): "
-                    + CellInfoUtil.cellInfoListToString(new ArrayList<>(results)));
-            return;
-        }
-        mWaitingForNumberOfScanResults--;
-        if ((mWaitingForNumberOfScanResults <= 0) && (!isResumed())) {
-            stopNetworkQuery();
-        }
-
-        mCellInfoList = doAggregation(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
@@ -521,11 +371,8 @@
 
     /**
      * 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
@@ -536,7 +383,6 @@
         }
 
         // update the content of preference
-        NetworkOperatorPreference connectedPref = null;
         for (int index = 0; index < mCellInfoList.size(); index++) {
             final CellInfo cellInfo = mCellInfoList.get(index);
 
@@ -561,23 +407,10 @@
 
             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;
     }
 
     /**
@@ -646,18 +479,6 @@
         }
     }
 
-    private long getNewRequestId() {
-        return Math.max(mRequestIdManualNetworkSelect,
-                mRequestIdManualNetworkScan) + 1;
-    }
-
-    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);
@@ -665,35 +486,13 @@
     }
 
     private void addMessagePreference(int messageId) {
-        setProgressBarVisible(false);
         mStatusMessagePreference.setTitle(messageId);
         mPreferenceCategory.removeAll();
         mPreferenceCategory.addPreference(mStatusMessagePreference);
     }
 
-    private void startNetworkQuery() {
-        setProgressBarVisible(true);
-        if (mNetworkScanHelper != null) {
-            mRequestIdManualNetworkScan = getNewRequestId();
-            mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
-            mNetworkScanHelper.startNetworkScan(
-                    mUseNewApi
-                            ? NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS
-                            : NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
-        }
-    }
-
-    private void stopNetworkQuery() {
-        setProgressBarVisible(false);
-        if (mNetworkScanHelper != null) {
-            mWaitingForNumberOfScanResults = 0;
-            mNetworkScanHelper.stopNetworkQuery();
-        }
-    }
-
     @Override
     public void onDestroy() {
-        stopNetworkQuery();
         mNetworkScanExecutor.shutdown();
         super.onDestroy();
     }
diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
index fb8cd51..bf02308 100644
--- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
@@ -63,16 +63,20 @@
 
     public RoamingPreferenceController(Context context, String key, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner, int subId) {
-        super(context, key);
+        this(context, key);
         mSubId = subId;
-        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
-        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mLifecycleOwner = lifecycleOwner;
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
     }
 
+    public RoamingPreferenceController(Context context, String key) {
+        super(context, key);
+        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+    }
+
     @Override
     public int getAvailabilityStatus() {
         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
diff --git a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
index c49647d..c35a78c 100644
--- a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
@@ -35,6 +35,12 @@
                 .getBoolean(com.android.internal.R.bool.config_sms_ask_every_time_support);
     }
 
+    public SmsDefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mIsAskEverytimeSupported = mContext.getResources()
+                .getBoolean(com.android.internal.R.bool.config_sms_ask_every_time_support);
+    }
+
     @Override
     protected int getDefaultSubscriptionId() {
         int defaultSmsSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
diff --git a/src/com/android/settings/network/telephony/scan/NetworkScanRepository.kt b/src/com/android/settings/network/telephony/scan/NetworkScanRepository.kt
new file mode 100644
index 0000000..0344002
--- /dev/null
+++ b/src/com/android/settings/network/telephony/scan/NetworkScanRepository.kt
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony.scan
+
+import android.content.Context
+import android.telephony.AccessNetworkConstants.AccessNetworkType
+import android.telephony.CellInfo
+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 androidx.lifecycle.LifecycleOwner
+import com.android.settings.network.telephony.CellInfoUtil.getNetworkTitle
+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(context: Context, subId: Int) {
+    enum class NetworkScanState {
+        ACTIVE, COMPLETE, ERROR
+    }
+
+    data class NetworkScanResult(
+        val state: NetworkScanState,
+        val cellInfos: List<CellInfo>,
+    )
+
+    private val telephonyManager =
+        context.getSystemService(TelephonyManager::class.java)!!.createForSubscriptionId(subId)
+
+    /** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
+    fun launchNetworkScan(lifecycleOwner: LifecycleOwner, onResult: (NetworkScanResult) -> Unit) {
+        networkScanFlow().collectLatestWithLifecycle(lifecycleOwner, action = onResult)
+    }
+
+    data class CellInfoScanKey(
+        val title: String?,
+        val className: String,
+        val isRegistered: Boolean,
+    ) {
+        constructor(cellInfo: CellInfo) : this(
+            title = cellInfo.cellIdentity.getNetworkTitle(),
+            className = cellInfo.javaClass.name,
+            isRegistered = cellInfo.isRegistered,
+        )
+    }
+
+    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>) {
+                cellInfos = results.distinctBy { CellInfoScanKey(it) }
+                sendResult()
+            }
+
+            override fun onComplete() {
+                state = NetworkScanState.COMPLETE
+                sendResult()
+                // Don't call close() here since onComplete() could happens before onResults()
+            }
+
+            override fun onError(error: Int) {
+                state = NetworkScanState.ERROR
+                sendResult()
+                close()
+            }
+
+            private fun sendResult() {
+                trySend(NetworkScanResult(state, cellInfos))
+            }
+        }
+
+        val networkScan = telephonyManager.requestNetworkScan(
+            createNetworkScan(),
+            Dispatchers.Default.asExecutor(),
+            callback,
+        )
+
+        awaitClose { networkScan.stopScan() }
+    }.conflate().onEach { Log.d(TAG, "networkScanFlow: $it") }.flowOn(Dispatchers.Default)
+
+    /** Create network scan for allowed network types. */
+    private fun createNetworkScan(): NetworkScanRequest {
+        val allowedNetworkTypes = getAllowedNetworkTypes()
+        Log.d(TAG, "createNetworkScan: allowedNetworkTypes = $allowedNetworkTypes")
+        val radioAccessSpecifiers = allowedNetworkTypes
+            .map { RadioAccessSpecifier(it, null, null) }
+            .toTypedArray()
+        return NetworkScanRequest(
+            NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
+            radioAccessSpecifiers,
+            NetworkScanRequest.MIN_SEARCH_PERIODICITY_SEC, // one shot, not used
+            MAX_SEARCH_TIME_SEC,
+            true,
+            INCREMENTAL_RESULTS_PERIODICITY_SEC,
+            null,
+        )
+    }
+
+    private fun getAllowedNetworkTypes(): List<Int> {
+        val networkTypeBitmap3gpp: Long =
+            telephonyManager.getAllowedNetworkTypesBitmask() and
+                TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP
+        return buildList {
+            // If the allowed network types are unknown or if they are of the right class, scan for
+            // them; otherwise, skip them to save scan time and prevent users from being shown
+            // networks that they can't connect to.
+            if (networkTypeBitmap3gpp == 0L
+                || networkTypeBitmap3gpp and TelephonyManager.NETWORK_CLASS_BITMASK_2G != 0L
+            ) {
+                add(AccessNetworkType.GERAN)
+            }
+            if (networkTypeBitmap3gpp == 0L
+                || networkTypeBitmap3gpp and TelephonyManager.NETWORK_CLASS_BITMASK_3G != 0L
+            ) {
+                add(AccessNetworkType.UTRAN)
+            }
+            if (networkTypeBitmap3gpp == 0L
+                || networkTypeBitmap3gpp and TelephonyManager.NETWORK_CLASS_BITMASK_4G != 0L
+            ) {
+                add(AccessNetworkType.EUTRAN)
+            }
+            // If a device supports 5G stand-alone then the code below should be re-enabled; however
+            // a device supporting only non-standalone mode cannot perform PLMN selection and camp
+            // on 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.
+            //
+            if (networkTypeBitmap3gpp == 0L
+                || (networkTypeBitmap3gpp and TelephonyManager.NETWORK_CLASS_BITMASK_5G != 0L &&
+                    hasNrSaCapability())
+            ) {
+                add(AccessNetworkType.NGRAN)
+                Log.d(TAG, "radioAccessSpecifiers add NGRAN.")
+            }
+        }
+    }
+
+    private fun hasNrSaCapability(): Boolean {
+        val phoneCapability = telephonyManager.getPhoneCapability()
+        return PhoneCapability.DEVICE_NR_CAPABILITY_SA in phoneCapability.deviceNrCapabilities
+    }
+
+    companion object {
+        private const val TAG = "NetworkScanRepository"
+
+        @VisibleForTesting
+        val MAX_SEARCH_TIME_SEC = 300
+
+        @VisibleForTesting
+        val INCREMENTAL_RESULTS_PERIODICITY_SEC = 3
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index 9fa9651..1b8d24e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -35,7 +35,6 @@
 
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
@@ -374,11 +373,10 @@
     }
 
     @Test
-    public void displayPreference_init_showLoading() {
+    public void displayPreference_init_showEmptySpace() {
         mController.displayPreference(mPreferenceScreen);
 
-        verify(mBatteryUsageProgressBarPref)
-                .setBottomSummary(mContext.getString(R.string.settings_license_activity_loading));
+        verify(mBatteryUsageProgressBarPref).setBottomSummary(" ");
     }
 
     private CharSequence formatBatteryPercentageText() {
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/scan/NetworkScanRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/scan/NetworkScanRepositoryTest.kt
new file mode 100644
index 0000000..c0b918f
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/scan/NetworkScanRepositoryTest.kt
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony.scan
+
+import android.content.Context
+import android.telephony.AccessNetworkConstants.AccessNetworkType
+import android.telephony.CellIdentityCdma
+import android.telephony.CellIdentityGsm
+import android.telephony.CellIdentityLte
+import android.telephony.CellInfoCdma
+import android.telephony.CellInfoGsm
+import android.telephony.CellInfoLte
+import android.telephony.NetworkScan
+import android.telephony.NetworkScanRequest
+import android.telephony.PhoneCapability
+import android.telephony.TelephonyManager
+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.settingslib.spa.testutils.firstWithTimeoutOrNull
+import com.android.settingslib.spa.testutils.toListWithTimeout
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.verify
+
+@RunWith(AndroidJUnit4::class)
+class NetworkScanRepositoryTest {
+
+    private var callback: TelephonyScanManager.NetworkScanCallback? = null
+
+    private val mockTelephonyManager = mock<TelephonyManager> {
+        on { createForSubscriptionId(SUB_ID) } doReturn mock
+        on { requestNetworkScan(any(), any(), any()) } doAnswer {
+            callback = it.arguments[2] as TelephonyScanManager.NetworkScanCallback
+            mock<NetworkScan>()
+        }
+    }
+
+    private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+        on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
+    }
+
+    private val repository = NetworkScanRepository(context, SUB_ID)
+
+    @Test
+    fun networkScanFlow_initial() = runBlocking {
+        val result = repository.networkScanFlow().firstWithTimeoutOrNull()
+
+        assertThat(result).isNull()
+    }
+
+    @Test
+    fun networkScanFlow_onResults(): Unit = runBlocking {
+        val cellInfos = listOf(CellInfoCdma().apply { cellIdentity = CELL_IDENTITY_CDMA })
+        val listDeferred = async {
+            repository.networkScanFlow().toListWithTimeout()
+        }
+        delay(100)
+
+        callback?.onResults(cellInfos)
+
+        assertThat(listDeferred.await()).containsExactly(
+            NetworkScanRepository.NetworkScanResult(
+                state = NetworkScanRepository.NetworkScanState.ACTIVE,
+                cellInfos = cellInfos,
+            )
+        )
+    }
+
+    @Test
+    fun networkScanFlow_onComplete(): Unit = runBlocking {
+        val listDeferred = async {
+            repository.networkScanFlow().toListWithTimeout()
+        }
+        delay(100)
+
+        callback?.onComplete()
+
+        assertThat(listDeferred.await()).containsExactly(
+            NetworkScanRepository.NetworkScanResult(
+                state = NetworkScanRepository.NetworkScanState.COMPLETE,
+                cellInfos = emptyList(),
+            )
+        )
+    }
+
+    @Test
+    fun networkScanFlow_onError(): Unit = runBlocking {
+        val listDeferred = async {
+            repository.networkScanFlow().toListWithTimeout()
+        }
+        delay(100)
+
+        callback?.onError(1)
+
+        assertThat(listDeferred.await()).containsExactly(
+            NetworkScanRepository.NetworkScanResult(
+                state = NetworkScanRepository.NetworkScanState.ERROR,
+                cellInfos = emptyList(),
+            )
+        )
+    }
+
+    @Test
+    fun networkScanFlow_hasDuplicateItems(): Unit = runBlocking {
+        val cellInfos = listOf(
+            createCellInfoLte("123", false),
+            createCellInfoLte("123", false),
+            createCellInfoLte("124", true),
+            createCellInfoLte("124", true),
+            createCellInfoGsm("123", false),
+            createCellInfoGsm("123", false),
+        )
+        val listDeferred = async {
+            repository.networkScanFlow().toListWithTimeout()
+        }
+        delay(100)
+
+        callback?.onResults(cellInfos)
+
+        assertThat(listDeferred.await()).containsExactly(
+            NetworkScanRepository.NetworkScanResult(
+                state = NetworkScanRepository.NetworkScanState.ACTIVE,
+                cellInfos = listOf(
+                    createCellInfoLte("123", false),
+                    createCellInfoLte("124", true),
+                    createCellInfoGsm("123", false),
+                ),
+            )
+        )
+    }
+
+
+    @Test
+    fun networkScanFlow_noDuplicateItems(): Unit = runBlocking {
+        val cellInfos = listOf(
+            createCellInfoLte("123", false),
+            createCellInfoLte("123", true),
+            createCellInfoLte("124", false),
+            createCellInfoLte("124", true),
+            createCellInfoGsm("456", false),
+            createCellInfoGsm("456", true),
+        )
+        val listDeferred = async {
+            repository.networkScanFlow().toListWithTimeout()
+        }
+        delay(100)
+
+        callback?.onResults(cellInfos)
+
+        assertThat(listDeferred.await()).containsExactly(
+            NetworkScanRepository.NetworkScanResult(
+                state = NetworkScanRepository.NetworkScanState.ACTIVE,
+                cellInfos = listOf(
+                    createCellInfoLte("123", false),
+                    createCellInfoLte("123", true),
+                    createCellInfoLte("124", false),
+                    createCellInfoLte("124", true),
+                    createCellInfoGsm("456", false),
+                    createCellInfoGsm("456", true),
+                )
+            )
+        )
+    }
+
+    @Test
+    fun createNetworkScan_deviceHasNrSa_requestNgran(): Unit = runBlocking {
+        mockTelephonyManager.stub {
+            on { getAllowedNetworkTypesBitmask() } doReturn NETWORK_CLASS_BITMASK_5G
+            on { getPhoneCapability() } doReturn
+                createPhoneCapability(intArrayOf(PhoneCapability.DEVICE_NR_CAPABILITY_SA))
+        }
+
+        repository.networkScanFlow().firstWithTimeoutOrNull()
+
+        verify(mockTelephonyManager).requestNetworkScan(argThat<NetworkScanRequest> {
+            specifiers.any { it.radioAccessNetwork == AccessNetworkType.NGRAN }
+        }, any(), any())
+    }
+
+    @Test
+    fun createNetworkScan_deviceNoNrSa_noNgran(): Unit = runBlocking {
+        mockTelephonyManager.stub {
+            on { getAllowedNetworkTypesBitmask() } doReturn NETWORK_CLASS_BITMASK_5G
+            on { getPhoneCapability() } doReturn
+                createPhoneCapability(intArrayOf(PhoneCapability.DEVICE_NR_CAPABILITY_NSA))
+        }
+
+        repository.networkScanFlow().firstWithTimeoutOrNull()
+
+        verify(mockTelephonyManager).requestNetworkScan(argThat<NetworkScanRequest> {
+            specifiers.none { it.radioAccessNetwork == AccessNetworkType.NGRAN }
+        }, any(), any())
+    }
+
+    private companion object {
+        const val SUB_ID = 1
+        const val LONG = "Long"
+        const val SHORT = "Short"
+
+        val CELL_IDENTITY_CDMA = CellIdentityCdma(
+            /* nid = */ 1,
+            /* sid = */ 2,
+            /* bid = */ 3,
+            /* lon = */ 4,
+            /* lat = */ 5,
+            /* alphal = */ LONG,
+            /* alphas = */ SHORT,
+        )
+
+        private fun createCellInfoLte(alphaLong: String, registered: Boolean): CellInfoLte {
+            val cellIdentityLte = CellIdentityLte(
+                /* ci = */ 1,
+                /* pci = */ 2,
+                /* tac = */ 3,
+                /* earfcn = */ 4,
+                /* bands = */ intArrayOf(1, 2),
+                /* bandwidth = */ 10000,
+                /* mccStr = */ null,
+                /* mncStr = */ null,
+                /* alphal = */ alphaLong,
+                /* alphas = */ null,
+                /* additionalPlmns = */ emptyList(),
+                /* csgInfo = */ null,
+            )
+            return CellInfoLte().apply {
+                cellIdentity = cellIdentityLte
+                isRegistered = registered
+            }
+        }
+
+        private fun createCellInfoGsm(alphaLong: String, registered: Boolean): CellInfoGsm {
+            val cellIdentityGsm = CellIdentityGsm(
+                /* lac = */ 1,
+                /* cid = */ 2,
+                /* arfcn = */ 3,
+                /* bsic = */ 4,
+                /* mccStr = */ "123",
+                /* mncStr = */ "01",
+                /* alphal = */ alphaLong,
+                /* alphas = */ null,
+                /* additionalPlmns = */ emptyList(),
+            )
+            return CellInfoGsm().apply {
+                cellIdentity = cellIdentityGsm
+                isRegistered = registered
+            }
+        }
+
+        private fun createPhoneCapability(deviceNrCapabilities: IntArray) =
+            PhoneCapability.Builder().setDeviceNrCapabilities(deviceNrCapabilities).build()
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java b/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
index 947ba75..570a320 100644
--- a/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java
@@ -240,6 +240,33 @@
     }
 
     @Test
+    public void getActiveSubscriptionIdList_nonActive_returnEmptyArray() {
+        int[] expectedList = new int[0];
+        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(new ArrayList<>());
+
+        assertThat(MobileNetworkUtils.getActiveSubscriptionIdList(mContext))
+                .isEqualTo(expectedList);
+    }
+
+    @Test
+    public void getActiveSubscriptionIdList_normalCaseTwoActiveSims_returnValidSubId() {
+        int[] expectedList = {SUB_ID_1, SUB_ID_2};
+
+        assertThat(MobileNetworkUtils.getActiveSubscriptionIdList(mContext))
+                .isEqualTo(expectedList);
+    }
+
+    @Test
+    public void getActiveSubscriptionIdList_TwoActiveSimsAndOneIsNtn_returnOneSubId() {
+        int[] expectedList = {SUB_ID_2};
+        when(mSubscriptionInfo1.isEmbedded()).thenReturn(true);
+        when(mSubscriptionInfo1.isOnlyNonTerrestrialNetwork()).thenReturn(true);
+
+        assertThat(MobileNetworkUtils.getActiveSubscriptionIdList(mContext))
+                .isEqualTo(expectedList);
+    }
+
+    @Test
     public void shouldDisplayNetworkSelectOptions_HideCarrierNetwork_returnFalse() {
         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL,
                 true);
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkScanHelperTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkScanHelperTest.java
deleted file mode 100644
index f046c9a..0000000
--- a/tests/unit/src/com/android/settings/network/telephony/NetworkScanHelperTest.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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.
- * 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.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;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-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;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-@RunWith(AndroidJUnit4.class)
-public class NetworkScanHelperTest {
-
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private List<CellInfo> mCellInfos;
-    @Mock
-    private NetworkScanHelper.NetworkScanCallback mNetworkScanCallback;
-
-    private static final long THREAD_EXECUTION_TIMEOUT_MS = 3000L;
-
-    private ExecutorService mNetworkScanExecutor;
-    private NetworkScanHelper mNetworkScanHelper;
-
-    private static final int SCAN_ID = 1234;
-    private static final int SUB_ID = 1;
-
-    private NetworkScan mNetworkScan;
-
-    public class NetworkScanMock extends NetworkScan {
-        NetworkScanMock(int scanId, int subId) {
-            super(scanId, subId);
-        }
-
-        @Override
-        public void stopScan() {
-            return;
-        }
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mNetworkScanExecutor = Executors.newFixedThreadPool(1);
-
-        mNetworkScanHelper = new NetworkScanHelper(mTelephonyManager,
-                mNetworkScanCallback, mNetworkScanExecutor);
-
-        mNetworkScan = spy(new NetworkScanMock(SCAN_ID, SUB_ID));
-    }
-
-    @Test
-    public void startNetworkScan_incrementalAndSuccess_completionWithResult() {
-        when(mCellInfos.size()).thenReturn(1);
-
-        doAnswer(new Answer() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                TelephonyScanManager.NetworkScanCallback callback =
-                        (TelephonyScanManager.NetworkScanCallback)
-                        (invocation.getArguments()[2]);
-                callback.onResults(mCellInfos);
-                callback.onComplete();
-                return mNetworkScan;
-            }
-        }).when(mTelephonyManager).requestNetworkScan(
-                any(NetworkScanRequest.class), any(Executor.class),
-                any(TelephonyScanManager.NetworkScanCallback.class));
-
-        ArgumentCaptor<List<CellInfo>> argument = ArgumentCaptor.forClass(List.class);
-
-        startNetworkScan_incremental(true);
-
-        verify(mNetworkScanCallback, times(1)).onResults(argument.capture());
-        List<CellInfo> actualResult = argument.getValue();
-        assertThat(actualResult.size()).isEqualTo(mCellInfos.size());
-        verify(mNetworkScanCallback, times(1)).onComplete();
-    }
-
-    @Test
-    public void startNetworkScan_incrementalAndImmediateFailure_failureWithErrorCode() {
-        doReturn(null).when(mTelephonyManager).requestNetworkScan(
-                any(NetworkScanRequest.class), any(Executor.class),
-                any(TelephonyScanManager.NetworkScanCallback.class));
-
-        startNetworkScan_incremental(true);
-
-        verify(mNetworkScanCallback, times(1)).onError(anyInt());
-    }
-
-    @Test
-    public void startNetworkScan_incrementalAndFailure_failureWithErrorCode() {
-        doAnswer(new Answer() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                TelephonyScanManager.NetworkScanCallback callback =
-                        (TelephonyScanManager.NetworkScanCallback)
-                        (invocation.getArguments()[2]);
-                callback.onError(NetworkScan.ERROR_MODEM_ERROR);
-                return mNetworkScan;
-            }
-        }).when(mTelephonyManager).requestNetworkScan(
-                any(NetworkScanRequest.class), any(Executor.class),
-                any(TelephonyScanManager.NetworkScanCallback.class));
-
-        startNetworkScan_incremental(true);
-
-        verify(mNetworkScanCallback, times(1)).onError(anyInt());
-    }
-
-    @Test
-    public void startNetworkScan_incrementalAndAbort_doStop() {
-        doReturn(mNetworkScan).when(mTelephonyManager).requestNetworkScan(
-                any(NetworkScanRequest.class), any(Executor.class),
-                any(TelephonyScanManager.NetworkScanCallback.class));
-
-        startNetworkScan_incremental(false);
-
-        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);
-        if (!waitForCompletion) {
-            mNetworkScanHelper.stopNetworkQuery();
-        }
-    }
-
-}
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
index 080534e..d71af84 100644
--- a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
@@ -44,8 +44,12 @@
 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;
@@ -83,7 +87,6 @@
 
     public Context mContext;
     public PreferenceCategory mPreferenceCategory;
-    public boolean mIsAggregationEnabled = true;
 
     private TargetClass mNetworkSelectSettings;
 
@@ -104,12 +107,13 @@
         doReturn(mCellId2).when(mCellInfo2).getCellIdentity();
         doReturn(mock(CellSignalStrength.class)).when(mCellInfo2).getCellSignalStrength();
         doReturn(CARRIER_NAME2).when(mCellId2).getOperatorAlphaLong();
-        mIsAggregationEnabled = true;
         mNetworkSelectSettings = spy(new TargetClass(this));
 
         PersistableBundle config = new PersistableBundle();
         config.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
-        doReturn(config).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+        doReturn(config).when(mCarrierConfigManager).getConfigForSubId(SUB_ID,
+                CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL,
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL);
 
         doReturn(TelephonyManager.DATA_CONNECTED).when(mTelephonyManager).getDataState();
     }
@@ -163,8 +167,7 @@
         }
 
         @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);
@@ -175,11 +178,6 @@
         }
 
         @Override
-        protected boolean enableAggregation(Context context) {
-            return mTestEnv.mIsAggregationEnabled;
-        }
-
-        @Override
         protected int getSubId() {
             return SUB_ID;
         }
@@ -188,9 +186,14 @@
     @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);
@@ -210,77 +213,7 @@
     }
 
     @Test
-    public void doAggregation_hasDuplicateItemsDiffCellIdCase1_removeSamePlmnRatItem() {
-        mNetworkSelectSettings.onCreateInitialization();
-        List<CellInfo> testList = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createLteCellInfo(true, 1234, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"));
-        List<CellInfo> expected = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
-    }
-
-    @Test
-    public void doAggregation_hasDuplicateItemsDiffCellIdCase2_removeSamePlmnRatItem() {
-        mNetworkSelectSettings.onCreateInitialization();
-        List<CellInfo> testList = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"),
-                createLteCellInfo(false, 1234, "123", "232", "CarrierB"),
-                createGsmCellInfo(false, 1234, "123", "232", "CarrierB"));
-        List<CellInfo> expected = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"),
-                createLteCellInfo(false, 1234, "123", "232", "CarrierB"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
-    }
-
-    @Test
-    public void doAggregation_hasDuplicateItemsDiffMccMncCase1_removeSamePlmnRatItem() {
-        mNetworkSelectSettings.onCreateInitialization();
-        List<CellInfo> testList = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createLteCellInfo(true, 123, "456", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"));
-        List<CellInfo> expected = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
-    }
-
-    @Test
-    public void doAggregation_hasDuplicateItemsDiffMccMncCase2_removeSamePlmnRatItem() {
-        mNetworkSelectSettings.onCreateInitialization();
-        List<CellInfo> testList = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"),
-                createLteCellInfo(false, 1234, "123", "232", "CarrierB"),
-                createGsmCellInfo(false, 123, "456", "232", "CarrierB"));
-        List<CellInfo> expected = Arrays.asList(
-                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
-                createGsmCellInfo(false, 123, "123", "232", "CarrierB"),
-                createLteCellInfo(false, 1234, "123", "232", "CarrierB"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
-    }
-
-    @Test
-    public void doAggregation_hasDuplicateItemsDiffMccMncCase3_removeSamePlmnRatItem() {
-        mNetworkSelectSettings.onCreateInitialization();
-        List<CellInfo> testList = Arrays.asList(
-                createLteCellInfo(false, 123, "123", "232", "CarrierA"),
-                createLteCellInfo(false, 124, "123", "233", "CarrierA"),
-                createLteCellInfo(true, 125, "123", "234", "CarrierA"),
-                createGsmCellInfo(false, 126, "456", "232", "CarrierA"));
-        List<CellInfo> expected = Arrays.asList(
-                createLteCellInfo(true, 125, "123", "234", "CarrierA"),
-                createGsmCellInfo(false, 126, "456", "232", "CarrierA"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
-    }
-
-    @Test
-    public void doAggregation_filterOutSatellitePlmn_whenKeyIsTrue() {
+    public void filterOutSatellitePlmn_filterOutSatellitePlmn_whenKeyIsTrue() {
         PersistableBundle config = new PersistableBundle();
         config.putBoolean(
                 CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
@@ -304,11 +237,11 @@
         List<CellInfo> expected = Arrays.asList(
                 createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
                 createLteCellInfo(false, 1234, "123", "234", "CarrierC"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+        assertThat(mNetworkSelectSettings.filterOutSatellitePlmn(testList)).isEqualTo(expected);
     }
 
     @Test
-    public void doAggregation_filterOutSatellitePlmn_whenNoSatellitePlmnIsAvailable() {
+    public void filterOutSatellitePlmn_filterOutSatellitePlmn_whenNoSatellitePlmnIsAvailable() {
         PersistableBundle config = new PersistableBundle();
         config.putBoolean(
                 CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
@@ -336,17 +269,17 @@
                 createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
                 createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
                 createGsmCellInfo(false, 12345, "123", "235", "CarrierD"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+        assertThat(mNetworkSelectSettings.filterOutSatellitePlmn(testList)).isEqualTo(expected);
 
         // Expect no filter out when KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL is false.
         config.putBoolean(
                 CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false);
         mNetworkSelectSettings.onCreateInitialization();
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+        assertThat(mNetworkSelectSettings.filterOutSatellitePlmn(testList)).isEqualTo(expected);
     }
 
     @Test
-    public void doAggregation_filterOutSatellitePlmn_whenKeyIsFalse() {
+    public void filterOutSatellitePlmn_filterOutSatellitePlmn_whenKeyIsFalse() {
         PersistableBundle config = new PersistableBundle();
         config.putBoolean(
                 CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
@@ -372,7 +305,7 @@
                 createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
                 createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
                 createGsmCellInfo(false, 12345, "123", "235", "CarrierD"));
-        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+        assertThat(mNetworkSelectSettings.filterOutSatellitePlmn(testList)).isEqualTo(expected);
     }
 
     private CellInfoLte createLteCellInfo(boolean registered, int cellId, String mcc, String mnc,
