Fall back to Wi-Fi data display in data usage screen with no SIM.
Bug: 70950124 Test: manual Test: make RunSettingsRoboTests Change-Id: I06bf78e54119819be87e15baca7e5b6a241958cb Merged-In: I06bf78e54119819be87e15baca7e5b6a241958cb
This commit is contained in:
@@ -48,13 +48,14 @@ public abstract class DataUsageBaseFragment extends DashboardFragment {
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
final Context context = getActivity();
|
||||
Context context = getContext();
|
||||
|
||||
services.mNetworkService = INetworkManagementService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
|
||||
services.mStatsService = INetworkStatsService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
||||
services.mPolicyManager = NetworkPolicyManager.from(context);
|
||||
services.mPolicyManager = (NetworkPolicyManager)context
|
||||
.getSystemService(Context.NETWORK_POLICY_SERVICE);
|
||||
|
||||
services.mPolicyEditor = new NetworkPolicyEditor(services.mPolicyManager);
|
||||
|
||||
@@ -100,6 +101,7 @@ public abstract class DataUsageBaseFragment extends DashboardFragment {
|
||||
|
||||
/**
|
||||
* Test if device has an ethernet network connection.
|
||||
* TODO(b/77590489): Remove this method when DataUsageSummaryLegacy is deprecated.
|
||||
*/
|
||||
public boolean hasEthernet(Context context) {
|
||||
if (DataUsageUtils.TEST_RADIOS) {
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import android.util.Log;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -85,8 +86,7 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
final Context context = getContext();
|
||||
Context context = getContext();
|
||||
|
||||
boolean hasMobileData = DataUsageUtils.hasMobileData(context);
|
||||
|
||||
@@ -100,18 +100,21 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
if (!hasMobileData || !isAdmin()) {
|
||||
removePreference(KEY_RESTRICT_BACKGROUND);
|
||||
}
|
||||
if (hasMobileData) {
|
||||
SubscriptionInfo subInfo
|
||||
= services.mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||
if (subInfo != null) {
|
||||
addMobileSection(subInfo.getSubscriptionId());
|
||||
}
|
||||
}
|
||||
boolean hasWifiRadio = DataUsageUtils.hasWifiRadio(context);
|
||||
if (hasWifiRadio) {
|
||||
if (hasMobileData) {
|
||||
addMobileSection(defaultSubId);
|
||||
if (DataUsageUtils.hasSim(context) && hasWifiRadio) {
|
||||
// If the device has a SIM installed, the data usage section shows usage for mobile,
|
||||
// and the WiFi section is added if there is a WiFi radio - legacy behavior.
|
||||
addWifiSection();
|
||||
}
|
||||
// Do not add the WiFi section if either there is no WiFi radio (obviously) or if no
|
||||
// SIM is installed. In the latter case the data usage section will show WiFi usage and
|
||||
// there should be no explicit WiFi section added.
|
||||
} else if (hasWifiRadio) {
|
||||
addWifiSection();
|
||||
}
|
||||
if (hasEthernet(context)) {
|
||||
if (DataUsageUtils.hasEthernet(context)) {
|
||||
addEthernetSection();
|
||||
}
|
||||
setHasOptionsMenu(true);
|
||||
@@ -161,7 +164,8 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
return controllers;
|
||||
}
|
||||
|
||||
private void addMobileSection(int subId) {
|
||||
@VisibleForTesting
|
||||
void addMobileSection(int subId) {
|
||||
addMobileSection(subId, null);
|
||||
}
|
||||
|
||||
@@ -176,7 +180,8 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
}
|
||||
}
|
||||
|
||||
private void addWifiSection() {
|
||||
@VisibleForTesting
|
||||
void addWifiSection() {
|
||||
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
|
||||
inflatePreferences(R.xml.data_usage_wifi);
|
||||
category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0, services);
|
||||
@@ -289,17 +294,25 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
TelephonyManager telephonyManager = (TelephonyManager) mActivity
|
||||
.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
final int simState = telephonyManager.getSimState();
|
||||
// Note that pulling the SIM card returns UNKNOWN, not ABSENT.
|
||||
if (simState == TelephonyManager.SIM_STATE_ABSENT
|
||||
|| simState == TelephonyManager.SIM_STATE_UNKNOWN) {
|
||||
mSummaryLoader.setSummary(this, null);
|
||||
} else {
|
||||
if (DataUsageUtils.hasSim(mActivity)) {
|
||||
mSummaryLoader.setSummary(this,
|
||||
mActivity.getString(R.string.data_usage_summary_format,
|
||||
formatUsedData()));
|
||||
} else {
|
||||
final DataUsageController.DataUsageInfo info =
|
||||
mDataController
|
||||
.getDataUsageInfo(NetworkTemplate.buildTemplateWifiWildcard());
|
||||
|
||||
if (info == null) {
|
||||
mSummaryLoader.setSummary(this, null);
|
||||
} else {
|
||||
final CharSequence wifiFormat = mActivity
|
||||
.getText(R.string.data_usage_wifi_format);
|
||||
final CharSequence sizeText =
|
||||
Formatter.formatFileSize(mActivity, info.usageLevel);
|
||||
mSummaryLoader.setSummary(this,
|
||||
TextUtils.expandTemplate(wifiFormat, sizeText));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,8 @@ import android.annotation.AttrRes;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.text.Spannable;
|
||||
@@ -34,7 +36,10 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
@@ -83,6 +88,10 @@ public class DataUsageSummaryPreference extends Preference {
|
||||
/** The number of bytes used since the start of the cycle. */
|
||||
private long mDataplanUse;
|
||||
|
||||
/** WiFi only mode */
|
||||
private boolean mWifiMode;
|
||||
private String mUsagePeriod;
|
||||
|
||||
public DataUsageSummaryPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutResource(R.layout.data_usage_summary_preference);
|
||||
@@ -130,6 +139,12 @@ public class DataUsageSummaryPreference extends Preference {
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
void setWifiMode(boolean isWifiMode, String usagePeriod) {
|
||||
mWifiMode = isWifiMode;
|
||||
mUsagePeriod = usagePeriod;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
@@ -149,29 +164,52 @@ public class DataUsageSummaryPreference extends Preference {
|
||||
updateDataUsageLabels(holder);
|
||||
|
||||
TextView usageTitle = (TextView) holder.findViewById(R.id.usage_title);
|
||||
usageTitle.setVisibility(mNumPlans > 1 ? View.VISIBLE : View.GONE);
|
||||
|
||||
updateCycleTimeText(holder);
|
||||
|
||||
|
||||
updateCarrierInfo((TextView) holder.findViewById(R.id.carrier_and_update));
|
||||
|
||||
TextView carrierInfo = (TextView) holder.findViewById(R.id.carrier_and_update);
|
||||
Button launchButton = (Button) holder.findViewById(R.id.launch_mdp_app_button);
|
||||
launchButton.setOnClickListener((view) -> {
|
||||
getContext().sendBroadcast(mLaunchIntent);
|
||||
});
|
||||
if (mLaunchIntent != null) {
|
||||
TextView limitInfo = (TextView) holder.findViewById(R.id.data_limits);
|
||||
|
||||
if (mWifiMode) {
|
||||
usageTitle.setText(R.string.data_usage_wifi_title);
|
||||
usageTitle.setVisibility(View.VISIBLE);
|
||||
TextView cycleTime = (TextView) holder.findViewById(R.id.cycle_left_time);
|
||||
cycleTime.setText(mUsagePeriod);
|
||||
carrierInfo.setVisibility(View.GONE);
|
||||
limitInfo.setVisibility(View.GONE);
|
||||
|
||||
launchButton.setOnClickListener((view) -> {
|
||||
launchWifiDataUsage(getContext());
|
||||
});
|
||||
launchButton.setText(R.string.launch_wifi_text);
|
||||
launchButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
launchButton.setVisibility(View.GONE);
|
||||
usageTitle.setVisibility(mNumPlans > 1 ? View.VISIBLE : View.GONE);
|
||||
updateCycleTimeText(holder);
|
||||
updateCarrierInfo(carrierInfo);
|
||||
if (mLaunchIntent != null) {
|
||||
launchButton.setOnClickListener((view) -> {
|
||||
getContext().sendBroadcast(mLaunchIntent);
|
||||
});
|
||||
launchButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
launchButton.setVisibility(View.GONE);
|
||||
}
|
||||
limitInfo.setVisibility(
|
||||
TextUtils.isEmpty(mLimitInfoText) ? View.GONE : View.VISIBLE);
|
||||
limitInfo.setText(mLimitInfoText);
|
||||
}
|
||||
|
||||
TextView limitInfo = (TextView) holder.findViewById(R.id.data_limits);
|
||||
limitInfo.setVisibility(
|
||||
mLimitInfoText == null || mLimitInfoText.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
limitInfo.setText(mLimitInfoText);
|
||||
}
|
||||
|
||||
private static void launchWifiDataUsage(Context context) {
|
||||
final Bundle args = new Bundle(1);
|
||||
args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE,
|
||||
NetworkTemplate.buildTemplateWifiWildcard());
|
||||
final SubSettingLauncher launcher = new SubSettingLauncher(context)
|
||||
.setArguments(args)
|
||||
.setDestination(DataUsageList.class.getName())
|
||||
.setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN);
|
||||
launcher.setTitle(context.getString(R.string.wifi_data_usage));
|
||||
launcher.launch();
|
||||
}
|
||||
|
||||
private void updateDataUsageLabels(PreferenceViewHolder holder) {
|
||||
TextView usageNumberField = (TextView) holder.findViewById(R.id.data_usage_view);
|
||||
|
@@ -27,6 +27,7 @@ import android.support.v7.preference.Preference;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
@@ -183,17 +184,35 @@ public class DataUsageSummaryPreferenceController extends BasePreferenceControll
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mSubscriptionManager.getDefaultDataSubscriptionInfo() != null
|
||||
? AVAILABLE : DISABLED_UNSUPPORTED;
|
||||
return DataUsageUtils.hasSim(mActivity)
|
||||
|| DataUsageUtils.hasWifiRadio(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
DataUsageSummaryPreference summaryPreference = (DataUsageSummaryPreference) preference;
|
||||
DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
|
||||
mDefaultTemplate);
|
||||
|
||||
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||
final DataUsageController.DataUsageInfo info;
|
||||
if (DataUsageUtils.hasSim(mActivity)) {
|
||||
info = mDataUsageController.getDataUsageInfo(mDefaultTemplate);
|
||||
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||
summaryPreference.setWifiMode(/* isWifiMode */ false, /* usagePeriod */ null);
|
||||
} else {
|
||||
info = mDataUsageController.getDataUsageInfo(
|
||||
NetworkTemplate.buildTemplateWifiWildcard());
|
||||
summaryPreference.setWifiMode(/* isWifiMode */ true, /* usagePeriod */ info.period);
|
||||
summaryPreference.setLimitInfo(null);
|
||||
summaryPreference.setUsageNumbers(info.usageLevel,
|
||||
/* dataPlanSize */ -1L,
|
||||
/* hasMobileData */ true);
|
||||
summaryPreference.setChartEnabled(false);
|
||||
summaryPreference.setUsageInfo(info.cycleEnd,
|
||||
/* snapshotTime */ -1L,
|
||||
/* carrierName */ null,
|
||||
/* numPlans */ 0,
|
||||
/* launchIntent */ null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSubscriptionManager != null) {
|
||||
refreshDataplanInfo(info);
|
||||
|
@@ -14,11 +14,17 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_ETHERNET;
|
||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.INetworkStatsSession;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
@@ -31,10 +37,44 @@ import java.util.List;
|
||||
public final class DataUsageUtils {
|
||||
static final boolean TEST_RADIOS = false;
|
||||
static final String TEST_RADIOS_PROP = "test.radios";
|
||||
private static final String ETHERNET = "ethernet";
|
||||
|
||||
private DataUsageUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if device has an ethernet network connection.
|
||||
*/
|
||||
public static 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(ConnectivityManager.TYPE_ETHERNET);
|
||||
|
||||
final long ethernetBytes;
|
||||
try {
|
||||
INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
||||
|
||||
INetworkStatsSession statsSession = statsService.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether device has mobile data.
|
||||
* TODO: This is the opposite to Utils.isWifiOnly(), it should be refactored into 1 method.
|
||||
@@ -53,10 +93,19 @@ public final class DataUsageUtils {
|
||||
return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi");
|
||||
}
|
||||
|
||||
ConnectivityManager connectivityManager = ConnectivityManager.from(context);
|
||||
ConnectivityManager connectivityManager =
|
||||
context.getSystemService(ConnectivityManager.class);
|
||||
return connectivityManager != null && connectivityManager.isNetworkSupported(TYPE_WIFI);
|
||||
}
|
||||
|
||||
public static boolean hasSim(Context context) {
|
||||
TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
|
||||
final int simState = telephonyManager.getSimState();
|
||||
// Note that pulling the SIM card returns UNKNOWN, not ABSENT.
|
||||
return simState != TelephonyManager.SIM_STATE_ABSENT
|
||||
&& simState != TelephonyManager.SIM_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default subscription if available else returns
|
||||
* SubscriptionManager#INVALID_SUBSCRIPTION_ID
|
||||
|
Reference in New Issue
Block a user