From 611c62294a0e025370cb582a72f97a94d9ac1478 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Thu, 2 Jan 2025 10:34:30 +0800 Subject: [PATCH 1/3] Use BytesFormatter for data usage Change "480 B" to "480 byte". And no longer use FormattedDataUsage. Bug: 321861088 Flag: EXEMPT bug fix Test: manual - App data usage Test: unit test Change-Id: I9ed220e2d5b8fc512d7d28f6fa7faebb37beab83 --- .../AppDataUsageSummaryController.kt | 12 +++----- .../settings/datausage/DataUsageList.kt | 2 +- .../datausage/lib/DataUsageFormatter.kt | 30 ++----------------- .../datausage/lib/NetworkUsageData.kt | 7 ++--- .../DataUsagePreferenceController.kt | 13 ++++---- .../spa/app/appinfo/AppDataUsagePreference.kt | 2 +- .../AppDataUsageSummaryControllerTest.kt | 14 +++------ .../datausage/lib/DataUsageFormatterTest.kt | 12 +++----- .../DataUsagePreferenceControllerTest.kt | 4 +-- 9 files changed, 30 insertions(+), 66 deletions(-) diff --git a/src/com/android/settings/datausage/AppDataUsageSummaryController.kt b/src/com/android/settings/datausage/AppDataUsageSummaryController.kt index fb7101dba9b..1cab87f42bf 100644 --- a/src/com/android/settings/datausage/AppDataUsageSummaryController.kt +++ b/src/com/android/settings/datausage/AppDataUsageSummaryController.kt @@ -37,8 +37,7 @@ class AppDataUsageSummaryController(context: Context, preferenceKey: String) : private val dataFlow = MutableStateFlow(NetworkUsageDetailsData.AllZero) private val dataUsageFormatter = DataUsageFormatter(context) - private val emptyDataUsage = - DataUsageFormatter.FormattedDataUsage(context.getPlaceholder(), context.getPlaceholder()) + private val emptyDataUsage = context.getPlaceholder() private val totalUsageFlow = dataFlow.map { dataUsageFormatter.formatDataUsage(it.totalUsage) @@ -66,18 +65,15 @@ class AppDataUsageSummaryController(context: Context, preferenceKey: String) : val backgroundUsage by backgroundUsageFlow.collectAsStateWithLifecycle(emptyDataUsage) Preference(object : PreferenceModel { override val title = stringResource(R.string.total_size_label) - override val summary = { totalUsage.displayText } - override val summaryContentDescription = { totalUsage.contentDescription } + override val summary = { totalUsage } }) Preference(object : PreferenceModel { override val title = stringResource(R.string.data_usage_label_foreground) - override val summary = { foregroundUsage.displayText } - override val summaryContentDescription = { foregroundUsage.contentDescription } + override val summary = { foregroundUsage } }) Preference(object : PreferenceModel { override val title = stringResource(R.string.data_usage_label_background) - override val summary = { backgroundUsage.displayText } - override val summaryContentDescription = { backgroundUsage.contentDescription } + override val summary = { backgroundUsage } }) } } diff --git a/src/com/android/settings/datausage/DataUsageList.kt b/src/com/android/settings/datausage/DataUsageList.kt index a2932776669..8636c56de69 100644 --- a/src/com/android/settings/datausage/DataUsageList.kt +++ b/src/com/android/settings/datausage/DataUsageList.kt @@ -172,7 +172,7 @@ open class DataUsageList : DashboardFragment() { private fun updateSelectedCycle(usageData: NetworkUsageData) { Log.d(TAG, "showing cycle $usageData") - usageAmount?.title = usageData.getDataUsedString(requireContext()).displayText + usageAmount?.title = usageData.getDataUsedString(requireContext()) viewModel.selectedCycleFlow.value = usageData updateApps(usageData) diff --git a/src/com/android/settings/datausage/lib/DataUsageFormatter.kt b/src/com/android/settings/datausage/lib/DataUsageFormatter.kt index 0a4c06b264b..849ff0dc89c 100644 --- a/src/com/android/settings/datausage/lib/DataUsageFormatter.kt +++ b/src/com/android/settings/datausage/lib/DataUsageFormatter.kt @@ -16,40 +16,16 @@ package com.android.settings.datausage.lib -import android.annotation.StringRes import android.content.Context import android.content.res.Resources -import android.icu.text.UnicodeSet -import android.icu.text.UnicodeSetSpanner -import android.text.BidiFormatter import android.text.format.Formatter -import com.android.internal.R +import com.android.settingslib.spaprivileged.framework.common.BytesFormatter class DataUsageFormatter(private val context: Context) { - data class FormattedDataUsage( - val displayText: String, - val contentDescription: String, - ) { - fun format(context: Context, @StringRes resId: Int, vararg formatArgs: Any?) = - FormattedDataUsage( - displayText = context.getString(resId, displayText, *formatArgs), - contentDescription = context.getString(resId, contentDescription, *formatArgs), - ) - } - /** Formats the data usage. */ - fun formatDataUsage(sizeBytes: Long): FormattedDataUsage { - val result = Formatter.formatBytes(context.resources, sizeBytes, Formatter.FLAG_IEC_UNITS) - return FormattedDataUsage( - displayText = BidiFormatter.getInstance().unicodeWrap( - context.getString(R.string.fileSizeSuffix, result.value, result.units) - ), - contentDescription = context.getString( - R.string.fileSizeSuffix, result.value, result.unitsContentDescription - ), - ) - } + fun formatDataUsage(sizeBytes: Long): String = + BytesFormatter(context).format(sizeBytes, BytesFormatter.UseCase.DataUsage) companion object { /** diff --git a/src/com/android/settings/datausage/lib/NetworkUsageData.kt b/src/com/android/settings/datausage/lib/NetworkUsageData.kt index 26578e325b4..0c34edf1059 100644 --- a/src/com/android/settings/datausage/lib/NetworkUsageData.kt +++ b/src/com/android/settings/datausage/lib/NetworkUsageData.kt @@ -20,7 +20,6 @@ import android.content.Context import android.text.format.DateUtils import android.util.Range import com.android.settings.R -import com.android.settings.datausage.lib.DataUsageFormatter.FormattedDataUsage /** * Base data structure representing usage data in a period. @@ -38,11 +37,11 @@ data class NetworkUsageData( fun formatDateRange(context: Context): String = DateUtils.formatDateRange(context, startTime, endTime, DATE_FORMAT) - fun formatUsage(context: Context): FormattedDataUsage = + fun formatUsage(context: Context): String = DataUsageFormatter(context).formatDataUsage(usage) - fun getDataUsedString(context: Context): FormattedDataUsage = - formatUsage(context).format(context, R.string.data_used_template) + fun getDataUsedString(context: Context): String = + context.getString(R.string.data_used_template, formatUsage(context)) companion object { val AllZero = NetworkUsageData( diff --git a/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt b/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt index aa113b692dc..2d8c0f77024 100644 --- a/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt +++ b/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt @@ -31,7 +31,6 @@ import androidx.preference.PreferenceScreen import com.android.settings.R import com.android.settings.core.BasePreferenceController import com.android.settings.datausage.DataUsageUtils -import com.android.settings.datausage.lib.DataUsageFormatter.FormattedDataUsage import com.android.settings.datausage.lib.DataUsageLib import com.android.settings.datausage.lib.NetworkCycleDataRepository import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.AllTimeRange @@ -88,7 +87,7 @@ class DataUsagePreferenceController(context: Context, key: String) : getDataUsageSummaryAndEnabled() } preference.isEnabled = enabled - preference.summary = summary?.displayText + preference.summary = summary } private fun getNetworkTemplate(): NetworkTemplate? = @@ -100,12 +99,16 @@ class DataUsagePreferenceController(context: Context, key: String) : fun createNetworkCycleDataRepository(): NetworkCycleDataRepository? = networkTemplate?.let { NetworkCycleDataRepository(mContext, it) } - private fun getDataUsageSummaryAndEnabled(): Pair { + private fun getDataUsageSummaryAndEnabled(): Pair { val repository = createNetworkCycleDataRepository() ?: return null to false repository.loadFirstCycle()?.let { usageData -> - val formattedDataUsage = usageData.formatUsage(mContext) - .format(mContext, R.string.data_usage_template, usageData.formatDateRange(mContext)) + val formattedDataUsage = + mContext.getString( + R.string.data_usage_template, + usageData.formatUsage(mContext), + usageData.formatDateRange(mContext), + ) val hasUsage = usageData.usage > 0 || repository.queryUsage(AllTimeRange).usage > 0 return formattedDataUsage to hasUsage } diff --git a/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt b/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt index 7b8cf8c8b55..7e6e72613b7 100644 --- a/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt +++ b/src/com/android/settings/spa/app/appinfo/AppDataUsagePreference.kt @@ -113,7 +113,7 @@ private class AppDataUsagePresenter( } else { context.getString( R.string.data_summary_format, - appUsageData.formatUsage(context).displayText, + appUsageData.formatUsage(context), appUsageData.formatStartDate(context), ) } diff --git a/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt b/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt index be839dd416f..9323a4a7759 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/AppDataUsageSummaryControllerTest.kt @@ -56,13 +56,10 @@ class AppDataUsageSummaryControllerTest { composeTestRule.onNode(hasTextExactly("Total", "6.75 kB")).assertIsDisplayed() composeTestRule.onNode(hasTextExactly("Foreground", "5.54 kB")).assertIsDisplayed() composeTestRule.onNode(hasTextExactly("Background", "1.21 kB")).assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("6.75 kB").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("5.54 kB").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("1.21 kB").assertIsDisplayed() } @Test - fun summary_zero() { + fun summary_smallByte() { val appUsage = NetworkUsageDetailsData( range = Range(1L, 2L), totalUsage = 3, @@ -75,12 +72,9 @@ class AppDataUsageSummaryControllerTest { controller.Content() } - composeTestRule.onNode(hasTextExactly("Total", "3 B")).assertIsDisplayed() - composeTestRule.onNode(hasTextExactly("Foreground", "1 B")).assertIsDisplayed() - composeTestRule.onNode(hasTextExactly("Background", "2 B")).assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("3 byte").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("1 byte").assertIsDisplayed() - composeTestRule.onNodeWithContentDescription("2 byte").assertIsDisplayed() + composeTestRule.onNode(hasTextExactly("Total", "3 byte")).assertIsDisplayed() + composeTestRule.onNode(hasTextExactly("Foreground", "1 byte")).assertIsDisplayed() + composeTestRule.onNode(hasTextExactly("Background", "2 byte")).assertIsDisplayed() } private companion object { diff --git a/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt b/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt index 071234dcd65..97a6c0f7fd2 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/lib/DataUsageFormatterTest.kt @@ -21,7 +21,6 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.datausage.lib.DataUsageFormatter.Companion.getBytesDisplayUnit import com.google.common.truth.Truth.assertThat - import org.junit.Test import org.junit.runner.RunWith @@ -33,26 +32,23 @@ class DataUsageFormatterTest { @Test fun formatDataUsage_0() { - val (displayText, contentDescription) = dataUsageFormatter.formatDataUsage(0) + val displayText = dataUsageFormatter.formatDataUsage(0) - assertThat(displayText).isEqualTo("0 B") - assertThat(contentDescription).isEqualTo("0 byte") + assertThat(displayText).isEqualTo("0 byte") } @Test fun formatDataUsage_1000() { - val (displayText, contentDescription) = dataUsageFormatter.formatDataUsage(1000) + val displayText = dataUsageFormatter.formatDataUsage(1000) assertThat(displayText).isEqualTo("0.98 kB") - assertThat(contentDescription).isEqualTo("0.98 kB") } @Test fun formatDataUsage_2000000() { - val (displayText, contentDescription) = dataUsageFormatter.formatDataUsage(2000000) + val displayText = dataUsageFormatter.formatDataUsage(2000000) assertThat(displayText).isEqualTo("1.91 MB") - assertThat(contentDescription).isEqualTo("1.91 MB") } @Test diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt index f4974e9cd8e..f16c9fae017 100644 --- a/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt @@ -143,7 +143,7 @@ class DataUsagePreferenceControllerTest { controller.onViewCreated(TestLifecycleOwner()) waitUntil { preference.isEnabled } - waitUntil { preference.summary?.contains("0 B used") == true } + waitUntil { preference.summary?.contains("0 byte used") == true } } @Test @@ -159,7 +159,7 @@ class DataUsagePreferenceControllerTest { controller.onViewCreated(TestLifecycleOwner()) waitUntil { !preference.isEnabled } - waitUntil { preference.summary?.contains("0 B used") == true } + waitUntil { preference.summary?.contains("0 byte used") == true } } @Test From 2fdbe30929dbb3b3a9cba76cfad978156f376f5a Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Thu, 2 Jan 2025 12:54:47 +0800 Subject: [PATCH 2/3] Clean up unused DataUsageSummary.formatUsage Bug: 321861088 Flag: EXEMPT bug fix Test: atest DataUsageSummaryTest Change-Id: Idea8401a81d738272a8f7b23d22c1fbd3feb6903 --- .../settings/datausage/DataUsageSummary.java | 33 ------------------- .../datausage/DataUsageSummaryTest.java | 11 ------- 2 files changed, 44 deletions(-) diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java index dfb35084a12..558730cf78f 100644 --- a/src/com/android/settings/datausage/DataUsageSummary.java +++ b/src/com/android/settings/datausage/DataUsageSummary.java @@ -22,12 +22,7 @@ import android.os.Bundle; import android.os.UserManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; -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.EventLog; import android.util.Log; @@ -211,34 +206,6 @@ public class DataUsageSummary extends DashboardFragment { updateState(); } - @VisibleForTesting - static CharSequence formatUsage(Context context, String template, long usageLevel) { - final float LARGER_SIZE = 1.25f * 1.25f; // (1/0.8)^2 - final float SMALLER_SIZE = 1.0f / LARGER_SIZE; // 0.8^2 - return formatUsage(context, template, usageLevel, LARGER_SIZE, SMALLER_SIZE); - } - - static CharSequence formatUsage(Context context, String template, long usageLevel, - float larger, float smaller) { - final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE; - - final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(), - usageLevel, Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS); - final SpannableString enlargedValue = new SpannableString(usedResult.value); - enlargedValue.setSpan(new RelativeSizeSpan(larger), 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(smaller), 0, fullTemplate.length(), FLAGS); - return TextUtils.expandTemplate(fullTemplate, - BidiFormatter.getInstance().unicodeWrap(formattedUsage.toString())); - } - private void updateState() { PreferenceScreen screen = getPreferenceScreen(); for (int i = 1; i < screen.getPreferenceCount(); i++) { diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index 2a9cca9c669..54e4554802b 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -16,8 +16,6 @@ package com.android.settings.datausage; -import static com.google.common.truth.Truth.assertThat; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -92,15 +90,6 @@ public class DataUsageSummaryTest { doNothing().when(mDataUsageSummary).addWifiSection(); } - @Test - public void formatUsage_shouldLookLikeFormatFileSize() { - final long usage = 2147483648L; // 2GB - final String formattedUsage = - DataUsageSummary.formatUsage(mContext, "^1", usage).toString(); - final CharSequence formattedInIECUnit = DataUsageUtils.formatDataUsage(mContext, usage); - assertThat(formattedUsage).isEqualTo(formattedInIECUnit); - } - @Test @Config(shadows = ShadowSubscriptionManager.class) public void configuration_withSim_shouldShowMobileAndWifi() { From d3448f3a91b557df4415b6fad7e469c18b626f37 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Thu, 2 Jan 2025 06:32:26 -0800 Subject: [PATCH 3/3] Migrate all data usage format use case Now they are all aligned. Bug: 321861088 Flag: EXEMPT bug fix Test: unit test Change-Id: I1981fd32fd24de7c9eff93e0cd638e862f01b9b9 --- .../datausage/AppDataUsagePreference.java | 3 ++- .../datausage/BillingCycleSettings.java | 5 +++-- .../datausage/ChartDataUsagePreference.java | 9 +++++---- .../datausage/DataUsagePreference.java | 4 +++- .../datausage/DataUsageSummaryPreference.java | 18 ++++++++++-------- .../DataUsageSummaryPreferenceController.kt | 15 +++++++++------ .../settings/datausage/DataUsageUtils.java | 16 ---------------- .../datausage/lib/DataUsageFormatter.kt | 12 ++++++++---- .../settings/datausage/DataUsageUtilsTest.java | 9 --------- ...DataUsageSummaryPreferenceControllerTest.kt | 12 ++++++------ .../app/appinfo/AppDataUsagePreferenceTest.kt | 2 +- 11 files changed, 47 insertions(+), 58 deletions(-) diff --git a/src/com/android/settings/datausage/AppDataUsagePreference.java b/src/com/android/settings/datausage/AppDataUsagePreference.java index 277c9b3fe7e..2d5c76ac777 100644 --- a/src/com/android/settings/datausage/AppDataUsagePreference.java +++ b/src/com/android/settings/datausage/AppDataUsagePreference.java @@ -21,6 +21,7 @@ import android.widget.ProgressBar; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settingslib.AppItem; import com.android.settingslib.net.UidDetail; import com.android.settingslib.net.UidDetailProvider; @@ -46,7 +47,7 @@ public class AppDataUsagePreference extends AppPreference { if (item.restricted && item.total <= 0) { setSummary(com.android.settings.R.string.data_usage_app_restricted); } else { - setSummary(DataUsageUtils.formatDataUsage(context, item.total)); + setSummary(new DataUsageFormatter(context).formatDataUsage(item.total)); } mDetail = provider.getUidDetail(item.key, false /* blocking */); if (mDetail != null) { diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java index 69577a85574..3f240e65c09 100644 --- a/src/com/android/settings/datausage/BillingCycleSettings.java +++ b/src/com/android/settings/datausage/BillingCycleSettings.java @@ -152,8 +152,9 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements void updatePrefs() { mBillingCycle.setSummary(null); final long warningBytes = services.mPolicyEditor.getPolicyWarningBytes(mNetworkTemplate); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(requireContext()); if (warningBytes != WARNING_DISABLED) { - mDataWarning.setSummary(DataUsageUtils.formatDataUsage(getContext(), warningBytes)); + mDataWarning.setSummary(dataUsageFormatter.formatDataUsage(warningBytes)); mDataWarning.setEnabled(true); mEnableDataWarning.setChecked(true); } else { @@ -163,7 +164,7 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements } final long limitBytes = services.mPolicyEditor.getPolicyLimitBytes(mNetworkTemplate); if (limitBytes != LIMIT_DISABLED) { - mDataLimit.setSummary(DataUsageUtils.formatDataUsage(getContext(), limitBytes)); + mDataLimit.setSummary(dataUsageFormatter.formatDataUsage(limitBytes)); mDataLimit.setEnabled(true); mEnableDataLimit.setChecked(true); } else { diff --git a/src/com/android/settings/datausage/ChartDataUsagePreference.java b/src/com/android/settings/datausage/ChartDataUsagePreference.java index 0c7db715813..6a79b7a6fe9 100644 --- a/src/com/android/settings/datausage/ChartDataUsagePreference.java +++ b/src/com/android/settings/datausage/ChartDataUsagePreference.java @@ -20,7 +20,6 @@ import android.net.NetworkPolicy; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.format.DateUtils; -import android.text.format.Formatter; import android.text.style.ForegroundColorSpan; import android.util.AttributeSet; import android.util.DataUnit; @@ -34,9 +33,11 @@ import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settings.Utils; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settings.datausage.lib.NetworkCycleChartData; import com.android.settings.datausage.lib.NetworkUsageData; import com.android.settings.widget.UsageView; +import com.android.settingslib.spaprivileged.framework.common.BytesFormatter; import java.util.ArrayList; import java.util.Comparator; @@ -279,10 +280,10 @@ public class ChartDataUsagePreference extends Preference { } private CharSequence getLabel(long bytes, int str, int mLimitColor) { - Formatter.BytesResult result = Formatter.formatBytes(mResources, bytes, - Formatter.FLAG_SHORTER | Formatter.FLAG_IEC_UNITS); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(getContext()); + BytesFormatter.Result result = dataUsageFormatter.formatDataUsageWithUnits(bytes); CharSequence label = TextUtils.expandTemplate(getContext().getText(str), - result.value, result.units); + result.getNumber(), result.getUnits()); return new SpannableStringBuilder().append(label, new ForegroundColorSpan(mLimitColor), 0); } diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java index 07368c728eb..010df148a9f 100644 --- a/src/com/android/settings/datausage/DataUsagePreference.java +++ b/src/com/android/settings/datausage/DataUsagePreference.java @@ -28,6 +28,7 @@ import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settingslib.net.DataUsageController; public class DataUsagePreference extends Preference implements TemplatePreference { @@ -58,8 +59,9 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc final DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate); setTitle(mTitleRes); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(getContext()); setSummary(getContext().getString(R.string.data_usage_template, - DataUsageUtils.formatDataUsage(getContext(), usageInfo.usageLevel), + dataUsageFormatter.formatDataUsage(usageInfo.usageLevel), usageInfo.period)); } final long usageLevel = controller.getHistoricalUsageLevel(template); diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java index 6500501b210..92c9163ddc0 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java +++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java @@ -24,7 +24,6 @@ import android.telephony.SubscriptionPlan; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; -import android.text.format.Formatter; import android.text.style.AbsoluteSizeSpan; import android.util.AttributeSet; import android.view.View; @@ -39,7 +38,9 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; +import com.android.settings.datausage.lib.DataUsageFormatter; import com.android.settingslib.Utils; +import com.android.settingslib.spaprivileged.framework.common.BytesFormatter; import com.android.settingslib.utils.StringUtil; import java.util.HashMap; @@ -165,11 +166,12 @@ public class DataUsageSummaryPreference extends Preference { } private void updateDataUsageLabels(PreferenceViewHolder holder) { - TextView usageNumberField = getDataUsed(holder); + DataUsageFormatter dataUsageFormatter = new DataUsageFormatter(getContext()); - final Formatter.BytesResult usedResult = Formatter.formatBytes(getContext().getResources(), - mDataplanUse, Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS); - final SpannableString usageNumberText = new SpannableString(usedResult.value); + TextView usageNumberField = getDataUsed(holder); + final BytesFormatter.Result usedResult = + dataUsageFormatter.formatDataUsageWithUnits(mDataplanUse); + final SpannableString usageNumberText = new SpannableString(usedResult.getNumber()); final int textSize = getContext().getResources().getDimensionPixelSize(R.dimen.usage_number_text_size); usageNumberText.setSpan(new AbsoluteSizeSpan(textSize), 0, usageNumberText.length(), @@ -177,7 +179,7 @@ public class DataUsageSummaryPreference extends Preference { CharSequence template = getContext().getText(R.string.data_used_formatted); CharSequence usageText = - TextUtils.expandTemplate(template, usageNumberText, usedResult.units); + TextUtils.expandTemplate(template, usageNumberText, usedResult.getUnits()); usageNumberField.setText(usageText); final MeasurableLinearLayout layout = getLayout(holder); @@ -188,13 +190,13 @@ public class DataUsageSummaryPreference extends Preference { if (dataRemaining >= 0) { usageRemainingField.setText( TextUtils.expandTemplate(getContext().getText(R.string.data_remaining), - DataUsageUtils.formatDataUsage(getContext(), dataRemaining))); + dataUsageFormatter.formatDataUsage(dataRemaining))); usageRemainingField.setTextColor( Utils.getColorAttr(getContext(), android.R.attr.colorAccent)); } else { usageRemainingField.setText( TextUtils.expandTemplate(getContext().getText(R.string.data_overusage), - DataUsageUtils.formatDataUsage(getContext(), -dataRemaining))); + dataUsageFormatter.formatDataUsage(-dataRemaining))); usageRemainingField.setTextColor( Utils.getColorAttr(getContext(), android.R.attr.colorError)); } diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt index 6f62c300a84..7a696965109 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt +++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.kt @@ -24,6 +24,7 @@ import android.util.Log import androidx.lifecycle.LifecycleOwner import androidx.preference.PreferenceScreen import com.android.settings.R +import com.android.settings.datausage.lib.DataUsageFormatter import com.android.settings.datausage.lib.DataUsageLib.getMobileTemplate import com.android.settings.datausage.lib.INetworkCycleDataRepository import com.android.settings.datausage.lib.NetworkCycleDataRepository @@ -72,6 +73,8 @@ open class DataUsageSummaryPreferenceController @JvmOverloads constructor( private lateinit var preference: DataUsageSummaryPreference + private val dataUsageFormatter = DataUsageFormatter(mContext) + override fun getAvailabilityStatus(subId: Int) = if (subInfo != null) AVAILABLE else CONDITIONALLY_UNAVAILABLE @@ -120,8 +123,8 @@ open class DataUsageSummaryPreferenceController @JvmOverloads constructor( private fun setDataBarSize(dataBarSize: Long) { preference.setLabels( - DataUsageUtils.formatDataUsage(mContext, /* byteValue = */ 0), - DataUsageUtils.formatDataUsage(mContext, dataBarSize) + dataUsageFormatter.formatDataUsage(/* byteValue = */ 0), + dataUsageFormatter.formatDataUsage(dataBarSize) ) } @@ -129,22 +132,22 @@ open class DataUsageSummaryPreferenceController @JvmOverloads constructor( warningBytes > 0 && limitBytes > 0 -> { TextUtils.expandTemplate( mContext.getText(R.string.cell_data_warning_and_limit), - DataUsageUtils.formatDataUsage(mContext, warningBytes), - DataUsageUtils.formatDataUsage(mContext, limitBytes), + dataUsageFormatter.formatDataUsage(warningBytes), + dataUsageFormatter.formatDataUsage(limitBytes), ) } warningBytes > 0 -> { TextUtils.expandTemplate( mContext.getText(R.string.cell_data_warning), - DataUsageUtils.formatDataUsage(mContext, warningBytes), + dataUsageFormatter.formatDataUsage(warningBytes), ) } limitBytes > 0 -> { TextUtils.expandTemplate( mContext.getText(R.string.cell_data_limit), - DataUsageUtils.formatDataUsage(mContext, limitBytes), + dataUsageFormatter.formatDataUsage(limitBytes), ) } diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java index b73da1c3ada..e32741d037b 100644 --- a/src/com/android/settings/datausage/DataUsageUtils.java +++ b/src/com/android/settings/datausage/DataUsageUtils.java @@ -31,9 +31,6 @@ import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.text.BidiFormatter; -import android.text.format.Formatter; -import android.text.format.Formatter.BytesResult; import android.util.Log; import com.android.settings.datausage.lib.DataUsageLib; @@ -54,19 +51,6 @@ public final class DataUsageUtils { private DataUsageUtils() { } - /** - * Format byte value to readable string using IEC units. - * - * @deprecated Use {@link com.android.settings.datausage.lib.DataUsageFormatter} instead. - */ - @Deprecated - public static CharSequence formatDataUsage(Context context, long byteValue) { - final BytesResult res = Formatter.formatBytes(context.getResources(), byteValue, - Formatter.FLAG_IEC_UNITS); - return BidiFormatter.getInstance().unicodeWrap(context.getString( - com.android.internal.R.string.fileSizeSuffix, res.value, res.units)); - } - /** * Test if device has an ethernet network connection. */ diff --git a/src/com/android/settings/datausage/lib/DataUsageFormatter.kt b/src/com/android/settings/datausage/lib/DataUsageFormatter.kt index 849ff0dc89c..271be94c97d 100644 --- a/src/com/android/settings/datausage/lib/DataUsageFormatter.kt +++ b/src/com/android/settings/datausage/lib/DataUsageFormatter.kt @@ -18,14 +18,18 @@ package com.android.settings.datausage.lib import android.content.Context import android.content.res.Resources -import android.text.format.Formatter import com.android.settingslib.spaprivileged.framework.common.BytesFormatter -class DataUsageFormatter(private val context: Context) { +class DataUsageFormatter(context: Context) { + + private val bytesFormatter = BytesFormatter(context) /** Formats the data usage. */ fun formatDataUsage(sizeBytes: Long): String = - BytesFormatter(context).format(sizeBytes, BytesFormatter.UseCase.DataUsage) + bytesFormatter.format(sizeBytes, BytesFormatter.UseCase.DataUsage) + + fun formatDataUsageWithUnits(sizeBytes: Long): BytesFormatter.Result = + bytesFormatter.formatWithUnits(sizeBytes, BytesFormatter.UseCase.DataUsage) companion object { /** @@ -35,6 +39,6 @@ class DataUsageFormatter(private val context: Context) { * in Settings, and align with other places in Settings. */ fun Resources.getBytesDisplayUnit(bytes: Long): String = - Formatter.formatBytes(this, bytes, Formatter.FLAG_IEC_UNITS).units + BytesFormatter(this).formatWithUnits(bytes, BytesFormatter.UseCase.DataUsage).units } } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java index a465d742356..f78bb472805 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java @@ -29,7 +29,6 @@ import android.content.Context; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.telephony.TelephonyManager; -import android.util.DataUnit; import org.junit.Before; import org.junit.Test; @@ -74,14 +73,6 @@ public final class DataUsageUtilsTest { assertThat(hasMobileData).isFalse(); } - @Test - public void formatDataUsage_useIECUnit() { - final CharSequence formattedDataUsage = DataUsageUtils.formatDataUsage( - mContext, DataUnit.GIBIBYTES.toBytes(1)); - - assertThat(formattedDataUsage).isEqualTo("1.00 GB"); - } - @Test public void hasEthernet_shouldQueryEthernetSummaryForUser() throws Exception { ShadowPackageManager pm = shadowOf(RuntimeEnvironment.application.getPackageManager()); diff --git a/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt index 35a1a235bbe..afc196d8a6e 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.kt @@ -182,8 +182,8 @@ class DataUsageSummaryPreferenceControllerTest { val limitInfo = argumentCaptor { verify(preference).setLimitInfo(capture()) }.firstValue.toString() - assertThat(limitInfo).isEqualTo("1 B data warning") - verify(preference).setLabels("0 B", "1 B") + assertThat(limitInfo).isEqualTo("1 byte data warning") + verify(preference).setLabels("0 byte", "1 byte") } @Test @@ -200,8 +200,8 @@ class DataUsageSummaryPreferenceControllerTest { val limitInfo = argumentCaptor { verify(preference).setLimitInfo(capture()) }.firstValue.toString() - assertThat(limitInfo).isEqualTo("1 B data limit") - verify(preference).setLabels("0 B", "1 B") + assertThat(limitInfo).isEqualTo("1 byte data limit") + verify(preference).setLabels("0 byte", "1 byte") } @Test @@ -219,7 +219,7 @@ class DataUsageSummaryPreferenceControllerTest { verify(preference).setLimitInfo(capture()) }.firstValue.toString() assertThat(limitInfo).isEqualTo("512 MB data warning / 1.00 GB data limit") - verify(preference).setLabels("0 B", "1.00 GB") + verify(preference).setLabels("0 byte", "1.00 GB") } @Test @@ -256,7 +256,7 @@ class DataUsageSummaryPreferenceControllerTest { POSITIVE_DATA_PLAN_INFO.dataPlanSize, ) verify(preference).setChartEnabled(true) - verify(preference).setLabels("0 B", "9 B") + verify(preference).setLabels("0 byte", "9 byte") val progress = argumentCaptor { verify(preference).setProgress(capture()) }.firstValue diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt index f70f5d5ad63..d493b66737d 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppDataUsagePreferenceTest.kt @@ -134,7 +134,7 @@ class AppDataUsagePreferenceTest { setContent() - composeTestRule.waitUntilExists(hasText("123 B used since Oct 25, 2022")) + composeTestRule.waitUntilExists(hasText("123 byte used since Oct 25, 2022")) } @Test