Loading core/java/android/provider/Settings.java +13 −0 Original line number Diff line number Diff line Loading @@ -9252,6 +9252,19 @@ public final class Settings { */ public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on"; /** * Whether the wifi data connection should remain active even when higher * priority networks like Ethernet are active, to keep both networks. * In the case where higher priority networks are connected, wifi will be * unused unless an application explicitly requests to use it. * * See ConnectivityService for more info. * * (0 = disabled, 1 = enabled) * @hide */ public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested"; /** * Size of the event buffer for IP connectivity metrics. * @hide Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -463,6 +463,7 @@ public class SettingsBackupTest { Settings.Global.WFC_IMS_MODE, Settings.Global.WFC_IMS_ROAMING_ENABLED, Settings.Global.WFC_IMS_ROAMING_MODE, Settings.Global.WIFI_ALWAYS_REQUESTED, Settings.Global.WIFI_BADGING_THRESHOLDS, Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS, Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, Loading services/core/java/com/android/server/ConnectivityService.java +37 −14 Original line number Diff line number Diff line Loading @@ -393,9 +393,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 Loading Loading @@ -751,6 +751,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()); Loading Loading @@ -948,8 +954,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. Loading @@ -958,20 +964,28 @@ 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() { Loading @@ -983,7 +997,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() { Loading Loading @@ -1835,8 +1854,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)); Loading Loading @@ -3125,8 +3144,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. Loading Loading @@ -4554,6 +4573,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); Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +8 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2027,7 +2027,7 @@ public class ConnectivityServiceTest { @Test public void testNetworkGoesIntoBackgroundAfterLinger() { setMobileDataAlwaysOn(true); setAlwaysOnNetworks(true); NetworkRequest request = new NetworkRequest.Builder() .clearCapabilities() .build(); Loading Loading @@ -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(); } Loading @@ -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(); Loading Loading @@ -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()); Loading @@ -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. Loading Loading
core/java/android/provider/Settings.java +13 −0 Original line number Diff line number Diff line Loading @@ -9252,6 +9252,19 @@ public final class Settings { */ public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on"; /** * Whether the wifi data connection should remain active even when higher * priority networks like Ethernet are active, to keep both networks. * In the case where higher priority networks are connected, wifi will be * unused unless an application explicitly requests to use it. * * See ConnectivityService for more info. * * (0 = disabled, 1 = enabled) * @hide */ public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested"; /** * Size of the event buffer for IP connectivity metrics. * @hide Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -463,6 +463,7 @@ public class SettingsBackupTest { Settings.Global.WFC_IMS_MODE, Settings.Global.WFC_IMS_ROAMING_ENABLED, Settings.Global.WFC_IMS_ROAMING_MODE, Settings.Global.WIFI_ALWAYS_REQUESTED, Settings.Global.WIFI_BADGING_THRESHOLDS, Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS, Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, Loading
services/core/java/com/android/server/ConnectivityService.java +37 −14 Original line number Diff line number Diff line Loading @@ -393,9 +393,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 Loading Loading @@ -751,6 +751,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()); Loading Loading @@ -948,8 +954,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. Loading @@ -958,20 +964,28 @@ 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() { Loading @@ -983,7 +997,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() { Loading Loading @@ -1835,8 +1854,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)); Loading Loading @@ -3125,8 +3144,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. Loading Loading @@ -4554,6 +4573,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); Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +8 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2027,7 +2027,7 @@ public class ConnectivityServiceTest { @Test public void testNetworkGoesIntoBackgroundAfterLinger() { setMobileDataAlwaysOn(true); setAlwaysOnNetworks(true); NetworkRequest request = new NetworkRequest.Builder() .clearCapabilities() .build(); Loading Loading @@ -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(); } Loading @@ -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(); Loading Loading @@ -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()); Loading @@ -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. Loading