Merge "Controls to set expensive (metered) networks."
This commit is contained in:
@@ -35,11 +35,12 @@ import static android.net.NetworkTemplate.buildTemplateEthernet;
|
||||
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;
|
||||
@@ -83,6 +84,7 @@ import android.os.ServiceManager;
|
||||
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;
|
||||
@@ -127,6 +129,7 @@ import com.android.internal.telephony.Phone;
|
||||
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;
|
||||
@@ -144,8 +147,8 @@ import java.util.Locale;
|
||||
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";
|
||||
@@ -180,7 +183,7 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
private INetworkManagementService mNetworkService;
|
||||
private INetworkStatsService mStatsService;
|
||||
private INetworkPolicyManager mPolicyService;
|
||||
private NetworkPolicyManager mPolicyManager;
|
||||
private ConnectivityManager mConnService;
|
||||
|
||||
private static final String PREF_FILE = "data_usage";
|
||||
@@ -253,19 +256,18 @@ public class DataUsageSummary extends Fragment {
|
||||
@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);
|
||||
@@ -431,19 +433,19 @@ public class DataUsageSummary extends Fragment {
|
||||
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 {
|
||||
@@ -452,13 +454,20 @@ public class DataUsageSummary extends Fragment {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -505,6 +514,12 @@ public class DataUsageSummary extends Fragment {
|
||||
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;
|
||||
}
|
||||
@@ -572,7 +587,7 @@ public class DataUsageSummary extends Fragment {
|
||||
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)) {
|
||||
@@ -650,6 +665,9 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
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);
|
||||
@@ -671,7 +689,7 @@ public class DataUsageSummary extends Fragment {
|
||||
// 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
|
||||
@@ -755,8 +773,8 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
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));
|
||||
@@ -829,48 +847,22 @@ public class DataUsageSummary extends Fragment {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1201,23 +1193,25 @@ public class DataUsageSummary extends Fragment {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -2048,22 +2042,24 @@ public class DataUsageSummary extends Fragment {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
@@ -2071,39 +2067,35 @@ public class DataUsageSummary extends Fragment {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -2138,6 +2130,7 @@ public class DataUsageSummary extends Fragment {
|
||||
* Build string describing currently limited networks, which defines when
|
||||
* background data is restricted.
|
||||
*/
|
||||
@Deprecated
|
||||
private CharSequence buildLimitedNetworksString() {
|
||||
final List<CharSequence> limited = buildLimitedNetworksList();
|
||||
|
||||
@@ -2153,22 +2146,28 @@ public class DataUsageSummary extends Fragment {
|
||||
* 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));
|
||||
|
||||
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(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())) {
|
||||
|
133
src/com/android/settings/net/DataUsageMeteredSettings.java
Normal file
133
src/com/android/settings/net/DataUsageMeteredSettings.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
@@ -16,6 +16,7 @@
|
||||
|
||||
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;
|
||||
@@ -27,11 +28,10 @@ import static android.net.NetworkTemplate.buildTemplateMobile4g;
|
||||
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;
|
||||
@@ -43,27 +43,23 @@ import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@@ -78,12 +74,6 @@ public class NetworkPolicyEditor {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// drop any WIFI policies that were defined
|
||||
if (policy.template.getMatchRule() == MATCH_WIFI) {
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
mPolicies.add(policy);
|
||||
}
|
||||
|
||||
@@ -109,11 +99,7 @@ public class NetworkPolicyEditor {
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -142,13 +128,24 @@ public class NetworkPolicyEditor {
|
||||
@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) {
|
||||
@@ -188,6 +185,52 @@ public class NetworkPolicyEditor {
|
||||
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}.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user