Update DataUsageSummary to include carrier provided information.
This CL augments the existing data usage display with carrier provided information about data usage and plans when available from the new frameworks API. Test: manual Test: make RunSettingsRoboTests Bug: 70950124 Change-Id: Idde1ff786e8c5dbc04e58ffbcc0fd18789682699
This commit is contained in:
committed by
Eric Schwarzenbach
parent
525d757c09
commit
4fbe0f8354
@@ -18,7 +18,6 @@ import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
@@ -28,6 +27,7 @@ import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
@@ -40,7 +40,6 @@ import android.view.MenuItem;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SummaryPreference;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
@@ -65,7 +64,6 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
public static final String KEY_RESTRICT_BACKGROUND = "restrict_background";
|
||||
|
||||
private static final String KEY_STATUS_HEADER = "status_header";
|
||||
private static final String KEY_LIMIT_SUMMARY = "limit_summary";
|
||||
|
||||
// Mobile data keys
|
||||
public static final String KEY_MOBILE_USAGE_TITLE = "mobile_category";
|
||||
@@ -77,13 +75,9 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
public static final String KEY_WIFI_USAGE_TITLE = "wifi_category";
|
||||
public static final String KEY_WIFI_DATA_USAGE = "wifi_data_usage";
|
||||
|
||||
private DataUsageController mDataUsageController;
|
||||
private DataUsageInfoController mDataInfoController;
|
||||
private SummaryPreference mSummaryPreference;
|
||||
private Preference mLimitPreference;
|
||||
private DataUsageSummaryPreference mSummaryPreference;
|
||||
private DataUsageSummaryPreferenceController mSummaryController;
|
||||
private NetworkTemplate mDefaultTemplate;
|
||||
private int mDataUsageTemplate;
|
||||
private NetworkPolicyEditor mPolicyEditor;
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
@@ -95,25 +89,20 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
super.onCreate(icicle);
|
||||
|
||||
final Context context = getContext();
|
||||
NetworkPolicyManager policyManager = NetworkPolicyManager.from(context);
|
||||
mPolicyEditor = new NetworkPolicyEditor(policyManager);
|
||||
|
||||
boolean hasMobileData = DataUsageUtils.hasMobileData(context);
|
||||
mDataUsageController = new DataUsageController(context);
|
||||
mDataInfoController = new DataUsageInfoController();
|
||||
|
||||
int defaultSubId = DataUsageUtils.getDefaultSubscriptionId(context);
|
||||
if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
hasMobileData = false;
|
||||
}
|
||||
mDefaultTemplate = DataUsageUtils.getDefaultTemplate(context, defaultSubId);
|
||||
mSummaryPreference = (SummaryPreference) findPreference(KEY_STATUS_HEADER);
|
||||
mSummaryPreference = (DataUsageSummaryPreference) findPreference(KEY_STATUS_HEADER);
|
||||
|
||||
if (!hasMobileData || !isAdmin()) {
|
||||
removePreference(KEY_RESTRICT_BACKGROUND);
|
||||
}
|
||||
if (hasMobileData) {
|
||||
mLimitPreference = findPreference(KEY_LIMIT_SUMMARY);
|
||||
List<SubscriptionInfo> subscriptions =
|
||||
services.mSubscriptionManager.getActiveSubscriptionInfoList();
|
||||
if (subscriptions == null || subscriptions.size() == 0) {
|
||||
@@ -127,10 +116,6 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
addMobileSection(subInfo.getSubscriptionId());
|
||||
}
|
||||
}
|
||||
mSummaryPreference.setSelectable(true);
|
||||
} else {
|
||||
removePreference(KEY_LIMIT_SUMMARY);
|
||||
mSummaryPreference.setSelectable(false);
|
||||
}
|
||||
boolean hasWifiRadio = DataUsageUtils.hasWifiRadio(context);
|
||||
if (hasWifiRadio) {
|
||||
@@ -139,10 +124,6 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
if (hasEthernet(context)) {
|
||||
addEthernetSection();
|
||||
}
|
||||
mDataUsageTemplate = hasMobileData ? R.string.cell_data_template
|
||||
: hasWifiRadio ? R.string.wifi_data_template
|
||||
: R.string.ethernet_data_template;
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@@ -189,7 +170,11 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
||||
return null;
|
||||
final ArrayList<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
mSummaryController =
|
||||
new DataUsageSummaryPreferenceController(context);
|
||||
controllers.add(mSummaryController);
|
||||
return controllers;
|
||||
}
|
||||
|
||||
private void addMobileSection(int subId) {
|
||||
@@ -269,36 +254,6 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
}
|
||||
|
||||
private void updateState() {
|
||||
DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
|
||||
mDefaultTemplate);
|
||||
Context context = getContext();
|
||||
mDataInfoController.updateDataLimit(info,
|
||||
services.mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||
|
||||
if (mSummaryPreference != null) {
|
||||
mSummaryPreference.setTitle(
|
||||
formatUsage(context, getString(mDataUsageTemplate), info.usageLevel));
|
||||
final long limit = mDataInfoController.getSummaryLimit(info);
|
||||
mSummaryPreference.setSummary(info.period);
|
||||
if (limit <= 0) {
|
||||
mSummaryPreference.setChartEnabled(false);
|
||||
} else {
|
||||
mSummaryPreference.setChartEnabled(true);
|
||||
mSummaryPreference.setLabels(Formatter.formatFileSize(context, 0),
|
||||
Formatter.formatFileSize(context, limit));
|
||||
mSummaryPreference.setRatios(info.usageLevel / (float) limit, 0,
|
||||
(limit - info.usageLevel) / (float) limit);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
for (int i = 1; i < screen.getPreferenceCount(); i++) {
|
||||
((TemplatePreferenceCategory) screen.getPreference(i)).pushTemplates(services);
|
||||
@@ -323,6 +278,7 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
@Override
|
||||
public void updateDataUsage() {
|
||||
updateState();
|
||||
mSummaryController.updateState(mSummaryPreference);
|
||||
}
|
||||
|
||||
private static class SummaryProvider
|
||||
@@ -341,17 +297,39 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
@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));
|
||||
mActivity.getString(R.string.data_usage_summary_format, formatUsedData()));
|
||||
}
|
||||
}
|
||||
|
||||
private String formatUsedData() {
|
||||
SubscriptionManager subscriptionManager = (SubscriptionManager) mActivity
|
||||
.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
|
||||
int defaultSubId = subscriptionManager.getDefaultSubscriptionId();
|
||||
if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
return formatFallbackData();
|
||||
}
|
||||
SubscriptionPlan dfltPlan = DataUsageSummaryPreferenceController
|
||||
.getPrimaryPlan(subscriptionManager, defaultSubId);
|
||||
if (dfltPlan == null) {
|
||||
return formatFallbackData();
|
||||
}
|
||||
if (DataUsageSummaryPreferenceController.unlimited(dfltPlan.getDataLimitBytes())) {
|
||||
return Formatter.formatFileSize(mActivity, dfltPlan.getDataUsageBytes());
|
||||
} else {
|
||||
return Utils.formatPercentage(dfltPlan.getDataUsageBytes(),
|
||||
dfltPlan.getDataLimitBytes());
|
||||
}
|
||||
}
|
||||
|
||||
private String formatFallbackData() {
|
||||
DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
|
||||
if (info == null) {
|
||||
return Formatter.formatFileSize(mActivity, 0);
|
||||
} else if (info.limitLevel <= 0) {
|
||||
return Formatter.formatFileSize(mActivity, info.usageLevel);
|
||||
} else {
|
||||
return Utils.formatPercentage(info.usageLevel, info.limitLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SummaryPreference;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
import libcore.util.Objects;
|
||||
|
||||
/**
|
||||
* Provides a summary of data usage.
|
||||
*/
|
||||
public class DataUsageSummaryPreference extends SummaryPreference {
|
||||
|
||||
private int mNumPlans;
|
||||
/** The ending time of the billing cycle in milliseconds since epoch. */
|
||||
private long mCycleEndTimeMs;
|
||||
/** The time of the last update in standard milliseconds since the epoch */
|
||||
private long mSnapshotTimeMs;
|
||||
/** Name of carrier, or null if not available */
|
||||
private CharSequence mCarrierName;
|
||||
private String mLimitInfoText;
|
||||
private Intent mLaunchIntent;
|
||||
|
||||
public DataUsageSummaryPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutResource(R.layout.data_usage_summary_preference);
|
||||
}
|
||||
|
||||
public void setLimitInfo(String text) {
|
||||
if (!Objects.equal(text, mLimitInfoText)) {
|
||||
mLimitInfoText = text;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUsageInfo(long cycleEnd, long snapshotTime, CharSequence carrierName,
|
||||
int numPlans, Intent launchIntent) {
|
||||
mCycleEndTimeMs = cycleEnd;
|
||||
mSnapshotTimeMs = snapshotTime;
|
||||
mCarrierName = carrierName;
|
||||
mNumPlans = numPlans;
|
||||
mLaunchIntent = launchIntent;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
TextView usageTitle = (TextView) holder.findViewById(R.id.usage_title);
|
||||
usageTitle.setVisibility(mNumPlans > 1 ? View.VISIBLE : View.GONE);
|
||||
|
||||
TextView cycleTime = (TextView) holder.findViewById(R.id.cycle_left_time);
|
||||
cycleTime.setText(getContext().getString(R.string.cycle_left_time_text,
|
||||
StringUtil.formatElapsedTime(getContext(),
|
||||
mCycleEndTimeMs - System.currentTimeMillis(),false /* withSeconds */)));
|
||||
|
||||
TextView carrierInfo = (TextView) holder.findViewById(R.id.carrier_and_update);
|
||||
setCarrierInfo(carrierInfo, mCarrierName, mSnapshotTimeMs);
|
||||
|
||||
Button launchButton = (Button) holder.findViewById(R.id.launch_mdp_app_button);
|
||||
launchButton.setOnClickListener((view) -> {
|
||||
getContext().sendBroadcast(mLaunchIntent);
|
||||
});
|
||||
if (mLaunchIntent != null) {
|
||||
launchButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
launchButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
TextView limitInfo = (TextView) holder.findViewById(R.id.data_limits);
|
||||
limitInfo.setVisibility(
|
||||
mLimitInfoText == null || mLimitInfoText.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
limitInfo.setText(mLimitInfoText);
|
||||
}
|
||||
|
||||
private void setCarrierInfo(TextView carrierInfo, CharSequence carrierName, long updateAge) {
|
||||
if (mNumPlans > 0 && updateAge >= 0L) {
|
||||
carrierInfo.setVisibility(View.VISIBLE);
|
||||
if (carrierName != null) {
|
||||
carrierInfo.setText(getContext().getString(R.string.carrier_and_update_text,
|
||||
carrierName, StringUtil.formatRelativeTime(
|
||||
getContext(), updateAge, false /* withSeconds */)));
|
||||
} else {
|
||||
carrierInfo.setText(getContext().getString(R.string.no_carrier_update_text,
|
||||
StringUtil.formatRelativeTime(
|
||||
getContext(), updateAge, false /* withSeconds */)));
|
||||
}
|
||||
} else {
|
||||
carrierInfo.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.util.Log;
|
||||
import android.util.RecurrenceRule;
|
||||
|
||||
import com.android.internal.util.CollectionUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This is the controller for the top of the data usage screen that retrieves carrier data from the
|
||||
* new subscriptions framework API if available. The controller reads subscription information from
|
||||
* the framework and falls back to legacy usage data if none are available.
|
||||
*/
|
||||
public class DataUsageSummaryPreferenceController extends BasePreferenceController {
|
||||
|
||||
private static final String TAG = "DataUsageController";
|
||||
private static final String KEY = "status_header";
|
||||
private static final long PETA = 1000000000000000L;
|
||||
private static final float RELATIVE_SIZE_LARGE = 1.25f * 1.25f; // (1/0.8)^2
|
||||
private static final float RELATIVE_SIZE_SMALL = 1.0f / RELATIVE_SIZE_LARGE; // 0.8^2
|
||||
|
||||
private final DataUsageController mDataUsageController;
|
||||
private final DataUsageInfoController mDataInfoController;
|
||||
private final NetworkTemplate mDefaultTemplate;
|
||||
private final NetworkPolicyEditor mPolicyEditor;
|
||||
private final int mDataUsageTemplate;
|
||||
private final boolean mHasMobileData;
|
||||
private final SubscriptionManager mSubscriptionManager;
|
||||
|
||||
/** Name of the carrier, or null if not available */
|
||||
private CharSequence mCarrierName;
|
||||
|
||||
/** The number of registered plans, [0,N] */
|
||||
private int mDataplanCount;
|
||||
|
||||
/** The time of the last update in milliseconds since the epoch, or -1 if unknown */
|
||||
private long mSnapshotTime;
|
||||
|
||||
/**
|
||||
* The size of the first registered plan if one exists or the size of the warning if it is set.
|
||||
* -1 if no information is available.
|
||||
*/
|
||||
private long mDataplanSize;
|
||||
/** The number of bytes used since the start of the cycle. */
|
||||
private long mDataplanUse;
|
||||
/** The starting time of the billing cycle in ms since the epoch */
|
||||
private long mCycleStart;
|
||||
/** The ending time of the billing cycle in ms since the epoch */
|
||||
private long mCycleEnd;
|
||||
|
||||
private Intent mManageSubscriptionIntent;
|
||||
|
||||
public DataUsageSummaryPreferenceController(Context context) {
|
||||
super(context, KEY);
|
||||
|
||||
final int defaultSubId = DataUsageUtils.getDefaultSubscriptionId(context);
|
||||
mDefaultTemplate = DataUsageUtils.getDefaultTemplate(context, defaultSubId);
|
||||
NetworkPolicyManager policyManager = NetworkPolicyManager.from(context);
|
||||
mPolicyEditor = new NetworkPolicyEditor(policyManager);
|
||||
|
||||
mHasMobileData = DataUsageUtils.hasMobileData(context)
|
||||
&& defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
mDataUsageController = new DataUsageController(context);
|
||||
mDataInfoController = new DataUsageInfoController();
|
||||
|
||||
if (mHasMobileData) {
|
||||
mDataUsageTemplate = R.string.cell_data_template;
|
||||
} else if (DataUsageUtils.hasWifiRadio(context)) {
|
||||
mDataUsageTemplate = R.string.wifi_data_template;
|
||||
} else {
|
||||
mDataUsageTemplate = R.string.ethernet_data_template;
|
||||
}
|
||||
|
||||
mSubscriptionManager = (SubscriptionManager)
|
||||
mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DataUsageSummaryPreferenceController(
|
||||
Context context,
|
||||
DataUsageController dataUsageController,
|
||||
DataUsageInfoController dataInfoController,
|
||||
NetworkTemplate defaultTemplate,
|
||||
NetworkPolicyEditor policyEditor,
|
||||
int dataUsageTemplate,
|
||||
boolean hasMobileData,
|
||||
SubscriptionManager subscriptionManager) {
|
||||
super(context, KEY);
|
||||
mDataUsageController = dataUsageController;
|
||||
mDataInfoController = dataInfoController;
|
||||
mDefaultTemplate = defaultTemplate;
|
||||
mPolicyEditor = policyEditor;
|
||||
mDataUsageTemplate = dataUsageTemplate;
|
||||
mHasMobileData = hasMobileData;
|
||||
mSubscriptionManager = subscriptionManager;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPlanValues(int dataPlanCount, long dataPlanSize, long dataPlanUse) {
|
||||
mDataplanCount = dataPlanCount;
|
||||
mDataplanSize = dataPlanSize;
|
||||
mDataplanUse = dataPlanUse;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setCarrierValues(String carrierName, long snapshotTime, long cycleEnd, Intent intent) {
|
||||
mCarrierName = carrierName;
|
||||
mSnapshotTime = snapshotTime;
|
||||
mCycleEnd = cycleEnd;
|
||||
mManageSubscriptionIntent = intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
DataUsageSummaryPreference summaryPreference = (DataUsageSummaryPreference) preference;
|
||||
DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
|
||||
mDefaultTemplate);
|
||||
|
||||
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||
|
||||
if (mSubscriptionManager != null) {
|
||||
refreshDataplanInfo(info);
|
||||
}
|
||||
|
||||
if (mDataplanCount == 0 && (info.warningLevel > 0 || info.limitLevel > 0)) {
|
||||
final String warning = Formatter.formatFileSize(mContext, info.warningLevel);
|
||||
final String limit = Formatter.formatFileSize(mContext, info.limitLevel);
|
||||
summaryPreference.setLimitInfo(mContext.getString(info.limitLevel <= 0
|
||||
? R.string.cell_warning_only
|
||||
: R.string.cell_warning_and_limit, warning, limit));
|
||||
} else {
|
||||
summaryPreference.setLimitInfo(null);
|
||||
}
|
||||
|
||||
final StringBuilder title = new StringBuilder();
|
||||
if (mHasMobileData) {
|
||||
title.append(formatUsage(mContext, mContext.getString(R.string.data_used),
|
||||
mDataplanUse));
|
||||
if (mDataplanCount >= 0 && mDataplanSize > 0L) {
|
||||
title.append(formatUsage(mContext, mContext.getString(R.string.data_remaining),
|
||||
mDataplanSize - mDataplanUse));
|
||||
}
|
||||
} else {
|
||||
title.append(formatUsage(mContext, mContext.getString(mDataUsageTemplate),
|
||||
mDataplanUse));
|
||||
}
|
||||
summaryPreference.setTitle(title.toString());
|
||||
|
||||
if (mDataplanSize <= 0) {
|
||||
summaryPreference.setChartEnabled(false);
|
||||
} else {
|
||||
summaryPreference.setChartEnabled(true);
|
||||
summaryPreference.setLabels(Formatter.formatFileSize(mContext, 0 /* sizeBytes */),
|
||||
Formatter.formatFileSize(mContext, mDataplanSize));
|
||||
summaryPreference.setRatios(mDataplanUse / (float) mDataplanSize, 0 /* middle */,
|
||||
(mDataplanSize - mDataplanUse) / (float) mDataplanSize);
|
||||
}
|
||||
summaryPreference.setUsageInfo(mCycleEnd, mSnapshotTime, mCarrierName,
|
||||
mDataplanCount, mManageSubscriptionIntent);
|
||||
}
|
||||
|
||||
// TODO(b/70950124) add test for this method once the robolectric shadow run script is
|
||||
// completed (b/3526807)
|
||||
private void refreshDataplanInfo(DataUsageController.DataUsageInfo info) {
|
||||
// reset data before overwriting
|
||||
mCarrierName = null;
|
||||
mDataplanCount = 0;
|
||||
mDataplanSize = mDataInfoController.getSummaryLimit(info);
|
||||
mDataplanUse = info.usageLevel;
|
||||
mCycleStart = info.cycleStart;
|
||||
mCycleEnd = info.cycleEnd;
|
||||
mSnapshotTime = -1L;
|
||||
|
||||
final int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
|
||||
final SubscriptionInfo subInfo = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||
if (subInfo != null && mHasMobileData) {
|
||||
mCarrierName = subInfo.getCarrierName();
|
||||
List<SubscriptionPlan> plans = mSubscriptionManager.getSubscriptionPlans(defaultSubId);
|
||||
final SubscriptionPlan primaryPlan = getPrimaryPlan(mSubscriptionManager, defaultSubId);
|
||||
if (primaryPlan != null) {
|
||||
mDataplanCount = plans.size();
|
||||
mDataplanSize = primaryPlan.getDataLimitBytes();
|
||||
if (unlimited(mDataplanSize)) {
|
||||
mDataplanSize = 0L;
|
||||
}
|
||||
mDataplanUse = primaryPlan.getDataUsageBytes();
|
||||
|
||||
RecurrenceRule rule = primaryPlan.getCycleRule();
|
||||
if (rule != null && rule.start != null && rule.end != null) {
|
||||
mCycleStart = rule.start.toEpochSecond() * 1000L;
|
||||
mCycleEnd = rule.end.toEpochSecond() * 1000L;
|
||||
}
|
||||
mSnapshotTime = System.currentTimeMillis() - primaryPlan.getDataUsageTime();
|
||||
}
|
||||
}
|
||||
mManageSubscriptionIntent =
|
||||
mSubscriptionManager.createManageSubscriptionIntent(defaultSubId);
|
||||
Log.i(TAG, "Have " + mDataplanCount + " plans, dflt sub-id " + defaultSubId
|
||||
+ ", intent " + mManageSubscriptionIntent);
|
||||
}
|
||||
|
||||
public static SubscriptionPlan getPrimaryPlan(SubscriptionManager subManager, int primaryId) {
|
||||
List<SubscriptionPlan> plans = subManager.getSubscriptionPlans(primaryId);
|
||||
if (CollectionUtils.isEmpty(plans)) {
|
||||
return null;
|
||||
}
|
||||
// First plan in the list is the primary plan
|
||||
SubscriptionPlan plan = plans.get(0);
|
||||
return plan.getDataLimitBytes() > 0
|
||||
&& saneSize(plan.getDataUsageBytes())
|
||||
&& plan.getCycleRule() != null ? plan : null;
|
||||
}
|
||||
|
||||
private static boolean saneSize(long value) {
|
||||
return value >= 0L && value < PETA;
|
||||
}
|
||||
|
||||
public static boolean unlimited(long size) {
|
||||
return size == SubscriptionPlan.BYTES_UNLIMITED;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
private static CharSequence formatUsage(Context context, String template, long usageLevel) {
|
||||
final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
|
||||
|
||||
final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
|
||||
usageLevel, Formatter.FLAG_CALCULATE_ROUNDED);
|
||||
final SpannableString enlargedValue = new SpannableString(usedResult.value);
|
||||
enlargedValue.setSpan(
|
||||
new RelativeSizeSpan(RELATIVE_SIZE_LARGE), 0, enlargedValue.length(), FLAGS);
|
||||
|
||||
final SpannableString amountTemplate = new SpannableString(
|
||||
context.getString(com.android.internal.R.string.fileSizeSuffix)
|
||||
.replace("%1$s", "^1").replace("%2$s", "^2"));
|
||||
final CharSequence formattedUsage = TextUtils.expandTemplate(amountTemplate,
|
||||
enlargedValue, usedResult.units);
|
||||
|
||||
final SpannableString fullTemplate = new SpannableString(template);
|
||||
fullTemplate.setSpan(
|
||||
new RelativeSizeSpan(RELATIVE_SIZE_SMALL), 0, fullTemplate.length(), FLAGS);
|
||||
return TextUtils.expandTemplate(fullTemplate,
|
||||
BidiFormatter.getInstance().unicodeWrap(formattedUsage.toString()));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user