Introduce carrier-aware avoid bad Wi-Fi APIs
This commit introduces new system APIs to manage "avoid bad Wi-Fi" settings, leveraging both global system settings and carrier configurations. This enhancement allows for more granular control and visibility into how Wi-Fi networks are managed, especially in multi-SIM environments. The new `setNetworkAvoidBadWifi(Context, int subId)` method provides the ability to programmatically control this setting based on carrier-specific policies or user preferences. This complements `getNetworkAvoidBadWifi(Context, int subId)`, which allows querying the setting for a specific subscription ID, ensuring the system can accurately determine the avoid bad Wi-Fi status. Additionally, `shouldShowAvoidBadWifiToggle(Context, int subId)` is introduced. This method determines whether the 'Avoid Bad Wi-Fi' user interface toggle should be displayed. It considers both global settings and carrier configurations, allowing for dynamic UI adjustments based on carrier requirements or user preferences. These changes provide greater flexibility for managing Wi-Fi network selection and improve the user experience by offering more context-aware control over cellular behavior. Deprecated APIs: - `setNetworkAvoidBadWifi(Context, int value)` - `getNetworkAvoidBadWifi(Context)` New APIs: - `setNetworkAvoidBadWifi(Context, int subId, int value)` - `getNetworkAvoidBadWifi(Context, int subId)` - `shouldShowAvoidBadWifiToggle(Context, int subId)` Flag: com.android.net.flags.carrier_aware_avoid_bad_wifi Bug: 410976315 Test: atest ConnectivityCoverageTests:android.net.connectivity.android.net.ConnectivitySettingsManagerTest Change-Id: I79469cfe865a585593219d226c8198206c06b589
This commit is contained in:
parent
5548278f28
commit
92e23acebb
6 changed files with 809 additions and 72 deletions
|
|
@ -208,3 +208,11 @@ flag {
|
||||||
bug: "419123367"
|
bug: "419123367"
|
||||||
is_fixed_read_only: true
|
is_fixed_read_only: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flag {
|
||||||
|
name: "carrier_aware_avoid_bad_wifi"
|
||||||
|
namespace: "android_core_networking"
|
||||||
|
description: "Flag for API to provide carrier-aware avoid bad Wi-Fi setting."
|
||||||
|
bug: "410976315"
|
||||||
|
is_fixed_read_only: true
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ java_defaults {
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"com.android.net.flags-aconfig-java",
|
"com.android.net.flags-aconfig-java",
|
||||||
|
"android.net.platform.flags-aconfig-java-export",
|
||||||
// Not using the latest stable version because all functions in the latest version of
|
// Not using the latest stable version because all functions in the latest version of
|
||||||
// mdns_aidl_interface are deprecated.
|
// mdns_aidl_interface are deprecated.
|
||||||
"mdns_aidl_interface-V1-java",
|
"mdns_aidl_interface-V1-java",
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,8 @@ package android.net {
|
||||||
method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
|
method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
|
||||||
method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
|
method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
|
||||||
method @NonNull public static java.util.Set<java.lang.Integer> getMobileDataPreferredUids(@NonNull android.content.Context);
|
method @NonNull public static java.util.Set<java.lang.Integer> getMobileDataPreferredUids(@NonNull android.content.Context);
|
||||||
method public static int getNetworkAvoidBadWifi(@NonNull android.content.Context);
|
method @Deprecated @FlaggedApi("com.android.net.flags.carrier_aware_avoid_bad_wifi") public static int getNetworkAvoidBadWifi(@NonNull android.content.Context);
|
||||||
|
method @FlaggedApi("com.android.net.flags.carrier_aware_avoid_bad_wifi") public static boolean getNetworkAvoidBadWifi(@NonNull android.content.Context, int);
|
||||||
method @Nullable public static String getNetworkMeteredMultipathPreference(@NonNull android.content.Context);
|
method @Nullable public static String getNetworkMeteredMultipathPreference(@NonNull android.content.Context);
|
||||||
method public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, int);
|
method public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, int);
|
||||||
method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
|
method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
|
||||||
|
|
@ -114,7 +115,8 @@ package android.net {
|
||||||
method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
|
method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
|
||||||
method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
|
method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
|
||||||
method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
|
method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
|
||||||
method public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int);
|
method @Deprecated @FlaggedApi("com.android.net.flags.carrier_aware_avoid_bad_wifi") public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int);
|
||||||
|
method @FlaggedApi("com.android.net.flags.carrier_aware_avoid_bad_wifi") public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int, int);
|
||||||
method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String);
|
method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String);
|
||||||
method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int);
|
method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int);
|
||||||
method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
|
method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
|
||||||
|
|
@ -124,6 +126,7 @@ package android.net {
|
||||||
method public static void setUidsAllowedOnRestrictedNetworks(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
|
method public static void setUidsAllowedOnRestrictedNetworks(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
|
||||||
method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
|
method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
|
||||||
method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
|
method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
|
||||||
|
method @FlaggedApi("com.android.net.flags.carrier_aware_avoid_bad_wifi") public static boolean shouldShowAvoidBadWifiToggle(@NonNull android.content.Context, int);
|
||||||
field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
|
field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
|
||||||
field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
|
field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
|
||||||
field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
|
field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,15 @@ import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
|
||||||
import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE;
|
import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE;
|
||||||
import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
|
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.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;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.IntRange;
|
import android.annotation.IntRange;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
|
@ -32,14 +39,17 @@ import android.content.pm.PackageManager;
|
||||||
import android.net.ConnectivityManager.MultipathPreference;
|
import android.net.ConnectivityManager.MultipathPreference;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.telephony.CarrierConfigManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Range;
|
import android.util.Range;
|
||||||
|
|
||||||
|
import com.android.net.flags.Flags;
|
||||||
import com.android.net.module.util.ConnectivitySettingsUtils;
|
import com.android.net.module.util.ConnectivitySettingsUtils;
|
||||||
import com.android.net.module.util.ProxyUtils;
|
import com.android.net.module.util.ProxyUtils;
|
||||||
|
|
||||||
|
|
@ -47,6 +57,7 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
|
@ -61,6 +72,29 @@ public class ConnectivitySettingsManager {
|
||||||
|
|
||||||
private ConnectivitySettingsManager() {}
|
private ConnectivitySettingsManager() {}
|
||||||
|
|
||||||
|
private static boolean isCarrierConfigValid(@Nullable PersistableBundle config) {
|
||||||
|
return config != null && !config.isEmpty()
|
||||||
|
&& CarrierConfigManager.isConfigForIdentifiedCarrier(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NonNull PersistableBundle getConfigForSubId(
|
||||||
|
@NonNull CarrierConfigManager ccm, int subId, @NonNull String... keys) {
|
||||||
|
PersistableBundle config = null;
|
||||||
|
try {
|
||||||
|
config = ccm.getConfigForSubId(subId, keys);
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
/** Data activity timeout settings */
|
/** Data activity timeout settings */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -324,6 +358,32 @@ public class ConnectivitySettingsManager {
|
||||||
*/
|
*/
|
||||||
public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2;
|
public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per-carrier setting whether to switch away from wifi networks that lose access.
|
||||||
|
*
|
||||||
|
* When a device is connected to both mobile and wifi, and wifi loses Internet
|
||||||
|
* access, normally the device will switch to the mobile network.
|
||||||
|
* Carrier config can override this default behavior per-carrier.
|
||||||
|
* This setting, if defined, overrides both the default and carrier config
|
||||||
|
* for that particular carrier.
|
||||||
|
*
|
||||||
|
* The format is a semicolon-separated list of `subId,value` pairs, where:
|
||||||
|
*
|
||||||
|
* subId: The carrier subscription ID (integer).
|
||||||
|
* value: Controls the avoidance behavior for the corresponding `subId`.
|
||||||
|
*
|
||||||
|
* Valid values are:
|
||||||
|
* 0: Don't avoid bad Wi-Fi for this subscription, and don't prompt the user.
|
||||||
|
* 1: Avoid bad Wi-Fi for this subscription.
|
||||||
|
*
|
||||||
|
* For example: "1,1;2,0" would mean subId 1 avoids bad Wi-Fi, and subId 2 does not.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@FlaggedApi(Flags.FLAG_CARRIER_AWARE_AVOID_BAD_WIFI)
|
||||||
|
public static final String NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI =
|
||||||
|
"network_carrier_aware_avoid_bad_wifi";
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef(value = {
|
@IntDef(value = {
|
||||||
|
|
@ -931,11 +991,13 @@ public class ConnectivitySettingsManager {
|
||||||
* @param context The {@link Context} to query the setting.
|
* @param context The {@link Context} to query the setting.
|
||||||
* @return The setting whether to automatically switch away from wifi networks that lose
|
* @return The setting whether to automatically switch away from wifi networks that lose
|
||||||
* internet access.
|
* internet access.
|
||||||
|
* @deprecated Use {@link #getNetworkAvoidBadWifi(Context, int)} instead.
|
||||||
*/
|
*/
|
||||||
|
@FlaggedApi(Flags.FLAG_CARRIER_AWARE_AVOID_BAD_WIFI)
|
||||||
|
@Deprecated
|
||||||
@NetworkAvoidBadWifi
|
@NetworkAvoidBadWifi
|
||||||
public static int getNetworkAvoidBadWifi(@NonNull Context context) {
|
public static int getNetworkAvoidBadWifi(@NonNull Context context) {
|
||||||
final String setting =
|
final String setting = getNetworkLegacyGlobalAvoidBadWifiSetting(context);
|
||||||
Settings.Global.getString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI);
|
|
||||||
if ("0".equals(setting)) {
|
if ("0".equals(setting)) {
|
||||||
return NETWORK_AVOID_BAD_WIFI_IGNORE;
|
return NETWORK_AVOID_BAD_WIFI_IGNORE;
|
||||||
} else if ("1".equals(setting)) {
|
} else if ("1".equals(setting)) {
|
||||||
|
|
@ -951,7 +1013,10 @@ public class ConnectivitySettingsManager {
|
||||||
* @param context The {@link Context} to set the setting.
|
* @param context The {@link Context} to set the setting.
|
||||||
* @param value Whether to automatically switch away from wifi networks that lose internet
|
* @param value Whether to automatically switch away from wifi networks that lose internet
|
||||||
* access.
|
* access.
|
||||||
|
* @deprecated Use {@link #setNetworkAvoidBadWifi(Context, int, int)} instead.
|
||||||
*/
|
*/
|
||||||
|
@FlaggedApi(Flags.FLAG_CARRIER_AWARE_AVOID_BAD_WIFI)
|
||||||
|
@Deprecated
|
||||||
public static void setNetworkAvoidBadWifi(@NonNull Context context,
|
public static void setNetworkAvoidBadWifi(@NonNull Context context,
|
||||||
@NetworkAvoidBadWifi int value) {
|
@NetworkAvoidBadWifi int value) {
|
||||||
final String setting;
|
final String setting;
|
||||||
|
|
@ -964,7 +1029,141 @@ public class ConnectivitySettingsManager {
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid avoid bad wifi setting");
|
throw new IllegalArgumentException("Invalid avoid bad wifi setting");
|
||||||
}
|
}
|
||||||
Settings.Global.putString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI, setting);
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set avoid bad wifi setting to {@link Settings} with specific subscription ID.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} to set the setting.
|
||||||
|
* @param subId The subscription ID to query carrier configurations for.
|
||||||
|
* @param value Whether to automatically switch away from wifi networks that lose internet
|
||||||
|
* access.
|
||||||
|
*/
|
||||||
|
@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<Integer, Boolean> settingMap =
|
||||||
|
convertCarrierAwareSettingsStringToMap(setting);
|
||||||
|
|
||||||
|
if (value == NETWORK_AVOID_BAD_WIFI_IGNORE) {
|
||||||
|
settingMap.put(subId, false);
|
||||||
|
} else if (value == NETWORK_AVOID_BAD_WIFI_AVOID) {
|
||||||
|
settingMap.put(subId, true);
|
||||||
|
} else if (value == NETWORK_AVOID_BAD_WIFI_PROMPT) {
|
||||||
|
settingMap.remove(subId);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get avoid bad wifi setting from {@link Settings} with specific subscription ID.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} to query the setting and system services.
|
||||||
|
* @param subId The subscription ID to query carrier configurations for.
|
||||||
|
* @return The setting whether to automatically switch away from wifi networks that lose
|
||||||
|
* internet access.
|
||||||
|
*/
|
||||||
|
@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;
|
||||||
|
// check new avoid bad wifi setting first if it's set
|
||||||
|
if (setting != null) {
|
||||||
|
final Map<Integer, Boolean> settingMap =
|
||||||
|
convertCarrierAwareSettingsStringToMap(setting);
|
||||||
|
if (settingMap.containsKey(subId)) {
|
||||||
|
return settingMap.get(subId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read carrier config if both new and old settings is not set.
|
||||||
|
final CarrierConfigManager ccm = context.getSystemService(CarrierConfigManager.class);
|
||||||
|
if (ccm == null) return defaultConfig;
|
||||||
|
|
||||||
|
final PersistableBundle config =
|
||||||
|
getConfigForSubId(ccm, subId, CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL);
|
||||||
|
|
||||||
|
return config.getBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, defaultConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the "Avoid Bad Wi-Fi" toggle should be displayed to the user.
|
||||||
|
*
|
||||||
|
* This method checks both global system settings and carrier configurations to decide
|
||||||
|
* if the option for automatically switching away from Wi-Fi networks with no internet
|
||||||
|
* access should be visible in the user interface.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} to query settings and system services.
|
||||||
|
* @param subId The subscription ID to query carrier configurations for.
|
||||||
|
* @return {@code true} if the "Avoid Bad Wi-Fi" toggle should be shown;
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// default to false if system does not support CarrierConfigManager
|
||||||
|
if (ccm == null) return defaultDisplay;
|
||||||
|
|
||||||
|
final PersistableBundle config = getConfigForSubId(
|
||||||
|
ccm,
|
||||||
|
subId,
|
||||||
|
CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL,
|
||||||
|
CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!config.getBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, defaultConfig)) {
|
||||||
|
// 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
|
||||||
|
// is false.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.getBoolean(
|
||||||
|
CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL, defaultDisplay);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of connectivity settings utilities.
|
* Collection of connectivity settings utilities.
|
||||||
|
|
@ -29,6 +33,7 @@ import android.text.TextUtils;
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class ConnectivitySettingsUtils {
|
public class ConnectivitySettingsUtils {
|
||||||
|
public static final String TAG = ConnectivitySettingsUtils.class.getSimpleName();
|
||||||
public static final int PRIVATE_DNS_MODE_OFF = 1;
|
public static final int PRIVATE_DNS_MODE_OFF = 1;
|
||||||
public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
|
public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
|
||||||
public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
|
public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
|
||||||
|
|
@ -40,6 +45,10 @@ public class ConnectivitySettingsUtils {
|
||||||
public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
|
public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
|
||||||
public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
|
public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
|
||||||
|
|
||||||
|
public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
|
||||||
|
public static final String NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI =
|
||||||
|
"network_carrier_aware_avoid_bad_wifi";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get private DNS mode as string.
|
* Get private DNS mode as string.
|
||||||
*
|
*
|
||||||
|
|
@ -128,4 +137,135 @@ public class ConnectivitySettingsUtils {
|
||||||
public static void setPrivateDnsHostname(@NonNull Context context, @Nullable String specifier) {
|
public static void setPrivateDnsHostname(@NonNull Context context, @Nullable String specifier) {
|
||||||
Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER, specifier);
|
Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER, specifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set legacy global avoid bad wifi to {@link Settings}.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} to set the setting.
|
||||||
|
* @param setting The desired setting value.
|
||||||
|
* "0": Don't avoid bad Wi-Fi.
|
||||||
|
* "1": Avoid bad Wi-Fi.
|
||||||
|
* {@code null}: Ask the user whether to switch away from bad Wi-Fi.
|
||||||
|
* @deprecated Use {@link #setNetworkAvoidBadWifiSetting(Context, String)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static void setNetworkLegacyGlobalAvoidBadWifiSetting(
|
||||||
|
@NonNull Context context, @Nullable String setting) {
|
||||||
|
Settings.Global.putString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI, setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get legacy global avoid bad wifi to {@link Settings}.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} to query the setting.
|
||||||
|
* @return The current setting value, which can be "0", "1", or {@code null}.
|
||||||
|
* Returns {@code null} if the setting is not found.
|
||||||
|
* @deprecated Use {@link #getNetworkAvoidBadWifiSetting(Context)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Nullable
|
||||||
|
public static String getNetworkLegacyGlobalAvoidBadWifiSetting(@NonNull Context context) {
|
||||||
|
return Settings.Global.getString(context.getContentResolver(), NETWORK_AVOID_BAD_WIFI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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".
|
||||||
|
* 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) {
|
||||||
|
Settings.Global.putString(
|
||||||
|
context.getContentResolver(), NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the raw carrier-aware avoid bad wifi string from {@link Settings}.
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static String getNetworkAvoidBadWifiSetting(@NonNull Context context) {
|
||||||
|
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<Integer, Boolean> convertCarrierAwareSettingsStringToMap(
|
||||||
|
@Nullable String setting) {
|
||||||
|
final ArrayMap<Integer, Boolean> 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<Integer, Boolean> settingMap) {
|
||||||
|
if (settingMap.isEmpty()) return null;
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, Boolean> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES
|
||||||
import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS
|
import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS
|
||||||
import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT
|
import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT
|
||||||
import android.net.ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON
|
import android.net.ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON
|
||||||
|
import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI
|
||||||
|
import android.net.ConnectivitySettingsManager.NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI
|
||||||
import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT
|
import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT
|
||||||
import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS
|
import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS
|
||||||
import android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE
|
import android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE
|
||||||
|
|
@ -42,6 +44,7 @@ import android.net.ConnectivitySettingsManager.getDnsResolverSuccessThresholdPer
|
||||||
import android.net.ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond
|
import android.net.ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond
|
||||||
import android.net.ConnectivitySettingsManager.getMobileDataActivityTimeout
|
import android.net.ConnectivitySettingsManager.getMobileDataActivityTimeout
|
||||||
import android.net.ConnectivitySettingsManager.getMobileDataAlwaysOn
|
import android.net.ConnectivitySettingsManager.getMobileDataAlwaysOn
|
||||||
|
import android.net.ConnectivitySettingsManager.getNetworkAvoidBadWifi
|
||||||
import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationMaximumDailyCount
|
import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationMaximumDailyCount
|
||||||
import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationRateDuration
|
import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationRateDuration
|
||||||
import android.net.ConnectivitySettingsManager.getPrivateDnsDefaultMode
|
import android.net.ConnectivitySettingsManager.getPrivateDnsDefaultMode
|
||||||
|
|
@ -55,27 +58,42 @@ import android.net.ConnectivitySettingsManager.setDnsResolverSuccessThresholdPer
|
||||||
import android.net.ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond
|
import android.net.ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond
|
||||||
import android.net.ConnectivitySettingsManager.setMobileDataActivityTimeout
|
import android.net.ConnectivitySettingsManager.setMobileDataActivityTimeout
|
||||||
import android.net.ConnectivitySettingsManager.setMobileDataAlwaysOn
|
import android.net.ConnectivitySettingsManager.setMobileDataAlwaysOn
|
||||||
|
import android.net.ConnectivitySettingsManager.setNetworkAvoidBadWifi
|
||||||
import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationMaximumDailyCount
|
import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationMaximumDailyCount
|
||||||
import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationRateDuration
|
import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationRateDuration
|
||||||
import android.net.ConnectivitySettingsManager.setPrivateDnsDefaultMode
|
import android.net.ConnectivitySettingsManager.setPrivateDnsDefaultMode
|
||||||
import android.net.ConnectivitySettingsManager.setWifiAlwaysRequested
|
import android.net.ConnectivitySettingsManager.setWifiAlwaysRequested
|
||||||
import android.net.ConnectivitySettingsManager.setWifiDataActivityTimeout
|
import android.net.ConnectivitySettingsManager.setWifiDataActivityTimeout
|
||||||
|
import android.net.ConnectivitySettingsManager.shouldShowAvoidBadWifiToggle
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.PersistableBundle
|
||||||
import android.platform.test.annotations.AppModeFull
|
import android.platform.test.annotations.AppModeFull
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.telephony.CarrierConfigManager
|
||||||
|
import android.telephony.SubscriptionManager
|
||||||
import android.util.Range
|
import android.util.Range
|
||||||
import androidx.test.InstrumentationRegistry
|
import androidx.test.InstrumentationRegistry
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.net.module.util.ConnectivitySettingsUtils.convertCarrierAwareSettingsStringToMap
|
||||||
|
import com.android.net.module.util.ConnectivitySettingsUtils.getNetworkAvoidBadWifiSetting
|
||||||
|
import com.android.net.module.util.ConnectivitySettingsUtils.getNetworkLegacyGlobalAvoidBadWifiSetting
|
||||||
import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString
|
import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString
|
||||||
|
import com.android.net.module.util.ConnectivitySettingsUtils.setNetworkAvoidBadWifiSetting
|
||||||
|
import com.android.net.module.util.ConnectivitySettingsUtils.setNetworkLegacyGlobalAvoidBadWifiSetting
|
||||||
import com.android.testutils.ConnectivityModuleTest
|
import com.android.testutils.ConnectivityModuleTest
|
||||||
|
import com.android.testutils.DevSdkIgnoreRule
|
||||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
|
||||||
import com.android.testutils.DevSdkIgnoreRunner
|
import com.android.testutils.DevSdkIgnoreRunner
|
||||||
import junit.framework.Assert.assertEquals
|
import com.android.testutils.com.android.testutils.CarrierConfigRule
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.Objects
|
import java.util.Objects
|
||||||
|
import junit.framework.Assert.assertEquals
|
||||||
|
import junit.framework.Assert.assertFalse
|
||||||
|
import junit.framework.Assert.assertTrue
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for [ConnectivitySettingsManager].
|
* Tests for [ConnectivitySettingsManager].
|
||||||
|
|
@ -98,12 +116,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
private val settingsTypeGlobal = "global"
|
private val settingsTypeGlobal = "global"
|
||||||
private val settingsTypeSecure = "secure"
|
private val settingsTypeSecure = "secure"
|
||||||
|
|
||||||
|
private val defaultSubId = SubscriptionManager.getDefaultSubscriptionId()
|
||||||
|
|
||||||
/*** Reset setting value or delete setting if the setting was not existed before testing. */
|
/*** Reset setting value or delete setting if the setting was not existed before testing. */
|
||||||
private fun resetSettings(names: Array<String>, type: String, values: Array<String?>) {
|
private fun resetSettings(names: Array<String>, type: String, values: Array<String?>) {
|
||||||
for (i in names.indices) {
|
for (i in names.indices) {
|
||||||
if (Objects.equals(values[i], null)) {
|
if (Objects.equals(values[i], null)) {
|
||||||
instrumentation.uiAutomation.executeShellCommand(
|
instrumentation.uiAutomation.executeShellCommand(
|
||||||
"settings delete $type ${names[i]}")
|
"settings delete $type ${names[i]}"
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
if (settingsTypeSecure.equals(type)) {
|
if (settingsTypeSecure.equals(type)) {
|
||||||
Settings.Secure.putString(resolver, names[i], values[i])
|
Settings.Secure.putString(resolver, names[i], values[i])
|
||||||
|
|
@ -114,6 +135,18 @@ 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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> testIntSetting(
|
fun <T> testIntSetting(
|
||||||
names: Array<String>,
|
names: Array<String>,
|
||||||
type: String,
|
type: String,
|
||||||
|
|
@ -148,32 +181,67 @@ class ConnectivitySettingsManagerTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun overrideAvoidBadWifiCarrierConfig(
|
||||||
|
avoidBadWifi: Boolean? = null,
|
||||||
|
showAvoidBadWifiToggle: Boolean? = null
|
||||||
|
) {
|
||||||
|
// Override carrier config to ignore entitlement check.
|
||||||
|
val bundle = PersistableBundle()
|
||||||
|
|
||||||
|
avoidBadWifi?.let { value ->
|
||||||
|
bundle.putBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
showAvoidBadWifiToggle?.let { value ->
|
||||||
|
bundle.putBoolean(CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
mCarrierConfigRule.addConfigOverrides(defaultSubId, bundle)
|
||||||
|
}
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val mCarrierConfigRule: CarrierConfigRule = CarrierConfigRule()
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val ignoreRule = DevSdkIgnoreRule()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMobileDataActivityTimeout() {
|
fun testMobileDataActivityTimeout() {
|
||||||
testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_MOBILE), type = settingsTypeGlobal,
|
testIntSetting(
|
||||||
value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2),
|
names = arrayOf(DATA_ACTIVITY_TIMEOUT_MOBILE),
|
||||||
getter = { getMobileDataActivityTimeout(context, defaultDuration) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setMobileDataActivityTimeout(context, it) },
|
value1 = Duration.ofSeconds(testTime1),
|
||||||
testIntValues = intArrayOf(testTime1.toInt()))
|
value2 = Duration.ofSeconds(testTime2),
|
||||||
|
getter = { getMobileDataActivityTimeout(context, defaultDuration) },
|
||||||
|
setter = { setMobileDataActivityTimeout(context, it) },
|
||||||
|
testIntValues = intArrayOf(testTime1.toInt())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testWifiDataActivityTimeout() {
|
fun testWifiDataActivityTimeout() {
|
||||||
testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_WIFI), type = settingsTypeGlobal,
|
testIntSetting(
|
||||||
value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2),
|
names = arrayOf(DATA_ACTIVITY_TIMEOUT_WIFI),
|
||||||
getter = { getWifiDataActivityTimeout(context, defaultDuration) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setWifiDataActivityTimeout(context, it) },
|
value1 = Duration.ofSeconds(testTime1),
|
||||||
testIntValues = intArrayOf(testTime1.toInt()))
|
value2 = Duration.ofSeconds(testTime2),
|
||||||
|
getter = { getWifiDataActivityTimeout(context, defaultDuration) },
|
||||||
|
setter = { setWifiDataActivityTimeout(context, it) },
|
||||||
|
testIntValues = intArrayOf(testTime1.toInt())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDnsResolverSampleValidityDuration() {
|
fun testDnsResolverSampleValidityDuration() {
|
||||||
testIntSetting(names = arrayOf(DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS),
|
testIntSetting(
|
||||||
type = settingsTypeGlobal, value1 = Duration.ofSeconds(testTime1),
|
names = arrayOf(DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS),
|
||||||
value2 = Duration.ofSeconds(testTime2),
|
type = settingsTypeGlobal,
|
||||||
getter = { getDnsResolverSampleValidityDuration(context, defaultDuration) },
|
value1 = Duration.ofSeconds(testTime1),
|
||||||
setter = { setDnsResolverSampleValidityDuration(context, it) },
|
value2 = Duration.ofSeconds(testTime2),
|
||||||
testIntValues = intArrayOf(testTime1.toInt()))
|
getter = { getDnsResolverSampleValidityDuration(context, defaultDuration) },
|
||||||
|
setter = { setDnsResolverSampleValidityDuration(context, it) },
|
||||||
|
testIntValues = intArrayOf(testTime1.toInt())
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setDnsResolverSampleValidityDuration(context, Duration.ofSeconds(-1L)) }
|
setDnsResolverSampleValidityDuration(context, Duration.ofSeconds(-1L)) }
|
||||||
|
|
@ -181,11 +249,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDnsResolverSuccessThresholdPercent() {
|
fun testDnsResolverSuccessThresholdPercent() {
|
||||||
testIntSetting(names = arrayOf(DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT),
|
testIntSetting(
|
||||||
type = settingsTypeGlobal, value1 = 5, value2 = 10,
|
names = arrayOf(DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT),
|
||||||
getter = { getDnsResolverSuccessThresholdPercent(context, 0 /* def */) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setDnsResolverSuccessThresholdPercent(context, it) },
|
value1 = 5,
|
||||||
testIntValues = intArrayOf(5))
|
value2 = 10,
|
||||||
|
getter = { getDnsResolverSuccessThresholdPercent(context, 0 /* def */) },
|
||||||
|
setter = { setDnsResolverSuccessThresholdPercent(context, it) },
|
||||||
|
testIntValues = intArrayOf(5)
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setDnsResolverSuccessThresholdPercent(context, -1) }
|
setDnsResolverSuccessThresholdPercent(context, -1) }
|
||||||
|
|
@ -195,11 +267,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDnsResolverSampleRanges() {
|
fun testDnsResolverSampleRanges() {
|
||||||
testIntSetting(names = arrayOf(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_MAX_SAMPLES),
|
testIntSetting(
|
||||||
type = settingsTypeGlobal, value1 = Range(1, 63), value2 = Range(2, 62),
|
names = arrayOf(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_MAX_SAMPLES),
|
||||||
getter = { getDnsResolverSampleRanges(context) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setDnsResolverSampleRanges(context, it) },
|
value1 = Range(1, 63),
|
||||||
testIntValues = intArrayOf(1, 63))
|
value2 = Range(2, 62),
|
||||||
|
getter = { getDnsResolverSampleRanges(context) },
|
||||||
|
setter = { setDnsResolverSampleRanges(context, it) },
|
||||||
|
testIntValues = intArrayOf(1, 63)
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setDnsResolverSampleRanges(context, Range(-1, 62)) }
|
setDnsResolverSampleRanges(context, Range(-1, 62)) }
|
||||||
|
|
@ -209,11 +285,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNetworkSwitchNotificationMaximumDailyCount() {
|
fun testNetworkSwitchNotificationMaximumDailyCount() {
|
||||||
testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT),
|
testIntSetting(
|
||||||
type = settingsTypeGlobal, value1 = 5, value2 = 15,
|
names = arrayOf(NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT),
|
||||||
getter = { getNetworkSwitchNotificationMaximumDailyCount(context, 0 /* def */) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setNetworkSwitchNotificationMaximumDailyCount(context, it) },
|
value1 = 5,
|
||||||
testIntValues = intArrayOf(5))
|
value2 = 15,
|
||||||
|
getter = { getNetworkSwitchNotificationMaximumDailyCount(context, 0 /* def */) },
|
||||||
|
setter = { setNetworkSwitchNotificationMaximumDailyCount(context, it) },
|
||||||
|
testIntValues = intArrayOf(5)
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setNetworkSwitchNotificationMaximumDailyCount(context, -1) }
|
setNetworkSwitchNotificationMaximumDailyCount(context, -1) }
|
||||||
|
|
@ -221,12 +301,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNetworkSwitchNotificationRateDuration() {
|
fun testNetworkSwitchNotificationRateDuration() {
|
||||||
testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS),
|
testIntSetting(
|
||||||
type = settingsTypeGlobal, value1 = Duration.ofMillis(testTime1),
|
names = arrayOf(NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS),
|
||||||
value2 = Duration.ofMillis(testTime2),
|
type = settingsTypeGlobal,
|
||||||
getter = { getNetworkSwitchNotificationRateDuration(context, defaultDuration) },
|
value1 = Duration.ofMillis(testTime1),
|
||||||
setter = { setNetworkSwitchNotificationRateDuration(context, it) },
|
value2 = Duration.ofMillis(testTime2),
|
||||||
testIntValues = intArrayOf(testTime1.toInt()))
|
getter = { getNetworkSwitchNotificationRateDuration(context, defaultDuration) },
|
||||||
|
setter = { setNetworkSwitchNotificationRateDuration(context, it) },
|
||||||
|
testIntValues = intArrayOf(testTime1.toInt())
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setNetworkSwitchNotificationRateDuration(context, Duration.ofMillis(-1L)) }
|
setNetworkSwitchNotificationRateDuration(context, Duration.ofMillis(-1L)) }
|
||||||
|
|
@ -234,11 +317,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCaptivePortalMode() {
|
fun testCaptivePortalMode() {
|
||||||
testIntSetting(names = arrayOf(CAPTIVE_PORTAL_MODE), type = settingsTypeGlobal,
|
testIntSetting(
|
||||||
value1 = CAPTIVE_PORTAL_MODE_AVOID, value2 = CAPTIVE_PORTAL_MODE_PROMPT,
|
names = arrayOf(CAPTIVE_PORTAL_MODE),
|
||||||
getter = { getCaptivePortalMode(context, CAPTIVE_PORTAL_MODE_IGNORE) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setCaptivePortalMode(context, it) },
|
value1 = CAPTIVE_PORTAL_MODE_AVOID,
|
||||||
testIntValues = intArrayOf(CAPTIVE_PORTAL_MODE_AVOID))
|
value2 = CAPTIVE_PORTAL_MODE_PROMPT,
|
||||||
|
getter = { getCaptivePortalMode(context, CAPTIVE_PORTAL_MODE_IGNORE) },
|
||||||
|
setter = { setCaptivePortalMode(context, it) },
|
||||||
|
testIntValues = intArrayOf(CAPTIVE_PORTAL_MODE_AVOID)
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setCaptivePortalMode(context, 5 /* mode */) }
|
setCaptivePortalMode(context, 5 /* mode */) }
|
||||||
|
|
@ -254,11 +341,16 @@ class ConnectivitySettingsManagerTest {
|
||||||
assertEquals(mode, getPrivateDnsDefaultMode(context))
|
assertEquals(mode, getPrivateDnsDefaultMode(context))
|
||||||
|
|
||||||
setPrivateDnsDefaultMode(context, PRIVATE_DNS_MODE_OFF)
|
setPrivateDnsDefaultMode(context, PRIVATE_DNS_MODE_OFF)
|
||||||
assertEquals(getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OFF),
|
assertEquals(
|
||||||
getPrivateDnsDefaultMode(context))
|
getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OFF),
|
||||||
|
getPrivateDnsDefaultMode(context)
|
||||||
|
)
|
||||||
} finally {
|
} finally {
|
||||||
resetSettings(names = arrayOf(PRIVATE_DNS_DEFAULT_MODE), type = settingsTypeGlobal,
|
resetSettings(
|
||||||
values = arrayOf(original))
|
names = arrayOf(PRIVATE_DNS_DEFAULT_MODE),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(original)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
|
|
@ -267,12 +359,15 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testConnectivityKeepPendingIntentDuration() {
|
fun testConnectivityKeepPendingIntentDuration() {
|
||||||
testIntSetting(names = arrayOf(CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS),
|
testIntSetting(
|
||||||
type = settingsTypeSecure, value1 = Duration.ofMillis(testTime1),
|
names = arrayOf(CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS),
|
||||||
value2 = Duration.ofMillis(testTime2),
|
type = settingsTypeSecure,
|
||||||
getter = { getConnectivityKeepPendingIntentDuration(context, defaultDuration) },
|
value1 = Duration.ofMillis(testTime1),
|
||||||
setter = { setConnectivityKeepPendingIntentDuration(context, it) },
|
value2 = Duration.ofMillis(testTime2),
|
||||||
testIntValues = intArrayOf(testTime1.toInt()))
|
getter = { getConnectivityKeepPendingIntentDuration(context, defaultDuration) },
|
||||||
|
setter = { setConnectivityKeepPendingIntentDuration(context, it) },
|
||||||
|
testIntValues = intArrayOf(testTime1.toInt())
|
||||||
|
)
|
||||||
|
|
||||||
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
|
||||||
setConnectivityKeepPendingIntentDuration(context, Duration.ofMillis(-1L)) }
|
setConnectivityKeepPendingIntentDuration(context, Duration.ofMillis(-1L)) }
|
||||||
|
|
@ -280,20 +375,28 @@ class ConnectivitySettingsManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMobileDataAlwaysOn() {
|
fun testMobileDataAlwaysOn() {
|
||||||
testIntSetting(names = arrayOf(MOBILE_DATA_ALWAYS_ON), type = settingsTypeGlobal,
|
testIntSetting(
|
||||||
value1 = false, value2 = true,
|
names = arrayOf(MOBILE_DATA_ALWAYS_ON),
|
||||||
getter = { getMobileDataAlwaysOn(context, true /* def */) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setMobileDataAlwaysOn(context, it) },
|
value1 = false,
|
||||||
testIntValues = intArrayOf(0))
|
value2 = true,
|
||||||
|
getter = { getMobileDataAlwaysOn(context, true /* def */) },
|
||||||
|
setter = { setMobileDataAlwaysOn(context, it) },
|
||||||
|
testIntValues = intArrayOf(0)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testWifiAlwaysRequested() {
|
fun testWifiAlwaysRequested() {
|
||||||
testIntSetting(names = arrayOf(WIFI_ALWAYS_REQUESTED), type = settingsTypeGlobal,
|
testIntSetting(
|
||||||
value1 = false, value2 = true,
|
names = arrayOf(WIFI_ALWAYS_REQUESTED),
|
||||||
getter = { getWifiAlwaysRequested(context, true /* def */) },
|
type = settingsTypeGlobal,
|
||||||
setter = { setWifiAlwaysRequested(context, it) },
|
value1 = false,
|
||||||
testIntValues = intArrayOf(0))
|
value2 = true,
|
||||||
|
getter = { getWifiAlwaysRequested(context, true /* def */) },
|
||||||
|
setter = { setWifiAlwaysRequested(context, it) },
|
||||||
|
testIntValues = intArrayOf(0)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConnectivityModuleTest // get/setIngressRateLimitInBytesPerSecond was added via module update
|
@ConnectivityModuleTest // get/setIngressRateLimitInBytesPerSecond was added via module update
|
||||||
|
|
@ -311,4 +414,287 @@ class ConnectivitySettingsManagerTest {
|
||||||
setIngressRateLimitInBytesPerSecond(context, -10)
|
setIngressRateLimitInBytesPerSecond(context, -10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
|
||||||
|
fun testSetNetworkAvoidBadWifiWithSettings() {
|
||||||
|
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
|
||||||
|
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
try {
|
||||||
|
// initialize NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI and NETWORK_AVOID_BAD_WIFI to null
|
||||||
|
setNetworkAvoidBadWifiSetting(context, 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;..."
|
||||||
|
// and if old key NETWORK_AVOID_BAD_WIFI is set as well.
|
||||||
|
// format: "value"
|
||||||
|
setNetworkAvoidBadWifi(
|
||||||
|
context,
|
||||||
|
defaultSubId,
|
||||||
|
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_AVOID
|
||||||
|
)
|
||||||
|
assertAvoidBadWifiSettingEquals(
|
||||||
|
"$defaultSubId,1",
|
||||||
|
getNetworkAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"1",
|
||||||
|
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
setNetworkAvoidBadWifi(
|
||||||
|
context,
|
||||||
|
defaultSubId,
|
||||||
|
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_IGNORE
|
||||||
|
)
|
||||||
|
assertAvoidBadWifiSettingEquals(
|
||||||
|
"$defaultSubId,0",
|
||||||
|
getNetworkAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"0",
|
||||||
|
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
setNetworkAvoidBadWifi(
|
||||||
|
context,
|
||||||
|
testSubId,
|
||||||
|
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_AVOID
|
||||||
|
)
|
||||||
|
assertAvoidBadWifiSettingEquals(
|
||||||
|
"$defaultSubId,0;$testSubId,1",
|
||||||
|
getNetworkAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"1",
|
||||||
|
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
setNetworkAvoidBadWifi(
|
||||||
|
context,
|
||||||
|
testSubId,
|
||||||
|
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_IGNORE
|
||||||
|
)
|
||||||
|
assertAvoidBadWifiSettingEquals(
|
||||||
|
"$defaultSubId,0;$testSubId,0",
|
||||||
|
getNetworkAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"0",
|
||||||
|
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
setNetworkAvoidBadWifi(
|
||||||
|
context,
|
||||||
|
testSubId,
|
||||||
|
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_PROMPT
|
||||||
|
)
|
||||||
|
assertAvoidBadWifiSettingEquals(
|
||||||
|
"$defaultSubId,0",
|
||||||
|
getNetworkAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
setNetworkAvoidBadWifi(
|
||||||
|
context,
|
||||||
|
defaultSubId,
|
||||||
|
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_PROMPT
|
||||||
|
)
|
||||||
|
assertAvoidBadWifiSettingEquals(
|
||||||
|
null,
|
||||||
|
getNetworkAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
resetSettings(
|
||||||
|
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(orgCarrierAwareSetting, orgSetting)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
|
||||||
|
fun testGetNetworkAvoidBadWifiWithCarrierAwareSettings() {
|
||||||
|
val original = getNetworkAvoidBadWifiSetting(context)
|
||||||
|
try {
|
||||||
|
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1")
|
||||||
|
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
|
||||||
|
|
||||||
|
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")
|
||||||
|
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),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(original)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
|
||||||
|
fun testGetNetworkAvoidBadWifiWithSettings() {
|
||||||
|
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
|
||||||
|
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)
|
||||||
|
|
||||||
|
val testSubId = 1000
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "0")
|
||||||
|
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
|
||||||
|
assertFalse(getNetworkAvoidBadWifi(context, testSubId))
|
||||||
|
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "1")
|
||||||
|
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
|
||||||
|
assertTrue(getNetworkAvoidBadWifi(context, testSubId))
|
||||||
|
} finally {
|
||||||
|
resetSettings(
|
||||||
|
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(orgCarrierAwareSetting, orgSetting)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
|
||||||
|
fun testGetNetworkAvoidBadWifiWithCarrierConfig() {
|
||||||
|
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
|
||||||
|
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
|
||||||
|
try {
|
||||||
|
// unset the global settings, then it depends on the carrier config
|
||||||
|
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId)
|
||||||
|
setNetworkAvoidBadWifiSetting(context, null)
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
|
||||||
|
|
||||||
|
// default should be true if no carrier config key is set
|
||||||
|
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
|
||||||
|
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true)
|
||||||
|
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
|
||||||
|
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false)
|
||||||
|
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
|
||||||
|
} finally {
|
||||||
|
resetSettings(
|
||||||
|
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(orgCarrierAwareSetting, orgSetting)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
|
||||||
|
fun testShouldShowAvoidBadWifiToggleWithSettings() {
|
||||||
|
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
|
||||||
|
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)
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
|
||||||
|
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
// if any global settings is set, it should display the toggle.
|
||||||
|
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1")
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
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)
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "1")
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "0")
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
} finally {
|
||||||
|
resetSettings(
|
||||||
|
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(orgCarrierAwareSetting, orgSetting)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
|
||||||
|
fun testShouldShowAvoidBadWifiToggleWithCarrierConfig() {
|
||||||
|
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
|
||||||
|
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)
|
||||||
|
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
|
||||||
|
|
||||||
|
// default should be false if KEY_AVOID_BAD_WIFI_BOOL is not set
|
||||||
|
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
// if KEY_AVOID_BAD_WIFI_BOOL is true, then check KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL
|
||||||
|
// default should be false if KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL is not set
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true)
|
||||||
|
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
// it should be true if KEY_AVOID_BAD_WIFI_BOOL is false
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false)
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
// Even if the carrier says not to show the toggle, when the carrier says
|
||||||
|
// not to avoid bad wifi it should be shown.
|
||||||
|
// This is because 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.
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false, showAvoidBadWifiToggle = false)
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false, showAvoidBadWifiToggle = true)
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
// if KEY_AVOID_BAD_WIFI_BOOL is true, then check KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true, showAvoidBadWifiToggle = false)
|
||||||
|
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
|
||||||
|
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true, showAvoidBadWifiToggle = true)
|
||||||
|
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
|
||||||
|
} finally {
|
||||||
|
resetSettings(
|
||||||
|
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
|
||||||
|
type = settingsTypeGlobal,
|
||||||
|
values = arrayOf(orgCarrierAwareSetting, orgSetting)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue