From 0017a2f638032a91b31474c6df9d703580dfcf4b Mon Sep 17 00:00:00 2001 From: Oliver Scott Date: Wed, 17 Nov 2021 22:29:39 -0500 Subject: [PATCH] Settings: Add support for allowing/disallowing apps on cellular, vpn and wifi networks *) Add options to disable all cellular, vpn and wifi data in app data usage settings. *) Disable the existing background data and unrestricted data usage options when all cellular data access is disabled. *) The vpn data option can be selected independently from the Wi-Fi and cellular options. *) Prevent DataSaverBackend from overwriting uid policies This is a replacement for the appops menu based cell/wifi data restriction settings in cm-13.0: Author: Danesh M Date: Mon Mar 7 15:17:59 2016 -0800 Settings : Add per app internet/data control CYAN-3976 CRACKLING-834 Change-Id: I13192df837c057b5cadde8f31532e12daaf3c1b0 Change-Id: Ic087c27a5ed0bdb84bb8f297c425c6bcbffec848 (cherry picked from commit d4a2eea698cbc4636a635d60f2a52ec1bbc36ba2) --- res/values/cm_strings.xml | 6 + res/xml/app_data_usage.xml | 15 +++ .../settings/datausage/AppDataUsage.java | 114 ++++++++++++++++-- .../settings/datausage/DataSaverBackend.java | 13 +- 4 files changed, 133 insertions(+), 15 deletions(-) diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml index 62668ef80fb..73ee27672e2 100644 --- a/res/values/cm_strings.xml +++ b/res/values/cm_strings.xml @@ -63,6 +63,12 @@ Allow network access Enable network usage + Mobile data + Enable usage of mobile data + VPN data + Enable usage of VPN data + Wi\u2011Fi data + Enable usage of Wi\u2011Fi data Scramble layout diff --git a/res/xml/app_data_usage.xml b/res/xml/app_data_usage.xml index 013088ab822..8f2874da783 100644 --- a/res/xml/app_data_usage.xml +++ b/res/xml/app_data_usage.xml @@ -47,6 +47,16 @@ android:title="@string/data_usage_app_restrict_all" android:summary="@string/data_usage_app_restrict_all_summary" /> + + + + + + mPackages = new ArraySet<>(); private RestrictedSwitchPreference mRestrictAll; private RestrictedSwitchPreference mRestrictBackground; + private RestrictedSwitchPreference mRestrictCellular; + private RestrictedSwitchPreference mRestrictVpn; + private RestrictedSwitchPreference mRestrictWifi; private Drawable mIcon; @VisibleForTesting @@ -153,6 +163,9 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC removePreference(KEY_UNRESTRICTED_DATA); removePreference(KEY_RESTRICT_ALL); removePreference(KEY_RESTRICT_BACKGROUND); + removePreference(KEY_RESTRICT_CELLULAR); + removePreference(KEY_RESTRICT_VPN); + removePreference(KEY_RESTRICT_WIFI); } else { if (mPackages.size() != 0) { int userId = UserHandle.getUserId(mAppItem.key); @@ -170,6 +183,12 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC mRestrictAll.setOnPreferenceChangeListener(this); mRestrictBackground = findPreference(KEY_RESTRICT_BACKGROUND); mRestrictBackground.setOnPreferenceChangeListener(this); + mRestrictCellular = findPreference(KEY_RESTRICT_CELLULAR); + mRestrictCellular.setOnPreferenceChangeListener(this); + mRestrictVpn = findPreference(KEY_RESTRICT_VPN); + mRestrictVpn.setOnPreferenceChangeListener(this); + mRestrictWifi = findPreference(KEY_RESTRICT_WIFI); + mRestrictWifi.setOnPreferenceChangeListener(this); mUnrestrictedData = findPreference(KEY_UNRESTRICTED_DATA); mUnrestrictedData.setOnPreferenceChangeListener(this); } @@ -186,6 +205,9 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC removePreference(KEY_UNRESTRICTED_DATA); removePreference(KEY_RESTRICT_ALL); removePreference(KEY_RESTRICT_BACKGROUND); + removePreference(KEY_RESTRICT_CELLULAR); + removePreference(KEY_RESTRICT_VPN); + removePreference(KEY_RESTRICT_WIFI); } setupIntroPreference(); @@ -238,6 +260,18 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, uids); updatePrefs(); return true; + } else if (preference == mRestrictCellular) { + setAppRestrictCellular(!(Boolean) newValue); + updatePrefs(); + return true; + } else if (preference == mRestrictVpn) { + setAppRestrictVpn(!(Boolean) newValue); + updatePrefs(); + return true; + } else if (preference == mRestrictWifi) { + setAppRestrictWifi(!(Boolean) newValue); + updatePrefs(); + return true; } else if (preference == mUnrestrictedData) { mDataSaverBackend.setIsAllowlisted(mAppItem.key, mPackageName, (Boolean) newValue); return true; @@ -257,7 +291,8 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC @VisibleForTesting void updatePrefs() { - updatePrefs(getAppRestrictBackground(), getUnrestrictData(), getAppRestrictAll()); + updatePrefs(getAppRestrictBackground(), getUnrestrictData(), getAppRestrictAll(), + getAppRestrictCellular(), getAppRestrictVpn(), getAppRestrictWifi()); } @VisibleForTesting @@ -299,7 +334,8 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC } private void updatePrefs(boolean restrictBackground, boolean unrestrictData, - boolean restrictAll) { + boolean restrictAll, boolean restrictCellular, boolean restrictVpn, + boolean restrictWifi) { if (!isSimHardwareVisible(mContext)) { return; } @@ -312,15 +348,29 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC } if (mRestrictBackground != null) { mRestrictBackground.setDisabledByAdmin(admin); - mRestrictBackground.setEnabled(!mRestrictBackground.isDisabledByAdmin() && - !restrictAll); - mRestrictBackground.setChecked(!restrictBackground && !restrictAll); + mRestrictBackground.setEnabled(!mRestrictBackground.isDisabledByAdmin() && !restrictAll + && !restrictCellular); + mRestrictBackground.setChecked(!restrictBackground && !restrictAll && + !restrictCellular); + } + if (mRestrictCellular != null) { + mRestrictCellular.setEnabled(!restrictAll); + mRestrictCellular.setChecked(!restrictAll && !restrictCellular); + } + if (mRestrictVpn != null) { + mRestrictVpn.setEnabled(!restrictAll); + mRestrictVpn.setChecked(!restrictAll && !restrictVpn); + } + if (mRestrictWifi != null) { + mRestrictWifi.setEnabled(!restrictAll); + mRestrictWifi.setChecked(!restrictAll && !restrictWifi); } if (mUnrestrictedData != null) { mUnrestrictedData.setDisabledByAdmin(admin); mUnrestrictedData.setEnabled(!mUnrestrictedData.isDisabledByAdmin() && - !restrictBackground && !restrictAll); - mUnrestrictedData.setChecked(unrestrictData && !restrictBackground && !restrictAll); + !restrictBackground && !restrictAll && !restrictCellular); + mUnrestrictedData.setChecked(unrestrictData && !restrictBackground && !restrictAll + && !restrictCellular); } } @@ -332,10 +382,19 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC } private boolean getAppRestrictBackground() { - final int uid = mAppItem.key; - final int uidPolicy = services.mPolicyManager.getUidPolicy(uid); - return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0 - && DynamicDenylistManager.getInstance(mContext).isInManualDenylist(uid); + return getAppRestriction(POLICY_REJECT_METERED_BACKGROUND); + } + + private boolean getAppRestrictCellular() { + return getAppRestriction(POLICY_REJECT_CELLULAR); + } + + private boolean getAppRestrictVpn() { + return getAppRestriction(POLICY_REJECT_VPN); + } + + private boolean getAppRestrictWifi() { + return getAppRestriction(POLICY_REJECT_WIFI); } private boolean getAppRestrictAll() { @@ -350,6 +409,33 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC return false; } + private boolean getAppRestriction(int policy) { + final int uid = mAppItem.key; + final int uidPolicy = services.mPolicyManager.getUidPolicy(uid); + return (uidPolicy & policy) != 0; + } + + private void setAppRestrictCellular(boolean restrict) { + setAppRestriction(POLICY_REJECT_CELLULAR, restrict); + } + + private void setAppRestrictVpn(boolean restrict) { + setAppRestriction(POLICY_REJECT_VPN, restrict); + } + + private void setAppRestrictWifi(boolean restrict) { + setAppRestriction(POLICY_REJECT_WIFI, restrict); + } + + private void setAppRestriction(int policy, boolean restrict) { + final int uid = mAppItem.key; + if (restrict) { + services.mPolicyManager.addUidPolicy(uid, policy); + } else { + services.mPolicyManager.removeUidPolicy(uid, policy); + } + } + @VisibleForTesting void setupIntroPreference() { final Preference pref = getPreferenceScreen().findPreference(ARG_APP_HEADER); @@ -392,14 +478,16 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC @Override public void onAllowlistStatusChanged(int uid, boolean isAllowlisted) { if (mAppItem.uids.get(uid, false)) { - updatePrefs(getAppRestrictBackground(), isAllowlisted, getAppRestrictAll()); + updatePrefs(getAppRestrictBackground(), isAllowlisted, getAppRestrictAll(), + getAppRestrictCellular(), getAppRestrictVpn(), getAppRestrictWifi()); } } @Override public void onDenylistStatusChanged(int uid, boolean isDenylisted) { if (mAppItem.uids.get(uid, false)) { - updatePrefs(isDenylisted, getUnrestrictData(), getAppRestrictAll()); + updatePrefs(isDenylisted, getUnrestrictData(), getAppRestrictAll(), + getAppRestrictCellular(), getAppRestrictVpn(), getAppRestrictWifi()); } } } diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java index 6e994537aa8..8fc7e3aa5f5 100644 --- a/src/com/android/settings/datausage/DataSaverBackend.java +++ b/src/com/android/settings/datausage/DataSaverBackend.java @@ -86,12 +86,15 @@ public class DataSaverBackend { public void setIsAllowlisted(int uid, String packageName, boolean allowlisted) { final int policy = allowlisted ? POLICY_ALLOW_METERED_BACKGROUND : POLICY_NONE; - mDynamicDenylistManager.setUidPolicyLocked(uid, policy); mUidPolicies.put(uid, policy); if (allowlisted) { + mPolicyManager.addUidPolicy(uid, POLICY_ALLOW_METERED_BACKGROUND); mMetricsFeatureProvider.action( mContext, SettingsEnums.ACTION_DATA_SAVER_WHITELIST, packageName); + } else { + mPolicyManager.removeUidPolicy(uid, POLICY_ALLOW_METERED_BACKGROUND); } + mPolicyManager.removeUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND); } public boolean isAllowlisted(int uid) { @@ -116,12 +119,15 @@ public class DataSaverBackend { public void setIsDenylisted(int uid, String packageName, boolean denylisted) { final int policy = denylisted ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE; - mDynamicDenylistManager.setUidPolicyLocked(uid, policy); mUidPolicies.put(uid, policy); if (denylisted) { + mPolicyManager.addUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND); mMetricsFeatureProvider.action( mContext, SettingsEnums.ACTION_DATA_SAVER_BLACKLIST, packageName); + } else { + mPolicyManager.removeUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND); } + mPolicyManager.removeUidPolicy(uid, POLICY_ALLOW_METERED_BACKGROUND); } public boolean isDenylisted(int uid) { @@ -162,6 +168,9 @@ public class DataSaverBackend { loadAllowlist(); loadDenylist(); + // We only care about allow/reject metered background policy here. + newPolicy &= POLICY_ALLOW_METERED_BACKGROUND | POLICY_REJECT_METERED_BACKGROUND; + final int oldPolicy = mUidPolicies.get(uid, POLICY_NONE); if (newPolicy == POLICY_NONE) { mUidPolicies.delete(uid);