Support "don't ask again" in the avoid bad wifi dialog.

This contains the following changes:

1. Make NETWORK_AVOID_BAD_WIFI a tristate: 0 means never avoid
   bad wifi, unset means prompt the user, 1 means always avoid.
2. Look at NETWORK_AVOID_BAD_WIFI only if the carrier restricts
   avoiding bad wifi (previously, we relied on the setting being
   null and defaulting to the value of the config variable).
3. Add an avoidUnvalidated bit to NetworkAgentInfo to track
   whether the user has requested switching away from this
   unvalidated network even though avoiding bad wifi is generally
   disabled. This is set to true when the user selects "switch"
   in the dialog without setting the "Don't ask again" checkbox.
4. Add a hidden setAvoidUnvalidated API to ConnectivityManager to
   set the avoidUnvalidated bit.
5. Additional unit test coverage.

Bug: 31075769
Change-Id: I1be60c3016c8095df3c4752330149ce638bd0ce1
This commit is contained in:
Lorenzo Colitti
2016-09-19 01:00:19 +09:00
parent 21924545a2
commit c65750c8a0
5 changed files with 174 additions and 23 deletions

View File

@@ -82,6 +82,7 @@ import com.android.server.net.NetworkPinner;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
@@ -601,6 +602,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
private class WrappedConnectivityService extends ConnectivityService {
private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
public boolean configRestrictsAvoidBadWifi;
public WrappedConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
@@ -656,6 +658,11 @@ public class ConnectivityServiceTest extends AndroidTestCase {
return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj);
}
@Override
public boolean configRestrictsAvoidBadWifi() {
return configRestrictsAvoidBadWifi;
}
public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
return mLastCreatedNetworkMonitor;
}
@@ -1957,8 +1964,48 @@ public class ConnectivityServiceTest extends AndroidTestCase {
@SmallTest
public void testAvoidBadWifiSetting() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
mService.configRestrictsAvoidBadWifi = false;
String[] values = new String[] {null, "0", "1"};
for (int i = 0; i < values.length; i++) {
Settings.Global.putInt(cr, settingName, 1);
mService.updateNetworkAvoidBadWifi();
mService.waitForIdle();
String msg = String.format("config=false, setting=%s", values[i]);
assertTrue(msg, mService.avoidBadWifi());
assertFalse(msg, mService.shouldNotifyWifiUnvalidated());
}
mService.configRestrictsAvoidBadWifi = true;
Settings.Global.putInt(cr, settingName, 0);
mService.updateNetworkAvoidBadWifi();
mService.waitForIdle();
assertFalse(mService.avoidBadWifi());
assertFalse(mService.shouldNotifyWifiUnvalidated());
Settings.Global.putInt(cr, settingName, 1);
mService.updateNetworkAvoidBadWifi();
mService.waitForIdle();
assertTrue(mService.avoidBadWifi());
assertFalse(mService.shouldNotifyWifiUnvalidated());
Settings.Global.putString(cr, settingName, null);
mService.updateNetworkAvoidBadWifi();
mService.waitForIdle();
assertFalse(mService.avoidBadWifi());
assertTrue(mService.shouldNotifyWifiUnvalidated());
}
@SmallTest
public void testAvoidBadWifi() throws Exception {
ContentResolver cr = mServiceContext.getContentResolver();
// Pretend we're on a carrier that restricts switching away from bad wifi.
mService.configRestrictsAvoidBadWifi = true;
// File a request for cell to ensure it doesn't go down.
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
final NetworkRequest cellRequest = new NetworkRequest.Builder()
@@ -1975,8 +2022,8 @@ public class ConnectivityServiceTest extends AndroidTestCase {
TestNetworkCallback validatedWifiCallback = new TestNetworkCallback();
mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback);
// Takes effect on every rematch.
Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 0);
mService.updateNetworkAvoidBadWifi();
// Bring up validated cell.
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -2005,7 +2052,42 @@ public class ConnectivityServiceTest extends AndroidTestCase {
NET_CAPABILITY_VALIDATED));
assertEquals(mCm.getActiveNetwork(), wifiNetwork);
// Simulate the user selecting "switch" on the dialog.
// Simulate switching to a carrier that does not restrict avoiding bad wifi, and expect
// that we switch back to cell.
mService.configRestrictsAvoidBadWifi = false;
mService.updateNetworkAvoidBadWifi();
defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
assertEquals(mCm.getActiveNetwork(), cellNetwork);
// Switch back to a restrictive carrier.
mService.configRestrictsAvoidBadWifi = true;
mService.updateNetworkAvoidBadWifi();
defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
assertEquals(mCm.getActiveNetwork(), wifiNetwork);
// Simulate the user selecting "switch" on the dialog, and check that we switch to cell.
mCm.setAvoidUnvalidated(wifiNetwork);
defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
NET_CAPABILITY_VALIDATED));
assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
NET_CAPABILITY_VALIDATED));
assertEquals(mCm.getActiveNetwork(), cellNetwork);
// Disconnect and reconnect wifi to clear the one-time switch above.
mWiFiNetworkAgent.disconnect();
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true);
defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
wifiNetwork = mWiFiNetworkAgent.getNetwork();
// Fail validation on wifi and expect the dialog to appear.
mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
mCm.reportNetworkConnectivity(wifiNetwork, false);
validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
// Simulate the user selecting "switch" and checking the don't ask again checkbox.
Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
mService.updateNetworkAvoidBadWifi();
@@ -2017,6 +2099,17 @@ public class ConnectivityServiceTest extends AndroidTestCase {
NET_CAPABILITY_VALIDATED));
assertEquals(mCm.getActiveNetwork(), cellNetwork);
// Simulate the user turning the cellular fallback setting off and then on.
// We switch to wifi and then to cell.
Settings.Global.putString(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
mService.updateNetworkAvoidBadWifi();
defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
assertEquals(mCm.getActiveNetwork(), wifiNetwork);
Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
mService.updateNetworkAvoidBadWifi();
defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
assertEquals(mCm.getActiveNetwork(), cellNetwork);
// If cell goes down, we switch to wifi.
mCellNetworkAgent.disconnect();
defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);