Merge "Provide a way to override the avoid bad wifi configuration"

This commit is contained in:
Chiachang Wang
2021-06-23 00:48:17 +00:00
committed by Gerrit Code Review
5 changed files with 119 additions and 25 deletions

View File

@@ -4712,6 +4712,22 @@ public class ConnectivityManager {
}
}
/**
* Temporarily allow bad wifi to override {@code config_networkAvoidBadWifi} configuration.
*
* @param timeMs The expired current time. The value should be set within a limited time from
* now.
*
* @hide
*/
public void setTestAllowBadWifiUntil(long timeMs) {
try {
mService.setTestAllowBadWifiUntil(timeMs);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Requests that the system open the captive portal app on the specified network.
*

View File

@@ -226,4 +226,6 @@ interface IConnectivityManager
void offerNetwork(int providerId, in NetworkScore score,
in NetworkCapabilities caps, in INetworkOfferCallback callback);
void unofferNetwork(in INetworkOfferCallback callback);
void setTestAllowBadWifiUntil(long timeMs);
}

View File

@@ -75,6 +75,7 @@ public class MultinetworkPolicyTracker {
private volatile boolean mAvoidBadWifi = true;
private volatile int mMeteredMultipathPreference;
private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private volatile long mTestAllowBadWifiUntilMs = 0;
// Mainline module can't use internal HandlerExecutor, so add an identical executor here.
private static class HandlerExecutor implements Executor {
@@ -162,14 +163,31 @@ public class MultinetworkPolicyTracker {
* Whether the device or carrier configuration disables avoiding bad wifi by default.
*/
public boolean configRestrictsAvoidBadWifi() {
final boolean allowBadWifi = mTestAllowBadWifiUntilMs > 0
&& mTestAllowBadWifiUntilMs > System.currentTimeMillis();
// If the config returns true, then avoid bad wifi design can be controlled by the
// NETWORK_AVOID_BAD_WIFI setting.
if (allowBadWifi) return true;
// TODO: use R.integer.config_networkAvoidBadWifi directly
final int id = mResources.get().getIdentifier("config_networkAvoidBadWifi",
"integer", mResources.getResourcesContext().getPackageName());
return (getResourcesForActiveSubId().getInteger(id) == 0);
}
/**
* Temporarily allow bad wifi to override {@code config_networkAvoidBadWifi} configuration.
* The value works when the time set is more than {@link System.currentTimeMillis()}.
*/
public void setTestAllowBadWifiUntil(long timeMs) {
Log.d(TAG, "setTestAllowBadWifiUntil: " + mTestAllowBadWifiUntilMs);
mTestAllowBadWifiUntilMs = timeMs;
updateAvoidBadWifi();
}
@VisibleForTesting
@NonNull
private Resources getResourcesForActiveSubId() {
protected Resources getResourcesForActiveSubId() {
return SubscriptionManager.getResourcesForSubId(
mResources.getResourcesContext(), mActiveSubId);
}

View File

@@ -650,6 +650,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54;
/**
* Event to set temporary allow bad wifi within a limited time to override
* {@code config_networkAvoidBadWifi}.
*/
private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55;
/**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
@@ -662,6 +668,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
/**
* The maximum alive time to allow bad wifi configuration for testing.
*/
private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L;
private static String eventName(int what) {
return sMagicDecoderRing.get(what, Integer.toString(what));
}
@@ -4334,6 +4345,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
}
@Override
public void setTestAllowBadWifiUntil(long timeMs) {
enforceSettingsPermission();
if (!Build.isDebuggable()) {
throw new IllegalStateException("Does not support in non-debuggable build");
}
if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) {
throw new IllegalArgumentException("It should not exceed "
+ MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now");
}
mHandler.sendMessage(
mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs));
}
private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
if (DBG) log("handleSetAcceptUnvalidated network=" + network +
" accept=" + accept + " always=" + always);
@@ -4876,6 +4903,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED:
handleMobileDataPreferredUidsChanged();
break;
case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL:
final long timeMs = ((Long) msg.obj).longValue();
mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs);
break;
}
}
}

View File

