import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
import static android.net.NetworkTemplate.buildTemplateMobile4g;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateWifi;
+import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.GB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UID_REMOVED;
import static android.net.TrafficStats.UID_TETHERING;
+import static android.telephony.TelephonyManager.SIM_STATE_READY;
import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import android.os.SystemProperties;
import android.os.UserId;
import android.preference.Preference;
+import android.preference.PreferenceActivity;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.settings.drawable.InsetBoundsDrawable;
import com.android.settings.net.ChartData;
import com.android.settings.net.ChartDataLoader;
+import com.android.settings.net.DataUsageMeteredSettings;
import com.android.settings.net.NetworkPolicyEditor;
import com.android.settings.net.SummaryForAllUidLoader;
import com.android.settings.net.UidDetail;
import libcore.util.Objects;
/**
- * Panel show data usage history across various networks, including options to
- * inspect based on usage cycle and control through {@link NetworkPolicy}.
+ * Panel showing data usage history across various networks, including options
+ * to inspect based on usage cycle and control through {@link NetworkPolicy}.
*/
public class DataUsageSummary extends Fragment {
private static final String TAG = "DataUsage";
private INetworkManagementService mNetworkService;
private INetworkStatsService mStatsService;
- private INetworkPolicyManager mPolicyService;
+ private NetworkPolicyManager mPolicyManager;
private ConnectivityManager mConnService;
private static final String PREF_FILE = "data_usage";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ final Context context = getActivity();
mNetworkService = INetworkManagementService.Stub.asInterface(
ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
mStatsService = INetworkStatsService.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
- mPolicyService = INetworkPolicyManager.Stub.asInterface(
- ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
- mConnService = (ConnectivityManager) getActivity().getSystemService(
- Context.CONNECTIVITY_SERVICE);
+ mPolicyManager = NetworkPolicyManager.from(context);
+ mConnService = ConnectivityManager.from(context);
mPrefs = getActivity().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
- mPolicyEditor = new NetworkPolicyEditor(mPolicyService);
+ mPolicyEditor = new NetworkPolicyEditor(mPolicyManager);
mPolicyEditor.read();
mShowWifi = mPrefs.getBoolean(PREF_SHOW_WIFI, false);
final boolean appDetailMode = isAppDetailMode();
mMenuDataRoaming = menu.findItem(R.id.data_usage_menu_roaming);
- mMenuDataRoaming.setVisible(hasMobileRadio(context) && !appDetailMode);
+ mMenuDataRoaming.setVisible(hasReadyMobileRadio(context) && !appDetailMode);
mMenuDataRoaming.setChecked(getDataRoaming());
mMenuRestrictBackground = menu.findItem(R.id.data_usage_menu_restrict_background);
- mMenuRestrictBackground.setVisible(hasMobileRadio(context) && !appDetailMode);
- mMenuRestrictBackground.setChecked(getRestrictBackground());
+ mMenuRestrictBackground.setVisible(hasReadyMobileRadio(context) && !appDetailMode);
+ mMenuRestrictBackground.setChecked(mPolicyManager.getRestrictBackground());
final MenuItem split4g = menu.findItem(R.id.data_usage_menu_split_4g);
split4g.setVisible(hasMobile4gRadio(context) && !appDetailMode);
split4g.setChecked(isMobilePolicySplit());
final MenuItem showWifi = menu.findItem(R.id.data_usage_menu_show_wifi);
- if (hasWifiRadio(context) && hasMobileRadio(context)) {
+ if (hasWifiRadio(context) && hasReadyMobileRadio(context)) {
showWifi.setVisible(!appDetailMode);
showWifi.setChecked(mShowWifi);
} else {
}
final MenuItem showEthernet = menu.findItem(R.id.data_usage_menu_show_ethernet);
- if (hasEthernet(context) && hasMobileRadio(context)) {
+ if (hasEthernet(context) && hasReadyMobileRadio(context)) {
showEthernet.setVisible(!appDetailMode);
showEthernet.setChecked(mShowEthernet);
} else {
showEthernet.setVisible(false);
mShowEthernet = true;
}
+
+ final MenuItem metered = menu.findItem(R.id.data_usage_menu_metered);
+ if (hasReadyMobileRadio(context) || hasWifiRadio(context)) {
+ metered.setVisible(!appDetailMode);
+ } else {
+ metered.setVisible(false);
+ }
}
@Override
updateTabs();
return true;
}
+ case R.id.data_usage_menu_metered: {
+ final PreferenceActivity activity = (PreferenceActivity) getActivity();
+ activity.startPreferencePanel(DataUsageMeteredSettings.class.getCanonicalName(), null,
+ R.string.data_usage_metered_title, null, this, 0);
+ return true;
+ }
}
return false;
}
if (mobileSplit && hasMobile4gRadio(context)) {
mTabHost.addTab(buildTabSpec(TAB_3G, R.string.data_usage_tab_3g));
mTabHost.addTab(buildTabSpec(TAB_4G, R.string.data_usage_tab_4g));
- } else if (hasMobileRadio(context)) {
+ } else if (hasReadyMobileRadio(context)) {
mTabHost.addTab(buildTabSpec(TAB_MOBILE, R.string.data_usage_tab_mobile));
}
if (mShowWifi && hasWifiRadio(context)) {
mDataEnabledView.setVisibility(View.VISIBLE);
+ // TODO: remove mobile tabs when SIM isn't ready
+ final TelephonyManager tele = TelephonyManager.from(context);
+
if (TAB_MOBILE.equals(currentTab)) {
setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_mobile);
setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_mobile_limit);
// wifi doesn't have any controls
mDataEnabledView.setVisibility(View.GONE);
mDisableAtLimitView.setVisibility(View.GONE);
- mTemplate = buildTemplateWifi();
+ mTemplate = buildTemplateWifiWildcard();
} else if (TAB_ETHERNET.equals(currentTab)) {
// ethernet doesn't have any controls
updateDetailData();
- if (UserId.isApp(appId) && !getRestrictBackground() && isBandwidthControlEnabled()
- && hasMobileRadio(context)) {
+ if (UserId.isApp(appId) && !mPolicyManager.getRestrictBackground()
+ && isBandwidthControlEnabled() && hasReadyMobileRadio(context)) {
setPreferenceTitle(mAppRestrictView, R.string.data_usage_app_restrict_background);
setPreferenceSummary(mAppRestrictView,
getString(R.string.data_usage_app_restrict_background_summary));
mMenuDataRoaming.setChecked(enabled);
}
- private boolean getRestrictBackground() {
- try {
- return mPolicyService.getRestrictBackground();
- } catch (RemoteException e) {
- Log.w(TAG, "problem talking with policy service: " + e);
- return false;
- }
- }
-
- private void setRestrictBackground(boolean restrictBackground) {
- if (LOGD) Log.d(TAG, "setRestrictBackground()");
- try {
- mPolicyService.setRestrictBackground(restrictBackground);
- mMenuRestrictBackground.setChecked(restrictBackground);
- } catch (RemoteException e) {
- Log.w(TAG, "problem talking with policy service: " + e);
- }
+ public void setRestrictBackground(boolean restrictBackground) {
+ mPolicyManager.setRestrictBackground(restrictBackground);
+ mMenuRestrictBackground.setChecked(restrictBackground);
}
private boolean getAppRestrictBackground() {
final int appId = mCurrentApp.appId;
- final int uidPolicy;
- try {
- uidPolicy = mPolicyService.getAppPolicy(appId);
- } catch (RemoteException e) {
- // since we can't do much without policy, we bail hard.
- throw new RuntimeException("problem reading network policy", e);
- }
-
+ final int uidPolicy = mPolicyManager.getAppPolicy(appId);
return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
}
private void setAppRestrictBackground(boolean restrictBackground) {
if (LOGD) Log.d(TAG, "setAppRestrictBackground()");
final int appId = mCurrentApp.appId;
- try {
- mPolicyService.setAppPolicy(appId,
- restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
- } catch (RemoteException e) {
- throw new RuntimeException("unable to save policy", e);
- }
-
+ mPolicyManager.setAppPolicy(appId,
+ restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
mAppRestrict.setChecked(restrictBackground);
}
private boolean isMobilePolicySplit() {
final Context context = getActivity();
- if (hasMobileRadio(context)) {
- final String subscriberId = getActiveSubscriberId(context);
- return mPolicyEditor.isMobilePolicySplit(subscriberId);
+ if (hasReadyMobileRadio(context)) {
+ final TelephonyManager tele = TelephonyManager.from(context);
+ return mPolicyEditor.isMobilePolicySplit(getActiveSubscriberId(context));
} else {
return false;
}
}
private void setMobilePolicySplit(boolean split) {
- final String subscriberId = getActiveSubscriberId(getActivity());
- mPolicyEditor.setMobilePolicySplit(subscriberId, split);
+ final Context context = getActivity();
+ if (hasReadyMobileRadio(context)) {
+ final TelephonyManager tele = TelephonyManager.from(context);
+ mPolicyEditor.setMobilePolicySplit(getActiveSubscriberId(context), split);
+ }
}
private static String getActiveSubscriberId(Context context) {
- final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- final String actualSubscriberId = telephony.getSubscriberId();
+ final TelephonyManager tele = TelephonyManager.from(context);
+ final String actualSubscriberId = tele.getSubscriberId();
return SystemProperties.get(TEST_SUBSCRIBER_PROP, actualSubscriberId);
}
}
/**
- * Test if device has a mobile data radio.
+ * Test if device has a mobile data radio with SIM in ready state.
*/
- private static boolean hasMobileRadio(Context context) {
+ public static boolean hasReadyMobileRadio(Context context) {
if (TEST_RADIOS) {
return SystemProperties.get(TEST_RADIOS_PROP).contains("mobile");
}
- final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- return conn.isNetworkSupported(TYPE_MOBILE);
+ final ConnectivityManager conn = ConnectivityManager.from(context);
+ final TelephonyManager tele = TelephonyManager.from(context);
+
+ // require both supported network and ready SIM
+ return conn.isNetworkSupported(TYPE_MOBILE) && tele.getSimState() == SIM_STATE_READY;
}
/**
* Test if device has a mobile 4G data radio.
*/
- private static boolean hasMobile4gRadio(Context context) {
+ public static boolean hasMobile4gRadio(Context context) {
if (!NetworkPolicyEditor.ENABLE_SPLIT_POLICIES) {
return false;
}
return SystemProperties.get(TEST_RADIOS_PROP).contains("4g");
}
- final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
+ final ConnectivityManager conn = ConnectivityManager.from(context);
+ final TelephonyManager tele = TelephonyManager.from(context);
final boolean hasWimax = conn.isNetworkSupported(TYPE_WIMAX);
- final boolean hasLte = telephony.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE;
+ final boolean hasLte = tele.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE;
return hasWimax || hasLte;
}
/**
* Test if device has a Wi-Fi data radio.
*/
- private static boolean hasWifiRadio(Context context) {
+ public static boolean hasWifiRadio(Context context) {
if (TEST_RADIOS) {
return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi");
}
- final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
+ final ConnectivityManager conn = ConnectivityManager.from(context);
return conn.isNetworkSupported(TYPE_WIFI);
}
/**
* Test if device has an ethernet network connection.
*/
- private static boolean hasEthernet(Context context) {
+ public static boolean hasEthernet(Context context) {
if (TEST_RADIOS) {
return SystemProperties.get(TEST_RADIOS_PROP).contains("ethernet");
}
- final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
+ final ConnectivityManager conn = ConnectivityManager.from(context);
return conn.isNetworkSupported(TYPE_ETHERNET);
}
* Build string describing currently limited networks, which defines when
* background data is restricted.
*/
+ @Deprecated
private CharSequence buildLimitedNetworksString() {
final List<CharSequence> limited = buildLimitedNetworksList();
* Build list of currently limited networks, which defines when background
* data is restricted.
*/
+ @Deprecated
private List<CharSequence> buildLimitedNetworksList() {
final Context context = getActivity();
- final String subscriberId = getActiveSubscriberId(context);
// build combined list of all limited networks
final ArrayList<CharSequence> limited = Lists.newArrayList();
- if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobileAll(subscriberId))) {
- limited.add(getText(R.string.data_usage_list_mobile));
- }
- if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile3gLower(subscriberId))) {
- limited.add(getText(R.string.data_usage_tab_3g));
- }
- if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile4g(subscriberId))) {
- limited.add(getText(R.string.data_usage_tab_4g));
+
+ final TelephonyManager tele = TelephonyManager.from(context);
+ if (tele.getSimState() == SIM_STATE_READY) {
+ final String subscriberId = getActiveSubscriberId(context);
+ if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobileAll(subscriberId))) {
+ limited.add(getText(R.string.data_usage_list_mobile));
+ }
+ if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile3gLower(subscriberId))) {
+ limited.add(getText(R.string.data_usage_tab_3g));
+ }
+ if (mPolicyEditor.hasLimitedPolicy(buildTemplateMobile4g(subscriberId))) {
+ limited.add(getText(R.string.data_usage_tab_4g));
+ }
}
- if (mPolicyEditor.hasLimitedPolicy(buildTemplateWifi())) {
+
+ if (mPolicyEditor.hasLimitedPolicy(buildTemplateWifiWildcard())) {
limited.add(getText(R.string.data_usage_tab_wifi));
}
if (mPolicyEditor.hasLimitedPolicy(buildTemplateEthernet())) {
--- /dev/null
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.net;
+
+import static com.android.settings.DataUsageSummary.hasReadyMobileRadio;
+import static com.android.settings.DataUsageSummary.hasWifiRadio;
+
+import android.content.Context;
+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.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.telephony.TelephonyManager;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+/**
+ * Panel to configure {@link NetworkPolicy#metered} for networks.
+ */
+public class DataUsageMeteredSettings extends SettingsPreferenceFragment {
+
+ private NetworkPolicyManager mPolicyManager;
+ private WifiManager mWifiManager;
+
+ private NetworkPolicyEditor mPolicyEditor;
+
+ private PreferenceCategory mMobileCategory;
+ private PreferenceCategory mWifiCategory;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ final Context context = getActivity();
+
+ mPolicyManager = NetworkPolicyManager.from(context);
+ mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+
+ mPolicyEditor = new NetworkPolicyEditor(mPolicyManager);
+ mPolicyEditor.read();
+
+ addPreferencesFromResource(R.xml.data_usage_metered_prefs);
+ mMobileCategory = (PreferenceCategory) findPreference("mobile");
+ mWifiCategory = (PreferenceCategory) findPreference("wifi");
+
+ updateNetworks(context);
+
+ }
+
+ private void updateNetworks(Context context) {
+ if (hasReadyMobileRadio(context)) {
+ mMobileCategory.removeAll();
+ mMobileCategory.addPreference(buildMobilePref(context));
+ } else {
+ getPreferenceScreen().removePreference(mMobileCategory);
+ }
+
+ if (hasWifiRadio(context)) {
+ mWifiCategory.removeAll();
+ for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) {
+ if (config.SSID != null) {
+ mWifiCategory.addPreference(buildWifiPref(context, config));
+ }
+ }
+ } else {
+ getPreferenceScreen().removePreference(mWifiCategory);
+ }
+ }
+
+ private Preference buildMobilePref(Context context) {
+ final TelephonyManager tele = TelephonyManager.from(context);
+ final NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(
+ tele.getSubscriberId());
+ final MeteredPreference pref = new MeteredPreference(context, template);
+ pref.setTitle(tele.getNetworkOperatorName());
+ return pref;
+ }
+
+ private Preference buildWifiPref(Context context, WifiConfiguration config) {
+ final String networkId = removeDoubleQuotes(config.SSID);
+ final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(networkId);
+ final MeteredPreference pref = new MeteredPreference(context, template);
+ pref.setTitle(networkId);
+ return pref;
+ }
+
+ private class MeteredPreference extends CheckBoxPreference {
+ private final NetworkTemplate mTemplate;
+
+ public MeteredPreference(Context context, NetworkTemplate template) {
+ super(context);
+ mTemplate = template;
+
+ setPersistent(false);
+ setChecked(mPolicyEditor.getPolicyMetered(mTemplate));
+ }
+
+ @Override
+ protected void notifyChanged() {
+ super.notifyChanged();
+ mPolicyEditor.setPolicyMetered(mTemplate, isChecked());
+ }
+ }
+
+
+ private static String removeDoubleQuotes(String string) {
+ final int length = string.length();
+ if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
+ return string.substring(1, length - 1);
+ }
+ return string;
+ }
+
+}
package com.android.settings.net;
+import static android.net.NetworkPolicy.CYCLE_NONE;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.SNOOZE_NEVER;
import static android.net.NetworkPolicy.WARNING_DISABLED;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static com.android.internal.util.Preconditions.checkNotNull;
-import android.net.INetworkPolicyManager;
import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
import android.net.NetworkTemplate;
import android.os.AsyncTask;
-import android.os.RemoteException;
import android.text.format.Time;
import com.android.internal.util.Objects;
/**
* Utility class to modify list of {@link NetworkPolicy}. Specifically knows
- * about which policies can coexist. Not thread safe.
+ * about which policies can coexist. This editor offers thread safety when
+ * talking with {@link NetworkPolicyManager}.
*/
public class NetworkPolicyEditor {
// TODO: be more robust when missing policies from service
public static final boolean ENABLE_SPLIT_POLICIES = false;
- private INetworkPolicyManager mPolicyService;
+ private NetworkPolicyManager mPolicyManager;
private ArrayList<NetworkPolicy> mPolicies = Lists.newArrayList();
- public NetworkPolicyEditor(INetworkPolicyManager policyService) {
- mPolicyService = checkNotNull(policyService);
+ public NetworkPolicyEditor(NetworkPolicyManager policyManager) {
+ mPolicyManager = checkNotNull(policyManager);
}
public void read() {
- final NetworkPolicy[] policies;
- try {
- policies = mPolicyService.getNetworkPolicies();
- } catch (RemoteException e) {
- throw new RuntimeException("problem reading policies", e);
- }
+ final NetworkPolicy[] policies = mPolicyManager.getNetworkPolicies();
boolean modified = false;
mPolicies.clear();
modified = true;
}
- // drop any WIFI policies that were defined
- if (policy.template.getMatchRule() == MATCH_WIFI) {
- modified = true;
- continue;
- }
-
mPolicies.add(policy);
}
}
public void write(NetworkPolicy[] policies) {
- try {
- mPolicyService.setNetworkPolicies(policies);
- } catch (RemoteException e) {
- throw new RuntimeException("problem writing policies", e);
- }
+ mPolicyManager.setNetworkPolicies(policies);
}
public boolean hasLimitedPolicy(NetworkTemplate template) {
@Deprecated
private static NetworkPolicy buildDefaultPolicy(NetworkTemplate template) {
// TODO: move this into framework to share with NetworkPolicyManagerService
- final Time time = new Time();
- time.setToNow();
- final int cycleDay = time.monthDay;
- final String cycleTimezone = time.timezone;
+ final int cycleDay;
+ final String cycleTimezone;
+ final boolean metered;
+
+ if (template.getMatchRule() == MATCH_WIFI) {
+ cycleDay = CYCLE_NONE;
+ cycleTimezone = Time.TIMEZONE_UTC;
+ metered = false;
+ } else {
+ final Time time = new Time();
+ time.setToNow();
+ cycleDay = time.monthDay;
+ cycleTimezone = time.timezone;
+ metered = true;
+ }
return new NetworkPolicy(template, cycleDay, cycleTimezone, WARNING_DISABLED,
- LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, false);
+ LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, metered, true);
}
public int getPolicyCycleDay(NetworkTemplate template) {
writeAsync();
}
+ public boolean getPolicyMetered(NetworkTemplate template) {
+ final NetworkPolicy policy = getPolicy(template);
+ if (policy != null) {
+ return policy.metered;
+ } else {
+ return false;
+ }
+ }
+
+ public void setPolicyMetered(NetworkTemplate template, boolean metered) {
+ boolean modified = false;
+
+ NetworkPolicy policy = getPolicy(template);
+ if (metered) {
+ if (policy == null) {
+ policy = buildDefaultPolicy(template);
+ policy.metered = true;
+ policy.inferred = false;
+ mPolicies.add(policy);
+ modified = true;
+ } else if (!policy.metered) {
+ policy.metered = true;
+ policy.inferred = false;
+ modified = true;
+ }
+
+ } else {
+ if (policy == null) {
+ // ignore when policy doesn't exist
+ } else if (policy.template.getMatchRule() == MATCH_WIFI
+ && policy.warningBytes == WARNING_DISABLED
+ && policy.limitBytes == LIMIT_DISABLED) {
+ // when WIFI goes unmetered, and no other warning/limit for
+ // policy, clean it up.
+ mPolicies.remove(policy);
+ modified = true;
+ } else if (policy.metered) {
+ policy.metered = false;
+ policy.inferred = false;
+ modified = true;
+ }
+ }
+
+ if (modified) writeAsync();
+ }
+
/**
* Remove any split {@link NetworkPolicy}.
*/