Merge "Fix NPE in AudioSwitchPreferenceController" into 24D1-dev
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,