@@ -1496,8 +1496,7 @@ public class ConnectivityServiceTest {
return mService.getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd;
}
private static class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker {
volatile boolean mConfigRestrictsAvoidBadWifi;
private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker {
volatile int mConfigMeteredMultipathPreference;
WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
@@ -1505,8 +1504,8 @@ public class ConnectivityServiceTest {
}
@Override
public boolean configRestrictsAvoidBadWifi() {
return mConfigRestrictsAvoidBadWifi;
protected Resources getResourcesForActiveSubId() {
return mResources;
}
@Override
@@ -1723,7 +1722,9 @@ public class ConnectivityServiceTest {
.getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any());
doReturn(R.array.network_switch_type_name).when(mResources)
.getIdentifier(eq("network_switch_type_name"), eq("array"), any());
doReturn(R.integer.config_networkAvoidBadWifi).when(mResources)
.getIdentifier(eq("config_networkAvoidBadWifi"), eq("integer"), any());
doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
final ConnectivityResources connRes = mock(ConnectivityResources.class);
doReturn(mResources).when(connRes).get();
@@ -4645,30 +4646,29 @@ public class ConnectivityServiceTest {
}
@Test
public void testAvoidBadWifiSetting() throws Exception {
public void testSetAllowBadWifiUntil() throws Exception {
runAsShell(NETWORK_SETTINGS,
() -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() + 5_000L));
waitForIdle();
testAvoidBadWifiConfig_controlledBySettings();
runAsShell(NETWORK_SETTINGS,
() -> mService.setTestAllowBadWifiUntil(System.currentTimeMillis() - 5_000L));
waitForIdle();
testAvoidBadWifiConfig_ignoreSettings();
}
private void testAvoidBadWifiConfig_controlledBySettings() {
final ContentResolver cr = mServiceContext.getContentResolver();
final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
mPolicyTracker.mConfigRestrictsAvoidBadWifi = false;
String[] values = new String[] {null, "0", "1"};
for (int i = 0; i < values.length; i++) {
Settings.Global.putInt(cr, settingName, 1);
mPolicyTracker.reevaluate();
waitForIdle();
String msg = String.format("config=false, setting=%s", values[i]);
assertTrue(mService.avoidBadWifi());
assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated());
}
mPolicyTracker.mConfigRestrictsAvoidBadWifi = true;
Settings.Global.putInt(cr, settingName, 0);
Settings.Global.putString(cr, settingName, "0");
mPolicyTracker.reevaluate();
waitForIdle();
assertFalse(mService.avoidBadWifi());
assertFalse(mPolicyTracker.shouldNotifyWifiUnvalidated());
Settings.Global.putInt(cr, settingName, 1);
Settings.Global.putString(cr, settingName, "1");
mPolicyTracker.reevaluate();
waitForIdle();
assertTrue(mService.avoidBadWifi());
@@ -4681,13 +4681,40 @@ public class ConnectivityServiceTest {
assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated());
}
private void testAvoidBadWifiConfig_ignoreSettings() {
final ContentResolver cr = mServiceContext.getContentResolver();
final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
String[] values = new String[] {null, "0", "1"};
for (int i = 0; i < values.length; i++) {
Settings.Global.putString(cr, settingName, values[i]);
mPolicyTracker.reevaluate();
waitForIdle();
String msg = String.format("config=false, setting=%s", values[i]);
assertTrue(mService.avoidBadWifi());
assertFalse(msg, mPolicyTracker.shouldNotifyWifiUnvalidated());
}
}
@Test
public void testAvoidBadWifiSetting() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
final String settingName = ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
testAvoidBadWifiConfig_ignoreSettings();
doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
testAvoidBadWifiConfig_controlledBySettings();
}
@Ignore("Refactoring in progress b/178071397")
@Test
public void testAvoidBadWifi() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
// Pretend we're on a carrier that restricts switching away from bad wifi.
mPolicyTracker.mConfigRestrictsAvoidBadWifi = true;
doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
// File a request for cell to ensure it doesn't go down.
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -4738,13 +4765,13 @@ public class ConnectivityServiceTest {
// Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect
// that we switch back to cell.
mPolicyTracker.mConfigRestrictsAvoidBadWifi = false;
doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
mPolicyTracker.reevaluate();
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertEquals(mCm.getActiveNetwork(), cellNetwork);
// Switch back to a restrictive carrier.
mPolicyTracker.mConfigRestrictsAvoidBadWifi = true;
doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
mPolicyTracker.reevaluate();
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertEquals(mCm.getActiveNetwork(), wifiNetwork);