Allow wifi and ethenet connected at same time.

This will improve the user experience on Android TV devices,
see bug for details.

In addition when connecting adb to the device by ethernet
for cts, wifi will not connect, causing lots of tests to fail.
For example:
[CTS7.1]android.net.wifi.cts.WifiInfoTest#testWifiInfoProperties
[CTS7.1]android.net.cts.ConnectivityManagerTest#testConnectivityChanged_
manifestRequestOnlyPreN_shouldReceiveIntent

Use command:settings to put global wifi_data_always_on 1 to enable it.

Bug: 26102779
Test: Manual, CTS.
Change-Id: I711d93061a6bc7164d98a858912f781e1b967406
This commit is contained in:
Leif Hendrik Wilden
2018-05-02 12:05:24 -07:00
parent b7c67f8e24
commit 838c66128f
2 changed files with 45 additions and 22 deletions

View File

@@ -390,9 +390,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
private static final int EVENT_PROMPT_UNVALIDATED = 29;
/**
* used internally to (re)configure mobile data always-on settings.
* used internally to (re)configure always-on networks.
*/
private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30;
private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
/**
* used to add a network listener with a pending intent
@@ -748,6 +748,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
// The default WiFi request is a background request so that apps using WiFi are
// migrated to a better network (typically ethernet) when one comes up, instead
// of staying on WiFi forever.
mDefaultWifiRequest = createDefaultInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
mHandlerThread = new HandlerThread("ConnectivityServiceThread");
mHandlerThread.start();
mHandler = new InternalHandler(mHandlerThread.getLooper());
@@ -944,8 +950,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
// by subclassing SettingsObserver.
@VisibleForTesting
void updateMobileDataAlwaysOn() {
mHandler.sendEmptyMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON);
void updateAlwaysOnNetworks() {
mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
}
// See FakeSettingsProvider comment above.
@@ -954,22 +960,30 @@ public class ConnectivityService extends IConnectivityManager.Stub
mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
}
private void handleMobileDataAlwaysOn() {
private void handleAlwaysOnNetworkRequest(
NetworkRequest networkRequest, String settingName, boolean defaultValue) {
final boolean enable = toBool(Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 1));
final boolean isEnabled = (mNetworkRequests.get(mDefaultMobileDataRequest) != null);
mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
if (enable == isEnabled) {
return; // Nothing to do.
}
if (enable) {
handleRegisterNetworkRequest(new NetworkRequestInfo(
null, mDefaultMobileDataRequest, new Binder()));
null, networkRequest, new Binder()));
} else {
handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID);
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID);
}
}
private void handleConfigureAlwaysOnNetworks() {
handleAlwaysOnNetworkRequest(
mDefaultMobileDataRequest,Settings.Global.MOBILE_DATA_ALWAYS_ON, true);
handleAlwaysOnNetworkRequest(mDefaultWifiRequest, Settings.Global.WIFI_ALWAYS_REQUESTED,
false);
}
private void registerSettingsCallbacks() {
// Watch for global HTTP proxy changes.
mSettingsObserver.observe(
@@ -979,7 +993,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Watch for whether or not to keep mobile data always on.
mSettingsObserver.observe(
Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON),
EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON);
EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
// Watch for whether or not to keep wifi always on.
mSettingsObserver.observe(
Settings.Global.getUriFor(Settings.Global.WIFI_ALWAYS_REQUESTED),
EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
}
private void registerPrivateDnsSettingsCallbacks() {
@@ -1814,8 +1833,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// for user to unlock device too.
updateLockdownVpn();
// Configure whether mobile data is always on.
mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON));
// Create network requests for always-on networks.
mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
@@ -3106,8 +3125,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
handlePromptUnvalidated((Network) msg.obj);
break;
}
case EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON: {
handleMobileDataAlwaysOn();
case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
handleConfigureAlwaysOnNetworks();
break;
}
// Sent by KeepaliveTracker to process an app request on the state machine thread.
@@ -4535,6 +4554,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
// priority networks like Wi-Fi are active.
private final NetworkRequest mDefaultMobileDataRequest;
// Request used to optionally keep wifi data active even when higher
// priority networks like ethernet are active.
private final NetworkRequest mDefaultWifiRequest;
private NetworkAgentInfo getNetworkForRequest(int requestId) {
synchronized (mNetworkForRequestId) {
return mNetworkForRequestId.get(requestId);

View File

@@ -1070,13 +1070,13 @@ public class ConnectivityServiceTest {
// Ensure that the default setting for Captive Portals is used for most tests
setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
setMobileDataAlwaysOn(false);
setAlwaysOnNetworks(false);
setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
}
@After
public void tearDown() throws Exception {
setMobileDataAlwaysOn(false);
setAlwaysOnNetworks(false);
if (mCellNetworkAgent != null) {
mCellNetworkAgent.disconnect();
mCellNetworkAgent = null;
@@ -2027,7 +2027,7 @@ public class ConnectivityServiceTest {
@Test
public void testNetworkGoesIntoBackgroundAfterLinger() {
setMobileDataAlwaysOn(true);
setAlwaysOnNetworks(true);
NetworkRequest request = new NetworkRequest.Builder()
.clearCapabilities()
.build();
@@ -2772,10 +2772,10 @@ public class ConnectivityServiceTest {
Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
}
private void setMobileDataAlwaysOn(boolean enable) {
private void setAlwaysOnNetworks(boolean enable) {
ContentResolver cr = mServiceContext.getContentResolver();
Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
mService.updateMobileDataAlwaysOn();
mService.updateAlwaysOnNetworks();
waitForIdle();
}
@@ -2797,7 +2797,7 @@ public class ConnectivityServiceTest {
public void testBackgroundNetworks() throws Exception {
// Create a background request. We can't do this ourselves because ConnectivityService
// doesn't have an API for it. So just turn on mobile data always on.
setMobileDataAlwaysOn(true);
setAlwaysOnNetworks(true);
final NetworkRequest request = new NetworkRequest.Builder().build();
final NetworkRequest fgRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_FOREGROUND).build();
@@ -2995,7 +2995,7 @@ public class ConnectivityServiceTest {
// Turn on mobile data always on. The factory starts looking again.
testFactory.expectAddRequests(1);
setMobileDataAlwaysOn(true);
setAlwaysOnNetworks(true);
testFactory.waitForNetworkRequests(2);
assertTrue(testFactory.getMyStartRequested());
@@ -3015,7 +3015,7 @@ public class ConnectivityServiceTest {
// Turn off mobile data always on and expect the request to disappear...
testFactory.expectRemoveRequests(1);
setMobileDataAlwaysOn(false);
setAlwaysOnNetworks(false);
testFactory.waitForNetworkRequests(1);
// ... and cell data to be torn down.