diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java index 502c55d83b..db0b66c452 100644 --- a/framework/src/android/net/ConnectivitySettingsManager.java +++ b/framework/src/android/net/ConnectivitySettingsManager.java @@ -22,11 +22,9 @@ import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY; import static com.android.net.module.util.ConnectivitySettingsUtils.getNetworkLegacyGlobalAvoidBadWifiSetting; import static com.android.net.module.util.ConnectivitySettingsUtils.getNetworkAvoidBadWifiSetting; -import static com.android.net.module.util.ConnectivitySettingsUtils.convertCarrierAwareSettingsStringToMap; import static com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString; import static com.android.net.module.util.ConnectivitySettingsUtils.setNetworkLegacyGlobalAvoidBadWifiSetting; import static com.android.net.module.util.ConnectivitySettingsUtils.setNetworkAvoidBadWifiSetting; -import static com.android.net.module.util.ConnectivitySettingsUtils.convertCarrierAwareSettingsMapToString; import android.annotation.FlaggedApi; import android.annotation.IntDef; @@ -57,7 +55,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Duration; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.StringJoiner; @@ -384,6 +381,9 @@ public class ConnectivitySettingsManager { public static final String NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI = "network_carrier_aware_avoid_bad_wifi"; + private static final boolean DEFAULT_AVOID_BAD_WIFI = true; + private static final boolean DEFAULT_SHOULD_SHOW_AVOID_BAD_WIFI = false; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(value = { @@ -1043,35 +1043,21 @@ public class ConnectivitySettingsManager { @FlaggedApi(Flags.FLAG_CARRIER_AWARE_AVOID_BAD_WIFI) public static void setNetworkAvoidBadWifi(@NonNull Context context, int subId, @NetworkAvoidBadWifi int value) { - final String setting = getNetworkAvoidBadWifiSetting(context); - final Map settingMap = - convertCarrierAwareSettingsStringToMap(setting); + final String config; if (value == NETWORK_AVOID_BAD_WIFI_IGNORE) { - settingMap.put(subId, false); + config = "0"; } else if (value == NETWORK_AVOID_BAD_WIFI_AVOID) { - settingMap.put(subId, true); + config = "1"; } else if (value == NETWORK_AVOID_BAD_WIFI_PROMPT) { - settingMap.remove(subId); + config = null; } else { throw new IllegalArgumentException("Invalid avoid bad wifi setting"); } - if (settingMap.isEmpty()) { - setNetworkAvoidBadWifiSetting(context, null); - } else { - setNetworkAvoidBadWifiSetting( - context, - convertCarrierAwareSettingsMapToString(context, settingMap) - ); - } - // for backward compatibility, write to the old avoid bad wifi settings as well. - if (settingMap.containsKey(subId)) { - setNetworkLegacyGlobalAvoidBadWifiSetting(context, settingMap.get(subId) ? "1" : "0"); - } else { - setNetworkLegacyGlobalAvoidBadWifiSetting(context, null); - } + setNetworkAvoidBadWifiSetting(context, subId, config); + setNetworkLegacyGlobalAvoidBadWifiSetting(context, config); } /** @@ -1084,36 +1070,25 @@ public class ConnectivitySettingsManager { */ @FlaggedApi(Flags.FLAG_CARRIER_AWARE_AVOID_BAD_WIFI) public static boolean getNetworkAvoidBadWifi(@NonNull Context context, int subId) { - final String setting = - getNetworkAvoidBadWifiSetting(context); - final boolean defaultConfig = true; + final String setting = getNetworkAvoidBadWifiSetting(context, subId); // check new avoid bad wifi setting first if it's set - if (setting != null) { - final Map settingMap = - convertCarrierAwareSettingsStringToMap(setting); - if (settingMap.containsKey(subId)) { - return settingMap.get(subId); - } - } + if (setting != null) return !setting.equals("0"); // for backward compatibility, read the old avoid bad wifi settings if new key is not set. final String oldSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context); - if (oldSetting != null) { - if (oldSetting.equals("1")) { - return true; - } else if (oldSetting.equals("0")) { - return false; - } - } + if (oldSetting != null) return !oldSetting.equals("0"); // read carrier config if both new and old settings is not set. final CarrierConfigManager ccm = context.getSystemService(CarrierConfigManager.class); - if (ccm == null) return defaultConfig; + if (ccm == null) return DEFAULT_AVOID_BAD_WIFI; final PersistableBundle config = getConfigForSubId(ccm, subId, CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL); - return config.getBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, defaultConfig); + return config.getBoolean( + CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, + DEFAULT_AVOID_BAD_WIFI + ); } /** @@ -1130,21 +1105,18 @@ public class ConnectivitySettingsManager { */ @FlaggedApi(Flags.FLAG_CARRIER_AWARE_AVOID_BAD_WIFI) public static boolean shouldShowAvoidBadWifiToggle(@NonNull Context context, int subId) { - final String setting = - getNetworkAvoidBadWifiSetting(context); - final CarrierConfigManager ccm = context.getSystemService(CarrierConfigManager.class); - final boolean defaultConfig = true; - final boolean defaultDisplay = false; + final String setting = getNetworkAvoidBadWifiSetting(context, subId); // check new avoid bad wifi setting first if it's set if (setting != null) return true; // for backward compatibility, read the old avoid bad wifi if new setting is not set. - final String oldSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context); - if (oldSetting != null) return true; + final String legacySetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context); + if (legacySetting != null) return true; // default to false if system does not support CarrierConfigManager - if (ccm == null) return defaultDisplay; + final CarrierConfigManager ccm = context.getSystemService(CarrierConfigManager.class); + if (ccm == null) return DEFAULT_SHOULD_SHOW_AVOID_BAD_WIFI; final PersistableBundle config = getConfigForSubId( ccm, @@ -1153,7 +1125,8 @@ public class ConnectivitySettingsManager { CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL ); - if (!config.getBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, defaultConfig)) { + if (!config.getBoolean( + CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, DEFAULT_AVOID_BAD_WIFI)) { // It should not be possible to force a device to be stuck on bad wifi // and not give the user an option to change this, so if the device doesn't // avoid bad wifi, show the toggle even if KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL @@ -1162,7 +1135,9 @@ public class ConnectivitySettingsManager { } return config.getBoolean( - CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL, defaultDisplay); + CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL, + DEFAULT_SHOULD_SHOW_AVOID_BAD_WIFI + ); } diff --git a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java index e0bff53c93..544b9c38d9 100644 --- a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java +++ b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java @@ -20,10 +20,6 @@ import static android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION; import static android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI; import static android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE; -import static com.android.net.module.util.ConnectivitySettingsUtils.convertCarrierAwareSettingsStringToMap; -import static com.android.net.module.util.ConnectivitySettingsUtils.getNetworkAvoidBadWifiSetting; -import static com.android.net.module.util.ConnectivitySettingsUtils.getNetworkLegacyGlobalAvoidBadWifiSetting; - import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -35,6 +31,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.database.ContentObserver; +import android.net.ConnectivitySettingsManager; import android.net.Uri; import android.net.platform.flags.Flags; import android.os.Build; @@ -46,21 +43,17 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; -import android.util.ArrayMap; import android.util.Log; import com.android.connectivity.resources.R; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.build.SdkLevel; import com.android.net.module.util.DeviceConfigUtils; -import com.android.net.module.util.HandlerUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; @@ -90,7 +83,7 @@ public class MultinetworkPolicyTracker { @Override public void onCarrierConfigChanged( int slotIndex, int subId, int carrierId, int specificCarrierId) { - updateAvoidBadWifiFromCarrierConfigOnHandler(subId); + reevaluateInternal(); } } @@ -130,10 +123,6 @@ public class MultinetworkPolicyTracker { private final @Nullable CarrierConfigManager mCarrierConfigManager; private final @Nullable CarrierConfigChangeListener mCarrierConfigChangeListener; - // This will be accessed by background and handler thread - @GuardedBy("mAvoidBadWifiCarrierConfigForSubIdMap") - private final ArrayMap mAvoidBadWifiCarrierConfigForSubIdMap = - new ArrayMap<>(); private volatile boolean mAvoidBadWifi = true; private volatile int mMeteredMultipathPreference; private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -179,38 +168,14 @@ public class MultinetworkPolicyTracker { resources.getResourcesContext(), activeSubId); } - @VisibleForTesting - protected boolean readAvoidBadWifiFromCarrierConfig( - @NonNull final CarrierConfigManager ccm, final int subId) { - // Defaults to true to avoid potentially poor Wi-Fi and improve user experience. - final boolean defaultConfig = true; - if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - return defaultConfig; - } - - PersistableBundle config = null; - - try { - config = ccm.getConfigForSubId(subId, - CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL - ); - } catch (RuntimeException e) { - Log.e(TAG, "Failed to get config from carrier config", e); - } - - if (isCarrierConfigValid(config)) { - // If the "avoid bad Wi-Fi" setting is not defined in the carrier-specific config, - // retrieve the default configuration. - config = CarrierConfigManager.getDefaultConfig(); - } - - return config.getBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, defaultConfig); - } - protected boolean getAvoidBadWifiFromCarrierConfigFeature() { return Flags.avoidBadWifiFromCarrierConfig(); } + protected boolean getAvoidBadWifi(@NonNull Context context, int subId) { + return ConnectivitySettingsManager.getNetworkAvoidBadWifi(context, subId); + } + } private final Dependencies mDeps; @@ -323,8 +288,7 @@ public class MultinetworkPolicyTracker { ); // This ensures the latest carrier configuration is read. - final int subId = mActiveSubId; - mHandler.post(() -> updateAvoidBadWifiFromCarrierConfigOnHandler(subId)); + mHandler.post(() -> reevaluateInternal()); } else { mDeps.addOnDevicePropertiesChangedListener(handlerExecutor, properties -> reevaluateInternal()); @@ -455,106 +419,6 @@ public class MultinetworkPolicyTracker { updateMeteredMultipathPreference(); } - /** - * Reads the avoid bad Wi-Fi setting from the cache for a specific subscription ID. - * If no value is found for the given subId, it defaults to true. - */ - private boolean readAvoidBadWifiFromCache(int subId) { - synchronized (mAvoidBadWifiCarrierConfigForSubIdMap) { - return mAvoidBadWifiCarrierConfigForSubIdMap.getOrDefault(subId, true); - } - } - - /** - * Updates the cached avoid bad Wi-Fi setting for a specific subscription ID. - */ - private void updateAvoidBadWifiCache(int subId, boolean enable) { - synchronized (mAvoidBadWifiCarrierConfigForSubIdMap) { - mAvoidBadWifiCarrierConfigForSubIdMap.put(subId, enable); - } - } - - /** - * Updates the local cache of the "avoid bad Wi-Fi" setting from the carrier config - * for a specific subscription ID. - * Must be called on the handler thread. - */ - private void updateAvoidBadWifiFromCarrierConfig(int subId, boolean enable) { - updateAvoidBadWifiCache(subId, enable); - - if (subId == mActiveSubId) { - reevaluateInternal(); - } - } - - /** - * Retrieves the "avoid bad Wi-Fi" setting from the carrier configuration for the given subId, - * and updates the local cache asynchronously on the handler thread. - * Must be called on the background thread, because it makes an IPC to the phone process. - * It must not be called on the CS handler thread. - */ - private void updateAvoidBadWifiFromCarrierConfigOnHandler(int subId) { - HandlerUtils.ensureRunningOnHandlerThread(mHandler); - - if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - return; - } - - // CarrierConfigManager#getConfigForSubId() is supported - // only when system has FEATURE_TELEPHONY_SUBSCRIPTION - final boolean config = - mDeps.readAvoidBadWifiFromCarrierConfig(mCarrierConfigManager, subId); - updateAvoidBadWifiFromCarrierConfig(subId, config); - } - - /** - * Determines whether the device should avoid bad Wi-Fi connections based on a hierarchical - * preference for settings. - * - * This method checks for the "avoid bad Wi-Fi" setting by first looking for a - * **carrier-aware setting** via {@code NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI}. - * If this setting is present and contains a value for the {@code mActiveSubId}, - * that value is used. - * If {@code mActiveSubId} isn't explicitly found in the map, then fall back to the - * **legacy global setting** {@code NETWORK_AVOID_BAD_WIFI}. - * - * If the carrier-aware setting isn't available (i.e., it's {@code null}), the method then - * falls back to the **legacy global setting** {@code NETWORK_AVOID_BAD_WIFI}. - * This setting is considered {@code true} if its value is anything other than "0", - * and {@code false} if it is "0". - * - * Finally, if neither of the above settings is available (meaning both are {@code null}), - * the method retrieves the setting from a **local cache** using - * {@code readAvoidBadWifiFromCache(mActiveSubId)}. - * This is done to avoid potential IPC issues or blocking. - * - * @return {@code true} if the device should avoid bad Wi-Fi based on the highest priority - * available setting, {@code false} otherwise. - */ - private boolean getAvoidBadWifiInternal() { - final String carrierAwareSetting = - getNetworkAvoidBadWifiSetting(mContext); - if (carrierAwareSetting != null) { - final Map settingMap = - convertCarrierAwareSettingsStringToMap(carrierAwareSetting); - if (settingMap.containsKey(mActiveSubId)) { - return settingMap.get(mActiveSubId); - } - } - - // if NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI is not set, - // check NETWORK_AVOID_BAD_WIFI setting for backward compatible - final String setting = - getNetworkLegacyGlobalAvoidBadWifiSetting(mContext); - if (setting != null) { - return !setting.equals("0"); - } - - // Retrieve the avoid bad Wi-Fi setting from the local cache to avoid potential - // issues or blocking from the IPC call getAvoidBadWifiCarrierConfigForSubId(). - return readAvoidBadWifiFromCache(mActiveSubId); - } - /** * Updates the "avoid bad Wi-Fi" setting. * Depending on whether the carrier config feature is enabled, this method uses different logic: @@ -562,7 +426,7 @@ public class MultinetworkPolicyTracker { * If carrier config feature is ON (Android U+ and 25Q4+): * - Forces "actively prefer bad Wi-Fi" to true. * - Checks a system setting first. If it is enabled, we should avoid bad Wi-Fi. - * - If the system setting isn't available, it uses a cached value from the carrier config + * - If the system setting isn't available, it retrieves from the carrier config * for the current subId. * * If carrier config feature is OFF: @@ -582,7 +446,7 @@ public class MultinetworkPolicyTracker { // and mAvoidBadWifiFromCarrierConfigFeature is a trunk stable flag // that only exists in 25Q4+ mActivelyPreferBadWifi = true; - mAvoidBadWifi = getAvoidBadWifiInternal(); + mAvoidBadWifi = mDeps.getAvoidBadWifi(mContext, mActiveSubId); return mAvoidBadWifi != prevAvoid; case FROM_RESOURCE: final boolean settingAvoidBadWifi = "1".equals(readAvoidBadWifiFromSettings()); diff --git a/staticlibs/framework/com/android/net/module/util/ConnectivitySettingsUtils.java b/staticlibs/framework/com/android/net/module/util/ConnectivitySettingsUtils.java index 48b6438e5b..9f2eef19db 100644 --- a/staticlibs/framework/com/android/net/module/util/ConnectivitySettingsUtils.java +++ b/staticlibs/framework/com/android/net/module/util/ConnectivitySettingsUtils.java @@ -22,10 +22,6 @@ import android.content.ContentResolver; import android.content.Context; import android.provider.Settings; import android.text.TextUtils; -import android.util.ArrayMap; -import android.util.Log; - -import java.util.Map; /** * Collection of connectivity settings utilities. @@ -88,6 +84,23 @@ public class ConnectivitySettingsUtils { } } + /** + * Generates a unique setting key for the "avoid bad Wi-Fi" feature, + * specific to a given cellular subscription ID. + * This key is typically used to store and retrieve a preference + * that controls how the device manages Wi-Fi connectivity + * in the context of a particular cellular carrier. + * + * @param subId The unique identifier of the cellular subscription. + * @return A {@code String} representing the unique setting key. + * The key is constructed by appending the {@code subId} to a + * base constant string for carrier-aware "avoid bad Wi-Fi" settings, + * separated by a forward slash. + */ + public static String getAvoidBadWifiSettingKey(int subId) { + return NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI + "/" + subId; + } + /** * Get private DNS mode from settings. * @@ -172,15 +185,16 @@ public class ConnectivitySettingsUtils { * Set the carrier-aware avoid bad wifi to {@link Settings}. * * @param context The {@link Context} to set the setting. - * @param setting The desired setting string, formatted as "subId1,value1;subId2,value2". + * @param subId The subscription ID + * @param setting The desired setting string. * subId: The carrier subscription ID (integer). * value: "0" to not avoid bad Wi-Fi for this subscription, or "1" to avoid. * {@code null}: Ask the user whether to switch away from bad Wi-Fi. */ public static void setNetworkAvoidBadWifiSetting( - @NonNull Context context, @Nullable String setting) { + @NonNull Context context, int subId, @Nullable String setting) { Settings.Global.putString( - context.getContentResolver(), NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, setting); + context.getContentResolver(), getAvoidBadWifiSettingKey(subId), setting); } /** @@ -188,84 +202,13 @@ public class ConnectivitySettingsUtils { * @see #convertCarrierAwareSettingsStringToMap(String) * * @param context The {@link Context} to set the setting. - * @return The current setting string, formatted as "subId1,value1;subId2,value2", - * or {@code null} if the setting is not set. + * @param subId The subscription ID. + * @return The current setting string, formatted as + * "network_carrier_aware_avoid_bad_wifi/{subId}" or {@code null} if the setting is not set. */ @Nullable - public static String getNetworkAvoidBadWifiSetting(@NonNull Context context) { + public static String getNetworkAvoidBadWifiSetting(@NonNull Context context, int subId) { return Settings.Global.getString( - context.getContentResolver(), NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI); - } - - /** - * Parses the carrier-aware Wi-Fi avoid bad wifi setting string into a map. - * - * @param setting The setting string, typically retrieved from - * {@link #getNetworkAvoidBadWifiSetting(Context)}. - * Expected format is "subId1,value1;subId2,value2". - * @return A {@link Map} where keys are carrier subscription IDs ({@link Integer}) - * and values are booleans indicating whether to avoid bad Wi-Fi ({@code true} for avoid, - * {@code false} for not avoid). - * Returns an empty map if the input setting is null or invalid. - */ - @NonNull - public static Map convertCarrierAwareSettingsStringToMap( - @Nullable String setting) { - final ArrayMap settingMap = new ArrayMap<>(); - if (setting == null) { - return settingMap; - } - - for (String entry: setting.split(";")) { - final String[] parts = entry.split(","); - if (parts.length != 2) { - Log.e(TAG, "invalid setting string: " + entry); - continue; - } - - try { - int subId = Integer.parseInt(parts[0].trim()); - boolean value = Integer.parseInt(parts[1].trim()) != 0; - settingMap.put(subId, value); - } catch (NumberFormatException e) { - Log.e(TAG, "invalid setting string " + entry); - } - } - - return settingMap; - } - - /** - * Converts a map of carrier subscription IDs to Wi-Fi avoidance preferences into a string. - * - * @param context The application context. - * @param settingMap A {@link Map} where keys are carrier subscription IDs ({@link Integer}) - * and values are booleans indicating whether to avoid bad Wi-Fi ({@code true} for avoid, - * {@code false} for not avoid). - * This map will be converted into a "subId,value;subId2,value2" string format. - * @return A string representing the carrier-aware Wi-Fi avoidance settings, - * or {@code null} if the provided {@code settingMap} is empty. - * The format is "subId1,value1;subId2,value2". - */ - @Nullable - public static String convertCarrierAwareSettingsMapToString( - @NonNull Context context, @NonNull Map settingMap) { - if (settingMap.isEmpty()) return null; - - final StringBuilder sb = new StringBuilder(); - int index = 0; - - for (Map.Entry entry: settingMap.entrySet()) { - final String valueStr = entry.getValue() ? "1" : "0"; - sb.append(entry.getKey()) - .append(",") - .append(valueStr); - if (index < settingMap.size() - 1) { - sb.append(";"); - } - index++; - } - - return sb.toString(); + context.getContentResolver(), getAvoidBadWifiSettingKey(subId)); } } diff --git a/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt b/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt index c7ba27e7f4..24e5c5ea4c 100644 --- a/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt +++ b/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt @@ -74,7 +74,7 @@ import android.telephony.SubscriptionManager import android.util.Range import androidx.test.InstrumentationRegistry import androidx.test.filters.SmallTest -import com.android.net.module.util.ConnectivitySettingsUtils.convertCarrierAwareSettingsStringToMap +import com.android.net.module.util.ConnectivitySettingsUtils.getAvoidBadWifiSettingKey import com.android.net.module.util.ConnectivitySettingsUtils.getNetworkAvoidBadWifiSetting import com.android.net.module.util.ConnectivitySettingsUtils.getNetworkLegacyGlobalAvoidBadWifiSetting import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString @@ -135,16 +135,10 @@ class ConnectivitySettingsManagerTest { } } - private fun assertAvoidBadWifiSettingEquals(expected: String?, setting: String?) { - // The conversion is necessary because the strings may not be in the same order. - assertEquals( - convertCarrierAwareSettingsStringToMap( - expected - ), - convertCarrierAwareSettingsStringToMap( - setting - ) - ) + private fun assertAvoidBadWifiSettingEquals(expect: Array>) { + for ((subId, value) in expect) { + assertEquals(value, getNetworkAvoidBadWifiSetting(context, subId)) + } } fun testIntSetting( @@ -418,16 +412,18 @@ class ConnectivitySettingsManagerTest { @Test @IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) fun testSetNetworkAvoidBadWifiWithSettings() { - val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context) - val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context) + val testSubId = 1000 + val orgDefaultSubIdSetting = getNetworkAvoidBadWifiSetting(context, defaultSubId) + val orgTestSubIdSetting = getNetworkAvoidBadWifiSetting(context, testSubId) + val orgLegacySetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context) try { // initialize NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI and NETWORK_AVOID_BAD_WIFI to null - setNetworkAvoidBadWifiSetting(context, null) + setNetworkAvoidBadWifiSetting(context, defaultSubId, null) setNetworkLegacyGlobalAvoidBadWifiSetting(context, null) - val testSubId = 1000 // test with if new key NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI is set. - // format: "subId1,value1;subId2,value2;..." + // format: key: "network_carrier_aware_avoid_bad_wifi/{subId}" + // value: "value" // and if old key NETWORK_AVOID_BAD_WIFI is set as well. // format: "value" setNetworkAvoidBadWifi( @@ -436,8 +432,7 @@ class ConnectivitySettingsManagerTest { ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_AVOID ) assertAvoidBadWifiSettingEquals( - "$defaultSubId,1", - getNetworkAvoidBadWifiSetting(context) + arrayOf(Pair(defaultSubId, "1")) ) assertEquals( "1", @@ -450,8 +445,7 @@ class ConnectivitySettingsManagerTest { ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_IGNORE ) assertAvoidBadWifiSettingEquals( - "$defaultSubId,0", - getNetworkAvoidBadWifiSetting(context) + arrayOf(Pair(defaultSubId, "0")) ) assertEquals( "0", @@ -464,8 +458,10 @@ class ConnectivitySettingsManagerTest { ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_AVOID ) assertAvoidBadWifiSettingEquals( - "$defaultSubId,0;$testSubId,1", - getNetworkAvoidBadWifiSetting(context) + arrayOf( + Pair(defaultSubId, "0"), + Pair(testSubId, "1") + ) ) assertEquals( "1", @@ -478,8 +474,10 @@ class ConnectivitySettingsManagerTest { ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_IGNORE ) assertAvoidBadWifiSettingEquals( - "$defaultSubId,0;$testSubId,0", - getNetworkAvoidBadWifiSetting(context) + arrayOf( + Pair(defaultSubId, "0"), + Pair(testSubId, "0") + ) ) assertEquals( "0", @@ -492,8 +490,10 @@ class ConnectivitySettingsManagerTest { ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_PROMPT ) assertAvoidBadWifiSettingEquals( - "$defaultSubId,0", - getNetworkAvoidBadWifiSetting(context) + arrayOf( + Pair(defaultSubId, "0"), + Pair(testSubId, null) + ) ) assertEquals( null, @@ -506,8 +506,10 @@ class ConnectivitySettingsManagerTest { ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_PROMPT ) assertAvoidBadWifiSettingEquals( - null, - getNetworkAvoidBadWifiSetting(context) + arrayOf( + Pair(defaultSubId, null), + Pair(testSubId, null) + ) ) assertEquals( null, @@ -515,9 +517,17 @@ class ConnectivitySettingsManagerTest { ) } finally { resetSettings( - names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI), + names = arrayOf( + getAvoidBadWifiSettingKey(defaultSubId), + getAvoidBadWifiSettingKey(testSubId), + NETWORK_AVOID_BAD_WIFI + ), type = settingsTypeGlobal, - values = arrayOf(orgCarrierAwareSetting, orgSetting) + values = arrayOf( + orgDefaultSubIdSetting, + orgTestSubIdSetting, + orgLegacySetting + ) ) } } @@ -525,30 +535,13 @@ class ConnectivitySettingsManagerTest { @Test @IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) fun testGetNetworkAvoidBadWifiWithCarrierAwareSettings() { - val original = getNetworkAvoidBadWifiSetting(context) + val original = getNetworkAvoidBadWifiSetting(context, defaultSubId) try { - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1") - assertTrue(getNetworkAvoidBadWifi(context, defaultSubId)) - - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0") + setNetworkAvoidBadWifiSetting(context, defaultSubId, "0") assertFalse(getNetworkAvoidBadWifi(context, defaultSubId)) - val testSubId = 1000 - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0;$testSubId,1") - assertFalse(getNetworkAvoidBadWifi(context, defaultSubId)) - assertTrue(getNetworkAvoidBadWifi(context, testSubId)) - - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0;$testSubId,0") - assertFalse(getNetworkAvoidBadWifi(context, defaultSubId)) - assertFalse(getNetworkAvoidBadWifi(context, testSubId)) - - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1;$testSubId,0") + setNetworkAvoidBadWifiSetting(context, defaultSubId, "1") assertTrue(getNetworkAvoidBadWifi(context, defaultSubId)) - assertFalse(getNetworkAvoidBadWifi(context, testSubId)) - - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1;$testSubId,1") - assertTrue(getNetworkAvoidBadWifi(context, defaultSubId)) - assertTrue(getNetworkAvoidBadWifi(context, testSubId)) } finally { resetSettings( names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI), @@ -561,12 +554,12 @@ class ConnectivitySettingsManagerTest { @Test @IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) fun testGetNetworkAvoidBadWifiWithSettings() { - val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context) + val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context, defaultSubId) val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context) try { // test if NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI is not set, // then it check NETWORK_AVOID_BAD_WIFI for backward compatibility. - setNetworkAvoidBadWifiSetting(context, null) + setNetworkAvoidBadWifiSetting(context, defaultSubId, null) val testSubId = 1000 setNetworkLegacyGlobalAvoidBadWifiSetting(context, "0") @@ -588,12 +581,12 @@ class ConnectivitySettingsManagerTest { @Test @IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) fun testGetNetworkAvoidBadWifiWithCarrierConfig() { - val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context) + val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context, defaultSubId) val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context) try { // unset the global settings, then it depends on the carrier config mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId) - setNetworkAvoidBadWifiSetting(context, null) + setNetworkAvoidBadWifiSetting(context, defaultSubId, null) setNetworkLegacyGlobalAvoidBadWifiSetting(context, null) // default should be true if no carrier config key is set @@ -616,25 +609,25 @@ class ConnectivitySettingsManagerTest { @Test @IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) fun testShouldShowAvoidBadWifiToggleWithSettings() { - val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context) + val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context, defaultSubId) val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context) try { // unset the NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, and NETWORK_AVOID_BAD_WIFI, // it should be false since no carrier config is set - setNetworkAvoidBadWifiSetting(context, null) + setNetworkAvoidBadWifiSetting(context, defaultSubId, null) setNetworkLegacyGlobalAvoidBadWifiSetting(context, null) assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId)) // if any global settings is set, it should display the toggle. - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1") + setNetworkAvoidBadWifiSetting(context, defaultSubId, "1") assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId)) - setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0") + setNetworkAvoidBadWifiSetting(context, defaultSubId, "0") assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId)) // unset the NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, // then it check NETWORK_AVOID_BAD_WIFI for backward compatibility. - setNetworkAvoidBadWifiSetting(context, null) + setNetworkAvoidBadWifiSetting(context, defaultSubId, null) setNetworkLegacyGlobalAvoidBadWifiSetting(context, "1") assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId)) @@ -652,13 +645,13 @@ class ConnectivitySettingsManagerTest { @Test @IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) fun testShouldShowAvoidBadWifiToggleWithCarrierConfig() { - val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context) + val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context, defaultSubId) val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context) try { // unset both NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI and KEY_AVOID_BAD_WIFI_BOOL settings, // then it depends on the carrier config mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId) - setNetworkAvoidBadWifiSetting(context, null) + setNetworkAvoidBadWifiSetting(context, defaultSubId, null) setNetworkLegacyGlobalAvoidBadWifiSetting(context, null) // default should be false if KEY_AVOID_BAD_WIFI_BOOL is not set diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt index 48c681de0b..70410aa121 100644 --- a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt +++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt @@ -23,7 +23,6 @@ import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI -import android.net.ConnectivitySettingsManager.NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE import android.net.platform.flags.Flags.FLAG_AVOID_BAD_WIFI_FROM_CARRIER_CONFIG import android.os.Build @@ -281,81 +280,6 @@ class MultinetworkPolicyTrackerTest(private val supportCarrierConfigManager: Boo runOnActiveDataSubscriptionIdChanged() } - @Test - @FeatureFlag(name = FLAG_AVOID_BAD_WIFI_FROM_CARRIER_CONFIG, true) - @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) - fun testAvoidBadWifiWithGlobalSetting() { - val activeSubId = 1000 - // Mock the initial NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI setting to false - Settings.Global.putString(resolver, NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, "$activeSubId,0") - // Mock the initial carrier configuration to return true - trackerDependencies.setAvoidBadWifiCarrierConfigForSubId(activeSubId, true) - - val listenerCaptor = ArgumentCaptor.forClass( - ActiveDataSubscriptionIdListener::class.java - ) - verify(telephonyManager, times(1)) - .registerTelephonyCallback(any(), listenerCaptor.capture()) - val listener = listenerCaptor.value - csLooper.dispatchAll() - - // Simulate a change in the active data subscription ID to activeSubId. - listener.onActiveDataSubscriptionIdChanged(activeSubId) - - // Assert that the tracker's avoidBadWifi flag is false based on global setting - assertFalse(tracker.avoidBadWifi) - assertTrue(tracker.activelyPreferBadWifi) - - // Mock the NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI setting to true - Settings.Global.putString(resolver, NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, "$activeSubId,1") - // Mock the initial carrier configuration to return false - trackerDependencies.setAvoidBadWifiCarrierConfigForSubId(activeSubId, false) - - // Assert that the tracker's avoidBadWifi flag is true based on carrier aware setting - assertTrue(tracker.updateAvoidBadWifi()) - assertTrue(tracker.avoidBadWifi) - assertTrue(tracker.activelyPreferBadWifi) - - val testSubId = 1001 - // Mock the NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI setting to multiple carrier setting - Settings.Global.putString( - resolver, - NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, - "$activeSubId, 0;$testSubId, 1" - ) - - // Assert that the tracker's avoidBadWifi flag is false based on carrier aware setting - assertTrue(tracker.updateAvoidBadWifi()) - assertFalse(tracker.avoidBadWifi) - assertTrue(tracker.activelyPreferBadWifi) - - // Simulate a change in the active data subscription ID to testSubId. - listener.onActiveDataSubscriptionIdChanged(testSubId) - - // Assert that the tracker's avoidBadWifi flag is true based on carrier aware setting - assertTrue(tracker.avoidBadWifi) - assertTrue(tracker.activelyPreferBadWifi) - - // Unset NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI setting, - // it check NETWORK_AVOID_BAD_WIFI setting for backward compatible - Settings.Global.putString(resolver, NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, null) - // Mock the NETWORK_AVOID_BAD_WIFI setting to setting - Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") - - // Assert that the tracker's avoidBadWifi flag is true based on setting - assertTrue(tracker.updateAvoidBadWifi()) - assertFalse(tracker.avoidBadWifi) - assertTrue(tracker.activelyPreferBadWifi) - - // Mock the NETWORK_AVOID_BAD_WIFI setting to setting - Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1") - - // Assert that the tracker's avoidBadWifi flag is true based on setting - assertTrue(tracker.updateAvoidBadWifi()) - assertTrue(tracker.avoidBadWifi) - assertTrue(tracker.activelyPreferBadWifi) - } - @Test @FeatureFlag(name = FLAG_AVOID_BAD_WIFI_FROM_CARRIER_CONFIG, true) @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.BAKLAVA) diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt index b8a505e466..43b09bcb98 100644 --- a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt +++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt @@ -1,10 +1,10 @@ package com.android.server.connectivity +import android.content.Context import android.content.res.Resources import android.provider.DeviceConfig import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY import android.provider.DeviceConfig.OnPropertiesChangedListener -import android.telephony.CarrierConfigManager import com.android.internal.annotations.GuardedBy import com.android.server.connectivity.MultinetworkPolicyTracker.CONFIG_ACTIVELY_PREFER_BAD_WIFI import java.util.concurrent.Executor @@ -64,12 +64,10 @@ class MultinetworkPolicyTrackerTestDependencies( override fun getResourcesForActiveSubId(res: ConnectivityResources, id: Int): Resources = resources - override fun readAvoidBadWifiFromCarrierConfig( - ccm: CarrierConfigManager, - subId: Int - ): Boolean = - avoidBadWifiCarrierConfigForSubIdMap.getOrDefault(subId, true) - public override fun getAvoidBadWifiFromCarrierConfigFeature(): Boolean = avoidBadWifiFromCarrierConfigFeature + + public override fun getAvoidBadWifi(context: Context, subId: Int): Boolean { + return avoidBadWifiCarrierConfigForSubIdMap.getOrDefault(subId, true) + } }