Data plan usage summary fragment.

Change-Id: I2d928d1b5313b723450c8f5a45ff944b99dc3d5d
Note: These changes are required for Data balance UI.
Bug: 62349208
Test: make RunSettingsRoboTests -j40
This commit is contained in:
Rajeev Kumar
2017-07-14 19:40:56 -07:00
parent 4b351b4ca1
commit e19cd4828e
9 changed files with 734 additions and 40 deletions

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/data_usage_summary_title">
<PreferenceCategory
android:key="data_plan_usage"
android:title="@string/usage">
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/data_usage_summary_title">
<com.android.settings.datausage.TemplatePreferenceCategory
android:key="data_usage_mobile_category"
android:title="@string/data_usage_tab_mobile">
<com.android.settings.datausage.CellDataPreference
android:key="data_usage_enable"
android:title="@string/data_usage_enable_mobile" />
</com.android.settings.datausage.TemplatePreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,399 @@
/*
* Copyright (C) 2017 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 static android.net.NetworkPolicy.LIMIT_DISABLED;
import android.annotation.IdRes;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
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.os.UserManager;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.text.format.Formatter;
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.Utils;
import com.android.settings.dashboard.SummaryLoader;
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;
public class DataPlanUsageSummary extends DataUsageBase implements Indexable {
public static final String KEY_RESTRICT_BACKGROUND = "restrict_background";
public static final String KEY_NETWORK_RESTRICTIONS = "network_restrictions";
private static final String KEY_DATA_PLAN_USAGE = "data_plan_usage";
private static final String KEY_STATUS_HEADER = "status_header";
private static final String KEY_LIMIT_SUMMARY = "plan_summary";
private static final String KEY_MOBILE_USAGE_TITLE = "data_usage_mobile_category";
private static final String KEY_WIFI_USAGE_TITLE = "wifi_category";
private DataUsageController mDataUsageController;
private DataUsageInfoController mDataInfoController;
private List<DataPlanSummaryPreference> mDataPlanSummaryPreferenceList;
private Preference mLimitPreference;
private NetworkTemplate mDefaultTemplate;
private NetworkRestrictionsPreference mNetworkRestrictionPreference;
private WifiManager mWifiManager;
private NetworkPolicyEditor mPolicyEditor;
@Override
protected int getHelpResource() {
return R.string.help_url_data_usage;
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
final Context context = getContext();
NetworkPolicyManager policyManager = NetworkPolicyManager.from(context);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mPolicyEditor = new NetworkPolicyEditor(policyManager);
mDataUsageController = new DataUsageController(context);
mDataInfoController = new DataUsageInfoController();
int defaultSubId = DataUsageUtils.getDefaultSubscriptionId(context);
boolean hasMobileData = DataUsageUtils.hasMobileData(context);
if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
hasMobileData = false;
}
mDefaultTemplate = DataUsageUtils.getDefaultTemplate(context, defaultSubId);
if (!hasMobileData || !isAdmin()) {
removePreference(KEY_RESTRICT_BACKGROUND);
}
if (hasMobileData) {
addDataPlanSection(defaultSubId);
}
if (DataUsageUtils.hasWifiRadio(context)) {
addWifiSection();
}
if (hasEthernet(context)) {
addEthernetSection();
}
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (UserManager.get(getContext()).isAdminUser()) {
inflater.inflate(R.menu.data_usage, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.data_usage_menu_cellular_networks: {
final Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
startActivity(intent);
return true;
}
}
return false;
}
private void addDataPlanSection(int defaultSubId) {
Context context = getPrefContext();
addPreferencesFromResource(R.xml.data_plan_usage);
PreferenceScreen screen = getPreferenceScreen();
screen.setTitle(context.getString(R.string.data_usage_summary_title));
PreferenceCategory preferenceCategory =
(PreferenceCategory) findPreference(KEY_DATA_PLAN_USAGE);
screen.addPreference(preferenceCategory);
Preference dataPlansSyncTimePreference = new Preference(context);
dataPlansSyncTimePreference.setLayoutResource(R.layout.data_plans_sync_time_preference);
dataPlansSyncTimePreference.setTitle(MockDataPlanUsage.SYNC_TIME);
preferenceCategory.addPreference(dataPlansSyncTimePreference);
mDataPlanSummaryPreferenceList = new ArrayList<>(MockDataPlanUsage.DATA_PLAN_USAGES.length);
for (int i = 0; i < MockDataPlanUsage.DATA_PLAN_USAGES.length; i++) {
DataPlanSummaryPreference dataPlanSummaryPreference =
new DataPlanSummaryPreference(context);
dataPlanSummaryPreference.setKey(KEY_STATUS_HEADER + (i + 1));
mDataPlanSummaryPreferenceList.add(dataPlanSummaryPreference);
preferenceCategory.addPreference(dataPlanSummaryPreference);
}
Preference preference = new Preference(context);
preference.setLayoutResource(R.layout.manage_data_plans_preference);
preferenceCategory.addPreference(preference);
setPreferenceScreen(screen);
mLimitPreference = findPreference(KEY_LIMIT_SUMMARY);
List<SubscriptionInfo> subscriptions =
services.mSubscriptionManager.getActiveSubscriptionInfoList();
if (subscriptions == null || subscriptions.isEmpty()) {
addMobileSection(defaultSubId);
}
for (int i = 0, subscriptionsSize = subscriptions != null ? subscriptions.size() : 0;
i < subscriptionsSize; i++) {
SubscriptionInfo subInfo = subscriptions.get(i);
if (subscriptionsSize > 1) {
addMobileSection(subInfo.getSubscriptionId(), subInfo);
} else {
addMobileSection(subInfo.getSubscriptionId());
}
}
}
private void addMobileSection(int subId) {
addMobileSection(subId, null);
}
private void addMobileSection(int subId, SubscriptionInfo subInfo) {
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
inflatePreferences(R.xml.data_plan_usage_cell_data_preference_screen);
category.setTemplate(getNetworkTemplate(subId), subId, services);
category.pushTemplates(services);
if (subInfo != null && !TextUtils.isEmpty(subInfo.getDisplayName())) {
Preference title = category.findPreference(KEY_MOBILE_USAGE_TITLE);
title.setTitle(subInfo.getDisplayName());
}
}
private void addWifiSection() {
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
inflatePreferences(R.xml.data_usage_wifi);
category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0 /* subId */, services);
mNetworkRestrictionPreference =
(NetworkRestrictionsPreference) category.findPreference(KEY_NETWORK_RESTRICTIONS);
}
private void addEthernetSection() {
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
inflatePreferences(R.xml.data_usage_ethernet);
category.setTemplate(NetworkTemplate.buildTemplateEthernet(), 0 /* subId */, services);
}
private Preference inflatePreferences(@IdRes int resId) {
PreferenceScreen rootPreferences = getPreferenceManager().inflateFromResource(
getPrefContext(), resId, null);
Preference pref = rootPreferences.getPreference(0);
rootPreferences.removeAll();
PreferenceScreen screen = getPreferenceScreen();
pref.setOrder(screen.getPreferenceCount());
screen.addPreference(pref);
return pref;
}
private NetworkTemplate getNetworkTemplate(int subscriptionId) {
NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
services.mTelephonyManager.getSubscriberId(subscriptionId));
return NetworkTemplate.normalize(mobileAll,
services.mTelephonyManager.getMergedSubscriberIds());
}
@Override
public void onResume() {
super.onResume();
updateState();
}
private void updateState() {
DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
mDefaultTemplate);
Context context = getContext();
mDataInfoController.updateDataLimit(info,
services.mPolicyEditor.getPolicy(mDefaultTemplate));
// TODO(b/63391323): Get rid of MockDataPlanUsage once we integrate with data plan APIs
if (mDataPlanSummaryPreferenceList != null && !mDataPlanSummaryPreferenceList.isEmpty()) {
MockDataPlanUsage[] dataPlanUsages = MockDataPlanUsage.getDataPlanUsage();
for (int i = 0; i < dataPlanUsages.length; i++) {
DataPlanSummaryPreference dataPlanSummaryPreference =
mDataPlanSummaryPreferenceList.get(i);
MockDataPlanUsage dataPlanUsage = dataPlanUsages[i];
dataPlanSummaryPreference.setTitle(dataPlanUsage.mUsage);
dataPlanSummaryPreference.setUsageTextColor(dataPlanUsage.mUsageTextColor);
dataPlanSummaryPreference.setName(dataPlanUsage.mName);
dataPlanSummaryPreference.setPercentageUsage(dataPlanUsage.mPercentageUsage);
dataPlanSummaryPreference
.setMeterBackgroundColor(dataPlanUsage.mMeterBackgroundColor);
dataPlanSummaryPreference.setMeterConsumedColor(dataPlanUsage.mMeterConsumedColor);
dataPlanSummaryPreference.setDescription(dataPlanUsage.mDescription);
}
}
if (mLimitPreference != null && (info.warningLevel > 0 || info.limitLevel > 0)) {
String warning = Formatter.formatFileSize(context, info.warningLevel);
String limit = Formatter.formatFileSize(context, info.limitLevel);
mLimitPreference.setSummary(getString(info.limitLevel <= 0 ? R.string.cell_warning_only
: R.string.cell_warning_and_limit, warning, limit));
} else if (mLimitPreference != null) {
mLimitPreference.setSummary(null);
}
updateNetworkRestrictionSummary(mNetworkRestrictionPreference);
PreferenceScreen screen = getPreferenceScreen();
for (int i = 1, preferenceCount = screen.getPreferenceCount(); i < preferenceCount; i++) {
((TemplatePreferenceCategory) screen.getPreference(i)).pushTemplates(services);
}
}
@Override
public int getMetricsCategory() {
return MetricsEvent.DATA_USAGE_SUMMARY;
}
@VisibleForTesting
void updateNetworkRestrictionSummary(NetworkRestrictionsPreference preference) {
if (preference == null) {
return;
}
mPolicyEditor.read();
int count = 0;
List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks();
for (int i = 0, configuredNetworksSize = configuredNetworks.size();
i < configuredNetworksSize; i++) {
WifiConfiguration config = configuredNetworks.get(i);
if (isMetered(config)) {
count++;
}
}
preference.setSummary(getResources().getQuantityString(
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 {
private final Activity mActivity;
private final SummaryLoader mSummaryLoader;
private final DataUsageController mDataController;
public SummaryProvider(Activity activity, SummaryLoader summaryLoader) {
mActivity = activity;
mSummaryLoader = summaryLoader;
mDataController = new DataUsageController(activity);
}
@Override
public void setListening(boolean listening) {
if (listening) {
DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
String used;
if (info == null) {
used = Formatter.formatFileSize(mActivity, 0);
} else if (info.limitLevel <= 0) {
used = Formatter.formatFileSize(mActivity, info.usageLevel);
} else {
used = Utils.formatPercentage(info.usageLevel, info.limitLevel);
}
mSummaryLoader.setSummary(this,
mActivity.getString(R.string.data_usage_summary_format, used));
}
}
}
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
= SummaryProvider::new;
/**
* For search
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
List<SearchIndexableResource> resources = new ArrayList<>();
SearchIndexableResource resource = new SearchIndexableResource(context);
resource.xmlResId = R.xml.data_plan_usage;
resources.add(resource);
if (DataUsageUtils.hasMobileData(context)) {
resource = new SearchIndexableResource(context);
resource.xmlResId = R.xml.data_plan_usage_cell_data_preference_screen;
resources.add(resource);
}
if (DataUsageUtils.hasWifiRadio(context)) {
resource = new SearchIndexableResource(context);
resource.xmlResId = R.xml.data_usage_wifi;
resources.add(resource);
}
return resources;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
if (DataUsageUtils.hasMobileData(context)) {
keys.add(KEY_RESTRICT_BACKGROUND);
}
if (DataUsageUtils.hasWifiRadio(context)) {
keys.add(KEY_NETWORK_RESTRICTIONS);
}
keys.add(KEY_WIFI_USAGE_TITLE);
return keys;
}
};
}

View File

@@ -14,14 +14,21 @@
package com.android.settings.datausage;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
import android.os.Bundle;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -31,6 +38,7 @@ import com.android.settingslib.NetworkPolicyEditor;
public abstract class DataUsageBase extends SettingsPreferenceFragment {
private static final String TAG = "DataUsageBase";
private static final String ETHERNET = "ethernet";
protected final TemplatePreference.NetworkServices services =
new TemplatePreference.NetworkServices();
@@ -83,8 +91,38 @@ public abstract class DataUsageBase extends SettingsPreferenceFragment {
try {
return services.mNetworkService.isBandwidthControlEnabled();
} catch (RemoteException e) {
Log.w(TAG, "problem talking with INetworkManagementService: " + e);
Log.w(TAG, "problem talking with INetworkManagementService: ", e);
return false;
}
}
/**
* Test if device has an ethernet network connection.
*/
public boolean hasEthernet(Context context) {
if (DataUsageUtils.TEST_RADIOS) {
return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains(ETHERNET);
}
final ConnectivityManager conn = ConnectivityManager.from(context);
final boolean hasEthernet = conn.isNetworkSupported(TYPE_ETHERNET);
final long ethernetBytes;
try {
INetworkStatsSession statsSession = services.mStatsService.openSession();
if (statsSession != null) {
ethernetBytes = statsSession.getSummaryForNetwork(
NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE)
.getTotalBytes();
TrafficStats.closeQuietly(statsSession);
} else {
ethernetBytes = 0;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
// only show ethernet when both hardware present and traffic has occurred
return hasEthernet && ethernetBytes > 0;
}
}

View File

@@ -58,6 +58,12 @@ import com.android.settingslib.net.DataUsageController;
import java.util.ArrayList;
import java.util.List;
/**
* Settings preference fragment that displays data usage summary.
*
* This class in deprecated use {@link DataPlanUsageSummary}.
*/
@Deprecated
public class DataUsageSummary extends DataUsageBase implements Indexable, DataUsageEditController {
static final boolean LOGD = false;
@@ -311,36 +317,6 @@ public class DataUsageSummary extends DataUsageBase implements Indexable, DataUs
updateState();
}
/**
* Test if device has an ethernet network connection.
*/
public boolean hasEthernet(Context context) {
if (DataUsageUtils.TEST_RADIOS) {
return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains("ethernet");
}
final ConnectivityManager conn = ConnectivityManager.from(context);
final boolean hasEthernet = conn.isNetworkSupported(TYPE_ETHERNET);
final long ethernetBytes;
try {
INetworkStatsSession statsSession = services.mStatsService.openSession();
if (statsSession != null) {
ethernetBytes = statsSession.getSummaryForNetwork(
NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE)
.getTotalBytes();
TrafficStats.closeQuietly(statsSession);
} else {
ethernetBytes = 0;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
// only show ethernet when both hardware present and traffic has occurred
return hasEthernet && ethernetBytes > 0;
}
@VisibleForTesting
void updateNetworkRestrictionSummary(NetworkRestrictionsPreference preference) {
if (preference == null) {

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 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.graphics.Color;
/**
* Mock data plan usage data.
*/
@Deprecated // This class is only needed because we don't have working API yet.
final class MockDataPlanUsage {
static final MockDataPlanUsage[] DATA_PLAN_USAGES = new MockDataPlanUsage[3];
static final String SYNC_TIME = "Today 12:24pm";
final String mUsage;
final int mUsageTextColor;
final String mName;
final double mPercentageUsage;
final int mMeterBackgroundColor;
final int mMeterConsumedColor;
final String mDescription;
private MockDataPlanUsage(String usage, int usageTextColor, String name,
double percentageUsage, int meterBackgroundColor, int meterConsumedColor,
String description) {
mUsage = usage;
mUsageTextColor = usageTextColor;
mName = name;
mPercentageUsage = percentageUsage;
mMeterBackgroundColor = meterBackgroundColor;
mMeterConsumedColor = meterConsumedColor;
mDescription = description;
}
static MockDataPlanUsage[] getDataPlanUsage() {
DATA_PLAN_USAGES[0] = new MockDataPlanUsage("100 MB and 14 days left",
Color.parseColor("#FF5C94F1"), "GigaMaxLite / 1GB", 0.27D,
Color.parseColor("#FFDBDCDC"), Color.parseColor("#FF5C94F1"),
"Premium plan from Telekomsel");
DATA_PLAN_USAGES[1] = new MockDataPlanUsage("1.25 GB and 14 days left",
Color.parseColor("#FF673AB7"), "GigaMaxLite 4G / 5GB", 0.47D,
Color.parseColor("#FFDBDCDC"), Color.parseColor("#FF673AB7"),
"Plenty of 4G data");
DATA_PLAN_USAGES[2] = new MockDataPlanUsage("700 MB and 14 days left",
Color.parseColor("#FF4CAF50"), "GigaMaxLite Video / 7GB", 0.67D,
Color.parseColor("#FFDBDCDC"), Color.parseColor("#FF4CAF50"),
"Use certain video apps for free");
return DATA_PLAN_USAGES;
}
}

View File

@@ -21,7 +21,6 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.XmlRes;
import android.text.TextUtils;
import com.android.settings.DateTimeSettings;
import com.android.settings.DeviceInfoSettings;
import com.android.settings.DisplaySettings;
@@ -42,6 +41,7 @@ import com.android.settings.backup.BackupSettingsActivity;
import com.android.settings.backup.BackupSettingsFragment;
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.datausage.DataPlanUsageSummary;
import com.android.settings.datausage.DataUsageMeteredSettings;
import com.android.settings.datausage.DataUsageSummary;
import com.android.settings.development.DevelopmentSettings;
@@ -86,7 +86,6 @@ import com.android.settings.wallpaper.WallpaperTypeSettings;
import com.android.settings.wifi.ConfigureWifiSettings;
import com.android.settings.wifi.SavedAccessPointsWifiSettings;
import com.android.settings.wifi.WifiSettings;
import java.util.Collection;
import java.util.HashMap;
@@ -133,6 +132,7 @@ public final class SearchIndexableResources {
R.drawable.ic_settings_wireless);
addIndex(BluetoothSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_bluetooth);
addIndex(SimSettings.class, NO_DATA_RES_ID, R.drawable.ic_sim_sd);
addIndex(DataPlanUsageSummary.class, NO_DATA_RES_ID, R.drawable.ic_settings_data_usage);
addIndex(DataUsageSummary.class, NO_DATA_RES_ID, R.drawable.ic_settings_data_usage);
addIndex(DataUsageMeteredSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_data_usage);
addIndex(ScreenZoomSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_display);

View File

@@ -0,0 +1,162 @@
/*
* Copyright (C) 2017 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkPolicy;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
import com.android.settingslib.NetworkPolicyEditor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DataPlanUsageSummaryTest {
@Mock
private ConnectivityManager mManager;
private Context mContext;
private DataPlanUsageSummary mDataUsageSummary;
private NetworkPolicyEditor mPolicyEditor;
private WifiConfiguration mWifiConfiguration;
private NetworkPolicy mNetworkPolicy;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowContext = ShadowApplication.getInstance();
shadowContext.setSystemService(Context.CONNECTIVITY_SERVICE, mManager);
mContext = shadowContext.getApplicationContext();
when(mManager.isNetworkSupported(anyInt())).thenReturn(true);
}
@Test
public void testUpdateNetworkRestrictionSummary_shouldSetSummary() {
mDataUsageSummary = spy(new DataPlanUsageSummary());
NetworkRestrictionsPreference preference = mock(NetworkRestrictionsPreference.class);
mPolicyEditor = mock(NetworkPolicyEditor.class);
WifiManager wifiManager = mock(WifiManager.class);
ReflectionHelpers.setField(mDataUsageSummary, "mPolicyEditor", mPolicyEditor);
ReflectionHelpers.setField(mDataUsageSummary, "mWifiManager", wifiManager);
when(wifiManager.getConfiguredNetworks()).thenReturn(new ArrayList<>());
doReturn(mContext.getResources()).when(mDataUsageSummary).getResources();
mDataUsageSummary.updateNetworkRestrictionSummary(preference);
verify(preference).setSummary(mContext.getResources().getQuantityString(
R.plurals.network_restrictions_summary, 0, 0));
}
@Test
public void testIsMetered_noSsid_shouldReturnFalse() {
initTest();
assertThat(mDataUsageSummary.isMetered(mWifiConfiguration)).isFalse();
}
@Test
public void testIsMetered_noNetworkPolicy_shouldReturnFalse() {
initTest();
mWifiConfiguration.SSID = "network1";
doReturn(null).when(mPolicyEditor).getPolicyMaybeUnquoted(any());
assertThat(mDataUsageSummary.isMetered(mWifiConfiguration)).isFalse();
}
@Test
public void testIsMetered_policyHasLimit_shouldReturnTrue() {
initTest();
mWifiConfiguration.SSID = "network1";
mNetworkPolicy = mock(NetworkPolicy.class);
mNetworkPolicy.limitBytes = 100;
doReturn(mNetworkPolicy).when(mPolicyEditor).getPolicyMaybeUnquoted(any());
assertThat(mDataUsageSummary.isMetered(mWifiConfiguration)).isTrue();
}
@Test
public void testIsMetered_noPolicyLimit_shouldReturnMeteredValue() {
initTest();
mWifiConfiguration.SSID = "network1";
mNetworkPolicy = mock(NetworkPolicy.class);
mNetworkPolicy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
doReturn(mNetworkPolicy).when(mPolicyEditor).getPolicyMaybeUnquoted(any());
mNetworkPolicy.metered = true;
assertThat(mDataUsageSummary.isMetered(mWifiConfiguration)).isTrue();
mNetworkPolicy.metered = false;
assertThat(mDataUsageSummary.isMetered(mWifiConfiguration)).isFalse();
}
@Test
public void testNonIndexableKeys_existInXmlLayout() {
Context context = RuntimeEnvironment.application;
List<String> niks = DataPlanUsageSummary.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(context);
List<String> keys = new ArrayList<>();
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.data_usage_wifi));
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.data_usage));
assertThat(keys).containsAllIn(niks);
}
@Test
@Config(shadows = ShadowConnectivityManager.class)
public void testNonIndexableKeys_hasMobileData_restrictedAccessesAdded() {
ShadowConnectivityManager.setIsNetworkSupported(true);
List<String> keys = DataPlanUsageSummary.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
assertThat(keys).contains(DataPlanUsageSummary.KEY_RESTRICT_BACKGROUND);
assertThat(keys).contains(DataPlanUsageSummary.KEY_NETWORK_RESTRICTIONS);
ShadowConnectivityManager.setIsNetworkSupported(false);
}
private void initTest() {
mDataUsageSummary = new DataPlanUsageSummary();
mPolicyEditor = mock(NetworkPolicyEditor.class);
ReflectionHelpers.setField(mDataUsageSummary, "mPolicyEditor", mPolicyEditor);
mWifiConfiguration = mock(WifiConfiguration.class);
}
}

View File

@@ -1,28 +1,28 @@
package com.android.settings.search;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.SearchIndexableResource;
import android.util.ArraySet;
import com.android.settings.DateTimeSettings;
import com.android.settings.R;
import com.android.settings.SecuritySettings;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.codeinspection.CodeInspector;
import com.android.settings.datausage.DataPlanUsageSummary;
import com.android.settings.datausage.DataUsageSummary;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.google.common.truth.Truth.assertThat;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
assetDir = "/tests/robotests/assets")
@@ -60,6 +60,7 @@ public class DataIntegrityTest {
// Skip classes that are invalid or cannot be mocked. Add them as special Xml below.
if (clazz == null
|| clazz == DateTimeSettings.class
|| clazz == DataPlanUsageSummary.class
|| clazz == DataUsageSummary.class
|| clazz == SecuritySettings.class) {
continue;