From dc09269c81f7e761f78e23fa665c02e2138f6f10 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 12 Jul 2017 10:56:57 -0600 Subject: [PATCH] Move "metered" persistence to WifiConfiguration. For a long time we've had a nasty tangled dependency between Wi-Fi and NPMS, since they both persisted different details for configured networks. As part of preparing for new carrier data plan APIs, move the tracking of meteredness over to WifiConfiguration. We've never really supported "unmetered" mobile networks inside the framework, so remove the option to configure those flags. Replace MeteredPreference.notifyChanged() with explicit listener to avoid confusing an invalidation pass as expression of user intent to change metered values. Bug: 63391323 Test: builds, boots, Wi-Fi policy is upgraded Exempt-From-Owner-Approval: No owner was found for changed files. Change-Id: If8a6e12650d1d060a729ed1a80f07ebb65e0ffd7 --- res/values/strings.xml | 7 + .../datausage/DataUsageMeteredSettings.java | 125 ++++++------------ .../settings/datausage/DataUsageSummary.java | 29 +--- .../datausage/DataUsageSummaryTest.java | 54 -------- 4 files changed, 53 insertions(+), 162 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 998ec477fed..ad3edc1aa73 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5715,6 +5715,13 @@ To select metered networks, turn Wi\u2011Fi on. + + Automatic + + Metered + + Not metered + Carrier data accounting may differ from your device. diff --git a/src/com/android/settings/datausage/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java index c2a18e9c938..830fc960635 100644 --- a/src/com/android/settings/datausage/DataUsageMeteredSettings.java +++ b/src/com/android/settings/datausage/DataUsageMeteredSettings.java @@ -14,19 +14,21 @@ package com.android.settings.datausage; +import static android.net.wifi.WifiInfo.removeDoubleQuotes; + +import static com.android.settings.datausage.DataUsageSummary.hasWifiRadio; + import android.app.backup.BackupManager; import android.content.Context; import android.content.res.Resources; -import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; -import android.net.NetworkTemplate; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; -import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.DropDownPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceCategory; -import android.telephony.TelephonyManager; +import android.text.TextUtils; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; @@ -39,18 +41,11 @@ import com.android.settingslib.NetworkPolicyEditor; import java.util.ArrayList; import java.util.List; -import static android.net.NetworkPolicy.LIMIT_DISABLED; -import static android.net.wifi.WifiInfo.removeDoubleQuotes; -import static com.android.settings.datausage.DataUsageList.hasReadyMobileRadio; -import static com.android.settings.datausage.DataUsageSummary.hasWifiRadio; - /** - * Panel to configure {@link NetworkPolicy#metered} for networks. + * Panel to configure {@link WifiConfiguration#meteredOverride}. */ public class DataUsageMeteredSettings extends SettingsPreferenceFragment implements Indexable { - private static final boolean SHOW_MOBILE_CATEGORY = false; - private NetworkPolicyManager mPolicyManager; private WifiManager mWifiManager; @@ -85,18 +80,14 @@ public class DataUsageMeteredSettings extends SettingsPreferenceFragment impleme } private void updateNetworks(Context context) { - if (SHOW_MOBILE_CATEGORY && hasReadyMobileRadio(context)) { - mMobileCategory.removeAll(); - mMobileCategory.addPreference(buildMobilePref(context)); - } else { - getPreferenceScreen().removePreference(mMobileCategory); - } + getPreferenceScreen().removePreference(mMobileCategory); mWifiCategory.removeAll(); if (hasWifiRadio(context) && mWifiManager.isWifiEnabled()) { for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) { - if (config.SSID != null) { - mWifiCategory.addPreference(buildWifiPref(config)); + final Preference pref = new MeteredPreference(getPrefContext(), config); + if (!TextUtils.isEmpty(pref.getTitle())) { + mWifiCategory.addPreference(pref); } } } else { @@ -104,57 +95,40 @@ public class DataUsageMeteredSettings extends SettingsPreferenceFragment impleme } } - private Preference buildMobilePref(Context context) { - final TelephonyManager tele = TelephonyManager.from(context); - final NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll( - tele.getSubscriberId()); - final MeteredPreference pref = new MeteredPreference(getPrefContext(), template); - pref.setTitle(tele.getNetworkOperatorName()); - return pref; - } + private class MeteredPreference extends DropDownPreference { + private final WifiConfiguration mConfig; - private Preference buildWifiPref(WifiConfiguration config) { - final String networkId = config.isPasspoint() ? - config.providerFriendlyName : config.SSID; - final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(networkId); - final MeteredPreference pref = new MeteredPreference(getPrefContext(), template); - pref.setTitle(removeDoubleQuotes(networkId)); - return pref; - } - - private class MeteredPreference extends SwitchPreference { - private final NetworkTemplate mTemplate; - private boolean mBinding; - - public MeteredPreference(Context context, NetworkTemplate template) { + public MeteredPreference(Context context, WifiConfiguration config) { super(context); - mTemplate = template; + mConfig = config; setPersistent(false); + setEntries(new CharSequence[] { + getString(R.string.data_usage_metered_auto), + getString(R.string.data_usage_metered_yes), + getString(R.string.data_usage_metered_no), + }); + setEntryValues(new CharSequence[] { + Integer.toString(WifiConfiguration.METERED_OVERRIDE_NONE), + Integer.toString(WifiConfiguration.METERED_OVERRIDE_METERED), + Integer.toString(WifiConfiguration.METERED_OVERRIDE_NOT_METERED), + }); + setValue(Integer.toString(mConfig.meteredOverride)); + setTitle(NetworkPolicyManager.resolveNetworkId(mConfig)); + setSummary(getEntries()[mConfig.meteredOverride]); - mBinding = true; - final NetworkPolicy policy = mPolicyEditor.getPolicyMaybeUnquoted(template); - if (policy != null) { - if (policy.limitBytes != LIMIT_DISABLED) { - setChecked(true); - setEnabled(false); - } else { - setChecked(policy.metered); + setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mConfig.meteredOverride = Integer.parseInt((String) newValue); + setSummary(getEntries()[mConfig.meteredOverride]); + + mWifiManager.updateNetwork(mConfig); + // Stage the backup of the SettingsProvider package which backs this up + BackupManager.dataChanged("com.android.providers.settings"); + return true; } - } else { - setChecked(false); - } - mBinding = false; - } - - @Override - protected void notifyChanged() { - super.notifyChanged(); - if (!mBinding) { - mPolicyEditor.setPolicyMetered(mTemplate, isChecked()); - // Stage the backup of the SettingsProvider package which backs this up - BackupManager.dataChanged("com.android.providers.settings"); - } + }); } } @@ -180,21 +154,6 @@ public class DataUsageMeteredSettings extends SettingsPreferenceFragment impleme data.screenTitle = res.getString(R.string.data_usage_menu_metered); result.add(data); - if (SHOW_MOBILE_CATEGORY && hasReadyMobileRadio(context)) { - // Mobile networks category - data = new SearchIndexableRaw(context); - data.title = res.getString(R.string.data_usage_metered_mobile); - data.screenTitle = res.getString(R.string.data_usage_menu_metered); - result.add(data); - - final TelephonyManager tele = TelephonyManager.from(context); - - data = new SearchIndexableRaw(context); - data.title = tele.getNetworkOperatorName(); - data.screenTitle = res.getString(R.string.data_usage_menu_metered); - result.add(data); - } - // Wi-Fi networks category data = new SearchIndexableRaw(context); data.title = res.getString(R.string.data_usage_metered_wifi); @@ -227,12 +186,8 @@ public class DataUsageMeteredSettings extends SettingsPreferenceFragment impleme @Override public List getNonIndexableKeys(Context context) { final List result = super.getNonIndexableKeys(context); - if (!SHOW_MOBILE_CATEGORY || !hasReadyMobileRadio(context)) { - result.add("mobile"); - } - + result.add("mobile"); return result; } }; - } diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java index c5c32ba1dcc..e6fc5e7237b 100644 --- a/src/com/android/settings/datausage/DataUsageSummary.java +++ b/src/com/android/settings/datausage/DataUsageSummary.java @@ -14,13 +14,15 @@ package com.android.settings.datausage; +import static android.net.ConnectivityManager.TYPE_ETHERNET; +import static android.net.ConnectivityManager.TYPE_WIFI; + import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.INetworkStatsSession; -import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; import android.net.NetworkTemplate; import android.net.TrafficStats; @@ -46,6 +48,7 @@ import android.text.style.RelativeSizeSpan; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; + import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.SummaryPreference; @@ -55,13 +58,10 @@ import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settingslib.NetworkPolicyEditor; import com.android.settingslib.net.DataUsageController; + import java.util.ArrayList; import java.util.List; -import static android.net.ConnectivityManager.TYPE_ETHERNET; -import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.NetworkPolicy.LIMIT_DISABLED; - public class DataUsageSummary extends DataUsageBase implements Indexable, DataUsageEditController { static final boolean LOGD = false; @@ -403,7 +403,7 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs mPolicyEditor.read(); int count = 0; for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) { - if (isMetered(config)) { + if (WifiConfiguration.isMetered(config, null)) { count++; } } @@ -411,23 +411,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs R.plurals.network_restrictions_summary, count, count)); } - @VisibleForTesting - boolean isMetered(WifiConfiguration config) { - if (config.SSID == null) { - return false; - } - final String networkId = config.isPasspoint() ? config.providerFriendlyName : config.SSID; - final NetworkPolicy policy = - mPolicyEditor.getPolicyMaybeUnquoted(NetworkTemplate.buildTemplateWifi(networkId)); - if (policy == null) { - return false; - } - if (policy.limitBytes != LIMIT_DISABLED) { - return true; - } - return policy.metered; - } - private static class SummaryProvider implements SummaryLoader.SummaryProvider { diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index 77e0fe9ad9d..13e3aeea831 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -94,60 +94,6 @@ public class DataUsageSummaryTest { R.plurals.network_restrictions_summary, 0, 0)); } - @Test - public void testIsMetered_noSsid_shouldReturnFalse() { - final DataUsageSummary dataUsageSummary = new DataUsageSummary(); - final NetworkPolicyEditor policyEditor = mock(NetworkPolicyEditor.class); - ReflectionHelpers.setField(dataUsageSummary, "mPolicyEditor", policyEditor); - WifiConfiguration config = mock(WifiConfiguration.class); - - assertThat(dataUsageSummary.isMetered(config)).isFalse(); - } - - @Test - public void testIsMetered_noNetworkPolicy_shouldReturnFalse() { - final DataUsageSummary dataUsageSummary = new DataUsageSummary(); - final NetworkPolicyEditor policyEditor = mock(NetworkPolicyEditor.class); - ReflectionHelpers.setField(dataUsageSummary, "mPolicyEditor", policyEditor); - WifiConfiguration config = mock(WifiConfiguration.class); - config.SSID = "network1"; - doReturn(null).when(policyEditor).getPolicyMaybeUnquoted(any()); - - assertThat(dataUsageSummary.isMetered(config)).isFalse(); - } - - @Test - public void testIsMetered_policyHasLimit_shouldReturnTrue() { - final DataUsageSummary dataUsageSummary = new DataUsageSummary(); - final NetworkPolicyEditor policyEditor = mock(NetworkPolicyEditor.class); - ReflectionHelpers.setField(dataUsageSummary, "mPolicyEditor", policyEditor); - WifiConfiguration config = mock(WifiConfiguration.class); - config.SSID = "network1"; - NetworkPolicy policy = mock(NetworkPolicy.class); - policy.limitBytes = 100; - doReturn(policy).when(policyEditor).getPolicyMaybeUnquoted(any()); - - assertThat(dataUsageSummary.isMetered(config)).isTrue(); - } - - @Test - public void testIsMetered_noPolicyLimit_shouldReturnMeteredValue() { - final DataUsageSummary dataUsageSummary = new DataUsageSummary(); - final NetworkPolicyEditor policyEditor = mock(NetworkPolicyEditor.class); - ReflectionHelpers.setField(dataUsageSummary, "mPolicyEditor", policyEditor); - WifiConfiguration config = mock(WifiConfiguration.class); - config.SSID = "network1"; - NetworkPolicy policy = mock(NetworkPolicy.class); - policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; - doReturn(policy).when(policyEditor).getPolicyMaybeUnquoted(any()); - - policy.metered = true; - assertThat(dataUsageSummary.isMetered(config)).isTrue(); - - policy.metered = false; - assertThat(dataUsageSummary.isMetered(config)).isFalse(); - } - @Test public void testNonIndexableKeys_existInXmlLayout() { final Context context = RuntimeEnvironment.application;