From c279f1830ee6e1ca79ee86a707d5cc796a806667 Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Thu, 7 Sep 2023 15:25:52 +0800 Subject: [PATCH] [BR07.1] Expose setDataSaverEnabled from ConnectivityManager Currently, data saver switch is controlled in NPMS, which calls into NetworkManagementService and netd when switching status. In netd, BandwidthController manipulates the bw_data_saver chain to control the overall behavior. However, this code are all platform implementation, which are not updatable. In order to migrate data saver switch from iptables to bpf, this API is needed for Connectivity to change the implementation to directly write bpf in later patches. Test: atest CtsHostsideNetworkTests:com.android.cts.net.HostsideRestrictBackgroundNetworkTests Test: atest FrameworksServicesTests:NetworkManagementServiceTest Bug: 297836825 Change-Id: I71fa41ca739fef8e191fba91b02758ad5f732d5c --- common/flags.aconfig | 7 +++++ framework/api/module-lib-current.txt | 1 + .../src/android/net/ConnectivityManager.java | 31 +++++++++++++++++++ .../src/android/net/IConnectivityManager.aidl | 2 ++ .../android/server/ConnectivityService.java | 14 +++++++++ 5 files changed, 55 insertions(+) diff --git a/common/flags.aconfig b/common/flags.aconfig index 2e552a1ba9..72352028a4 100644 --- a/common/flags.aconfig +++ b/common/flags.aconfig @@ -20,3 +20,10 @@ flag { description: "Remove expired services from MdnsServiceCache" bug: "304649384" } + +flag { + name: "set_data_saver_via_cm" + namespace: "android_core_networking" + description: "Set data saver through ConnectivityManager API" + bug: "297836825" +} diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index 193bd920d2..782e20a981 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -24,6 +24,7 @@ package android.net { method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptUnvalidated(@NonNull android.net.Network, boolean, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAvoidUnvalidated(@NonNull android.net.Network); + method @FlaggedApi("com.android.net.flags.set_data_saver_via_cm") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setDataSaverEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setFirewallChainEnabled(int, boolean); method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setLegacyLockdownVpnEnabled(boolean); diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 23155210be..8963e308da 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -26,6 +26,7 @@ import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT; import static android.net.QosCallback.QosCallbackRegistrationException; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -115,6 +116,14 @@ public class ConnectivityManager { private static final String TAG = "ConnectivityManager"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + // TODO : remove this class when udc-mainline-prod is abandoned and android.net.flags.Flags is + // available here + /** @hide */ + public static class Flags { + static final String SET_DATA_SAVER_VIA_CM = + "com.android.net.flags.set_data_saver_via_cm"; + } + /** * A change in network connectivity has occurred. A default connection has either * been established or lost. The NetworkInfo for the affected network is @@ -5940,6 +5949,28 @@ public class ConnectivityManager { return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1); } + /** + * Sets data saver switch. + * + * @param enable True if enable. + * @throws IllegalStateException if failed. + * @hide + */ + @FlaggedApi(Flags.SET_DATA_SAVER_VIA_CM) + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK + }) + public void setDataSaverEnabled(final boolean enable) { + try { + mService.setDataSaverEnabled(enable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Adds the specified UID to the list of UIds that are allowed to use data on metered networks * even when background data is restricted. The deny list takes precedence over the allow list. diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl index ebe8bca77e..9f56e7efb1 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -238,6 +238,8 @@ interface IConnectivityManager void setTestAllowBadWifiUntil(long timeMs); + void setDataSaverEnabled(boolean enable); + void updateMeteredNetworkAllowList(int uid, boolean add); void updateMeteredNetworkDenyList(int uid, boolean add); diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index c19878cb91..967bcc89c1 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -12544,6 +12544,20 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + @Override + public void setDataSaverEnabled(final boolean enable) { + enforceNetworkStackOrSettingsPermission(); + try { + final boolean ret = mNetd.bandwidthEnableDataSaver(enable); + if (!ret) { + throw new IllegalStateException("Error when changing iptables: " + enable); + } + } catch (RemoteException e) { + // Lack of permission or binder errors. + throw new IllegalStateException(e); + } + } + @Override public void updateMeteredNetworkAllowList(final int uid, final boolean add) { enforceNetworkStackOrSettingsPermission();