diff --git a/res/drawable/ic_attach_money_black_24dp.xml b/res/drawable/ic_attach_money_black_24dp.xml new file mode 100644 index 00000000000..12605fd9c66 --- /dev/null +++ b/res/drawable/ic_attach_money_black_24dp.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml index cfb6d9a6a5b..2c4a1edfdff 100644 --- a/res/layout/wifi_dialog.xml +++ b/res/layout/wifi_dialog.xml @@ -316,6 +316,26 @@ android:orientation="vertical" android:visibility="gone"> + + + + + + + + zen_mode_from_none + + Use network preference + Treat as metered + Treat as unmetered + + + + 0 + 1 + 2 + + diff --git a/res/xml/data_usage_wifi.xml b/res/xml/data_usage_wifi.xml index 607cee1851b..905b15a04f4 100644 --- a/res/xml/data_usage_wifi.xml +++ b/res/xml/data_usage_wifi.xml @@ -27,11 +27,6 @@ android:key="wifi_data_usage" android:title="@string/wifi_data_usage" /> - - diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml index 8203bece42a..5e2745a6e51 100644 --- a/res/xml/wifi_network_details_fragment.xml +++ b/res/xml/wifi_network_details_fragment.xml @@ -49,6 +49,13 @@ android:icon="@drawable/ic_security_lock_24dp" android:title="@string/wifi_security" android:selectable="false"/> + + diff --git a/src/com/android/settings/datausage/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java deleted file mode 100644 index 8bc7e04c3db..00000000000 --- a/src/com/android/settings/datausage/DataUsageMeteredSettings.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2016 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.datausage; - -import android.app.backup.BackupManager; -import android.content.Context; -import android.net.NetworkPolicyManager; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.os.Bundle; -import android.provider.SearchIndexableResource; -import android.support.v7.preference.DropDownPreference; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceCategory; -import android.text.TextUtils; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; -import com.android.settingslib.NetworkPolicyEditor; - -import java.util.Arrays; -import java.util.List; - -/** - * Panel to configure {@link WifiConfiguration#meteredOverride}. - */ -public class DataUsageMeteredSettings extends SettingsPreferenceFragment implements Indexable { - - private NetworkPolicyManager mPolicyManager; - private WifiManager mWifiManager; - - private NetworkPolicyEditor mPolicyEditor; - - private PreferenceCategory mMobileCategory; - private PreferenceCategory mWifiCategory; - private Preference mWifiDisabled; - - @Override - public int getMetricsCategory() { - return MetricsEvent.NET_DATA_USAGE_METERED; - } - - @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"); - mWifiDisabled = findPreference("wifi_disabled"); - - updateNetworks(context); - } - - private void updateNetworks(Context context) { - getPreferenceScreen().removePreference(mMobileCategory); - - mWifiCategory.removeAll(); - if (DataUsageUtils.hasWifiRadio(context) && mWifiManager.isWifiEnabled()) { - for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) { - final Preference pref = new MeteredPreference(getPrefContext(), config); - if (!TextUtils.isEmpty(pref.getTitle())) { - mWifiCategory.addPreference(pref); - } - } - } else { - mWifiCategory.addPreference(mWifiDisabled); - } - } - - private class MeteredPreference extends DropDownPreference { - private final WifiConfiguration mConfig; - - public MeteredPreference(Context context, WifiConfiguration config) { - super(context); - 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]); - - 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; - } - }); - } - } - - /** - * For search - */ - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - @Override - public List getXmlResourcesToIndex(Context context, - boolean enabled) { - final SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = R.xml.data_usage_metered_prefs; - return Arrays.asList(sir); - } - - @Override - public List getNonIndexableKeys(Context context) { - final List result = super.getNonIndexableKeys(context); - result.add("mobile"); - return result; - } - }; -} diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java index fe220221db5..b4d5f50ee04 100644 --- a/src/com/android/settings/datausage/DataUsageSummary.java +++ b/src/com/android/settings/datausage/DataUsageSummary.java @@ -77,8 +77,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs // Wifi keys public static final String KEY_WIFI_USAGE_TITLE = "wifi_category"; public static final String KEY_WIFI_DATA_USAGE = "wifi_data_usage"; - public static final String KEY_NETWORK_RESTRICTIONS = "network_restrictions"; - private DataUsageController mDataUsageController; private DataUsageInfoController mDataInfoController; @@ -86,8 +84,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs private Preference mLimitPreference; private NetworkTemplate mDefaultTemplate; private int mDataUsageTemplate; - private NetworkRestrictionsPreference mNetworkRestrictionPreference; - private WifiManager mWifiManager; private NetworkPolicyEditor mPolicyEditor; @Override @@ -101,7 +97,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs final Context context = getContext(); NetworkPolicyManager policyManager = NetworkPolicyManager.from(context); - mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mPolicyEditor = new NetworkPolicyEditor(policyManager); boolean hasMobileData = DataUsageUtils.hasMobileData(context); @@ -203,8 +198,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs TemplatePreferenceCategory category = (TemplatePreferenceCategory) inflatePreferences(R.xml.data_usage_wifi); category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0, services); - mNetworkRestrictionPreference = - (NetworkRestrictionsPreference) category.findPreference(KEY_NETWORK_RESTRICTIONS); } private void addEthernetSection() { @@ -293,8 +286,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs mLimitPreference.setSummary(null); } - updateNetworkRestrictionSummary(mNetworkRestrictionPreference); - PreferenceScreen screen = getPreferenceScreen(); for (int i = 1; i < screen.getPreferenceCount(); i++) { ((TemplatePreferenceCategory) screen.getPreference(i)).pushTemplates(services); @@ -321,22 +312,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs updateState(); } - @VisibleForTesting - void updateNetworkRestrictionSummary(NetworkRestrictionsPreference preference) { - if (preference == null) { - return; - } - mPolicyEditor.read(); - int count = 0; - for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) { - if (WifiConfiguration.isMetered(config, null)) { - count++; - } - } - preference.setSummary(getResources().getQuantityString( - R.plurals.network_restrictions_summary, count, count)); - } - private static class SummaryProvider implements SummaryLoader.SummaryProvider { @@ -409,7 +384,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs if (!DataUsageUtils.hasWifiRadio(context)) { keys.add(KEY_WIFI_DATA_USAGE); - keys.add(KEY_NETWORK_RESTRICTIONS); } // This title is named Wifi, and will confuse users. diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 0207c94ad95..03763672454 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -36,7 +36,6 @@ import com.android.settings.bluetooth.BluetoothSettings; import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld; -import com.android.settings.datausage.DataUsageMeteredSettings; import com.android.settings.datausage.DataUsageSummary; import com.android.settings.deletionhelper.AutomaticStorageManagerSettings; import com.android.settings.development.DevelopmentSettingsDashboardFragment; @@ -110,7 +109,6 @@ public final class SearchIndexableResources { addIndex(BluetoothSettings.class); addIndex(SimSettings.class); addIndex(DataUsageSummary.class); - addIndex(DataUsageMeteredSettings.class); addIndex(ScreenZoomSettings.class); addIndex(DisplaySettings.class); addIndex(AmbientDisplaySettings.class); diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 4da7366696a..5e5d5ffaa00 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -146,11 +146,11 @@ public class WifiConfigController implements TextWatcher, private TextView mDns2View; private Spinner mProxySettingsSpinner; + private Spinner mMeteredSettingsSpinner; private TextView mProxyHostView; private TextView mProxyPortView; private TextView mProxyExclusionListView; private TextView mProxyPacView; - private CheckBox mSharedCheckBox; private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED; @@ -208,6 +208,7 @@ public class WifiConfigController implements TextWatcher, mProxySettingsSpinner = (Spinner) mView.findViewById(R.id.proxy_settings); mProxySettingsSpinner.setOnItemSelectedListener(this); mSharedCheckBox = (CheckBox) mView.findViewById(R.id.shared); + mMeteredSettingsSpinner = mView.findViewById(R.id.metered_settings); if (mAccessPoint == null) { // new network mConfigUi.setTitle(R.string.wifi_add_network); @@ -237,6 +238,7 @@ public class WifiConfigController implements TextWatcher, boolean showAdvancedFields = false; if (mAccessPoint.isSaved()) { WifiConfiguration config = mAccessPoint.getConfig(); + mMeteredSettingsSpinner.setSelection(config.meteredOverride); if (config.getIpAssignment() == IpAssignment.STATIC) { mIpSettingsSpinner.setSelection(STATIC_IP); showAdvancedFields = true; @@ -671,6 +673,9 @@ public class WifiConfigController implements TextWatcher, config.setIpConfiguration( new IpConfiguration(mIpAssignment, mProxySettings, mStaticIpConfiguration, mHttpProxy)); + if (mMeteredSettingsSpinner != null) { + config.meteredOverride = mMeteredSettingsSpinner.getSelectedItemPosition(); + } return config; } diff --git a/src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java b/src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java new file mode 100644 index 00000000000..1a3d195a973 --- /dev/null +++ b/src/com/android/settings/wifi/details/WifiMeteredPreferenceController.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2018 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.wifi.details; + +import android.app.backup.BackupManager; +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.provider.Settings; +import android.support.annotation.VisibleForTesting; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.DropDownPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.text.TextUtils; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.AbstractPreferenceController; + +/** + * {@link AbstractPreferenceController} that controls whether the wifi network is metered or not + */ +public class WifiMeteredPreferenceController extends BasePreferenceController implements + Preference.OnPreferenceChangeListener { + + private static final String KEY_WIFI_METERED = "metered"; + private WifiConfiguration mWifiConfiguration; + private WifiManager mWifiManager; + + public WifiMeteredPreferenceController(Context context, WifiConfiguration wifiConfiguration) { + super(context, KEY_WIFI_METERED); + mWifiConfiguration = wifiConfiguration; + mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + } + + @Override + public void updateState(Preference preference) { + final DropDownPreference dropDownPreference = (DropDownPreference) preference; + final int meteredOverride = getMeteredOverride(); + dropDownPreference.setValue(Integer.toString(meteredOverride)); + updateSummary(dropDownPreference, meteredOverride); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mWifiConfiguration.meteredOverride = Integer.parseInt((String) newValue); + mWifiManager.updateNetwork(mWifiConfiguration); + // Stage the backup of the SettingsProvider package which backs this up + BackupManager.dataChanged("com.android.providers.settings"); + updateSummary((DropDownPreference) preference, getMeteredOverride()); + return true; + } + + @VisibleForTesting + int getMeteredOverride() { + // Wrap the meteredOverride since robolectric cannot recognize it + return mWifiConfiguration.meteredOverride; + } + + private void updateSummary(DropDownPreference preference, int meteredOverride) { + preference.setSummary(preference.getEntries()[meteredOverride]); + } +} diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index ea30b562f3c..9a5430bcd8b 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -20,10 +20,13 @@ import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; import android.app.Dialog; import android.content.Context; import android.net.ConnectivityManager; +import android.net.NetworkPolicyManager; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.support.v7.preference.DropDownPreference; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -122,6 +125,7 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { @Override protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); mWifiDetailPreferenceController = WifiDetailPreferenceController.newInstance( mAccessPoint, @@ -133,6 +137,9 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { context.getSystemService(WifiManager.class), mMetricsFeatureProvider); - return new ArrayList<>(Collections.singletonList(mWifiDetailPreferenceController)); + controllers.add(mWifiDetailPreferenceController); + controllers.add(new WifiMeteredPreferenceController(context, mAccessPoint.getConfig())); + + return controllers; } } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index dc53ca104ea..c1221054c43 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -68,23 +68,6 @@ public class DataUsageSummaryTest { when(mManager.isNetworkSupported(anyInt())).thenReturn(true); } - @Test - public void testUpdateNetworkRestrictionSummary_shouldSetSummary() { - final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary()); - final NetworkRestrictionsPreference preference = mock(NetworkRestrictionsPreference.class); - final NetworkPolicyEditor policyEditor = mock(NetworkPolicyEditor.class); - final WifiManager wifiManager = mock(WifiManager.class); - ReflectionHelpers.setField(dataUsageSummary, "mPolicyEditor", policyEditor); - ReflectionHelpers.setField(dataUsageSummary, "mWifiManager", wifiManager); - when(wifiManager.getConfiguredNetworks()).thenReturn(new ArrayList()); - doReturn(mContext.getResources()).when(dataUsageSummary).getResources(); - - dataUsageSummary.updateNetworkRestrictionSummary(preference); - - verify(preference).setSummary(mContext.getResources().getQuantityString( - R.plurals.network_restrictions_summary, 0, 0)); - } - @Test @Config(shadows = { SettingsShadowResources.class, diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java new file mode 100644 index 00000000000..f624bd57cdb --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiMeteredPreferenceControllerTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2018 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.wifi.details; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.support.v7.preference.DropDownPreference; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class WifiMeteredPreferenceControllerTest { + public static final int METERED_OVERRIDE_NONE = 0; + public static final int METERED_OVERRIDE_METERED = 1; + public static final int METERED_OVERRIDE_NOT_METERED = 2; + + @Mock + private WifiConfiguration mWifiConfiguration; + + private WifiMeteredPreferenceController mPreferenceController; + private Context mContext; + private DropDownPreference mDropDownPreference; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + + mPreferenceController = spy( + new WifiMeteredPreferenceController(mContext, mWifiConfiguration)); + mDropDownPreference = new DropDownPreference(mContext); + mDropDownPreference.setEntries(R.array.wifi_metered_entries); + mDropDownPreference.setEntryValues(R.array.wifi_metered_values); + } + + @Test + public void testUpdateState_wifiMetered_setCorrectValue() { + doReturn(METERED_OVERRIDE_METERED).when(mPreferenceController).getMeteredOverride(); + + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.getEntry()).isEqualTo("Treat as metered"); + } + + @Test + public void testUpdateState_wifiNotMetered_setCorrectValue() { + doReturn(METERED_OVERRIDE_NOT_METERED).when(mPreferenceController).getMeteredOverride(); + + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.getEntry()).isEqualTo("Treat as unmetered"); + } + + @Test + public void testUpdateState_wifiAuto_setCorrectValue() { + doReturn(METERED_OVERRIDE_NONE).when(mPreferenceController).getMeteredOverride(); + + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.getEntry()).isEqualTo("Use network preference"); + } +}