Merge "Optimize DataUsagePreferenceController" into main

This commit is contained in:
Chaohui Wang
2023-10-12 02:58:54 +00:00
committed by Android (Google) Code Review
10 changed files with 103 additions and 98 deletions

View File

@@ -74,7 +74,7 @@ open class ChartDataUsagePreferenceController(context: Context, preferenceKey: S
preference.setTime(startTime, endTime)
lifecycleScope.launch {
val chartData = withContext(Dispatchers.Default) {
repository.querySummary(startTime, endTime)
repository.queryChartData(startTime, endTime)
}
preference.setNetworkCycleData(chartData)
}

View File

@@ -195,8 +195,7 @@ open class DataUsageList : DataUsageBaseFragment(), MobileDataEnabledListener.Cl
lastDisplayedUsageData = usageData
Log.d(TAG, "showing cycle $usageData")
val totalPhrase = DataUsageUtils.formatDataUsage(requireContext(), usageData.usage)
usageAmount.title = getString(R.string.data_used_template, totalPhrase)
usageAmount.title = usageData.getDataUsedString(requireContext())
updateChart(usageData)
updateApps(usageData)

View File

@@ -23,15 +23,13 @@ import android.net.NetworkTemplate
import android.text.format.DateUtils
import android.util.Range
import com.android.settingslib.NetworkPolicyEditor
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import com.android.settingslib.spa.framework.util.asyncMap
interface INetworkCycleDataRepository {
suspend fun loadCycles(): List<NetworkUsageData>
fun getCycles(): List<Range<Long>>
fun getPolicy(): NetworkPolicy?
suspend fun querySummary(startTime: Long, endTime: Long): NetworkCycleChartData?
suspend fun queryChartData(startTime: Long, endTime: Long): NetworkCycleChartData?
}
class NetworkCycleDataRepository(
@@ -46,6 +44,8 @@ class NetworkCycleDataRepository(
override suspend fun loadCycles(): List<NetworkUsageData> =
getCycles().queryUsage().filter { it.usage > 0 }
fun loadFirstCycle(): NetworkUsageData? = getCycles().firstOrNull()?.let { queryUsage(it) }
override fun getCycles(): List<Range<Long>> {
val policy = getPolicy() ?: return queryCyclesAsFourWeeks()
return policy.cycleIterator().asSequence().map {
@@ -68,7 +68,7 @@ class NetworkCycleDataRepository(
getPolicy(networkTemplate)
}
override suspend fun querySummary(startTime: Long, endTime: Long): NetworkCycleChartData? {
override suspend fun queryChartData(startTime: Long, endTime: Long): NetworkCycleChartData? {
val usage = networkStatsRepository.querySummaryForDevice(startTime, endTime)
if (usage > 0L) {
return NetworkCycleChartData(
@@ -83,17 +83,14 @@ class NetworkCycleDataRepository(
return null
}
private suspend fun List<Range<Long>>.queryUsage(): List<NetworkUsageData> = coroutineScope {
map { range ->
async {
NetworkUsageData(
startTime = range.lower,
endTime = range.upper,
usage = networkStatsRepository.querySummaryForDevice(range.lower, range.upper),
)
}
}.awaitAll()
}
private suspend fun List<Range<Long>>.queryUsage(): List<NetworkUsageData> =
asyncMap { queryUsage(it) }
fun queryUsage(range: Range<Long>) = NetworkUsageData(
startTime = range.lower,
endTime = range.upper,
usage = networkStatsRepository.querySummaryForDevice(range.lower, range.upper),
)
private fun bucketRange(startTime: Long, endTime: Long, bucketSize: Long): List<Range<Long>> {
val buckets = mutableListOf<Range<Long>>()

View File

@@ -16,7 +16,11 @@
package com.android.settings.datausage.lib
import android.content.Context
import android.text.format.DateUtils
import android.util.Range
import com.android.settings.R
import com.android.settings.datausage.DataUsageUtils
/**
* Base data structure representing usage data in a period.
@@ -27,6 +31,21 @@ data class NetworkUsageData(
val usage: Long,
) {
val timeRange = Range(startTime, endTime)
fun formatStartDate(context: Context): String =
DateUtils.formatDateTime(context, startTime, DATE_FORMAT)
fun formatDateRange(context: Context): String =
DateUtils.formatDateRange(context, startTime, endTime, DATE_FORMAT)
fun formatUsage(context: Context): CharSequence = DataUsageUtils.formatDataUsage(context, usage)
fun getDataUsedString(context: Context): String =
context.getString(R.string.data_used_template, formatUsage(context))
private companion object {
const val DATE_FORMAT = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_ABBREV_MONTH
}
}
fun List<NetworkUsageData>.aggregate(): NetworkUsageData? = when {

View File

@@ -31,7 +31,8 @@ import androidx.preference.PreferenceScreen
import com.android.settings.R
import com.android.settings.datausage.DataUsageUtils
import com.android.settings.datausage.lib.DataUsageLib
import com.android.settingslib.net.DataUsageController
import com.android.settings.datausage.lib.NetworkCycleDataRepository
import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.AllTimeRange
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -45,9 +46,6 @@ class DataUsagePreferenceController(context: Context, key: String) :
private lateinit var preference: Preference
private var networkTemplate: NetworkTemplate? = null
@VisibleForTesting
var dataUsageControllerFactory: (Context) -> DataUsageController = { DataUsageController(it) }
fun init(subId: Int) {
mSubId = subId
}
@@ -103,25 +101,21 @@ class DataUsagePreferenceController(context: Context, key: String) :
else -> null
}
@VisibleForTesting
fun createNetworkCycleDataRepository(): NetworkCycleDataRepository? =
networkTemplate?.let { NetworkCycleDataRepository(mContext, it) }
private fun getDataUsageSummary(): String? {
val networkTemplate = networkTemplate ?: return null
val controller = dataUsageControllerFactory(mContext).apply {
setSubscriptionId(mSubId)
}
val usageInfo = controller.getDataUsageInfo(networkTemplate)
if (usageInfo != null && usageInfo.usageLevel > 0) {
val repository = createNetworkCycleDataRepository() ?: return null
repository.loadFirstCycle()?.takeIf { it.usage > 0 }?.let { usageData ->
return mContext.getString(
R.string.data_usage_template,
DataUsageUtils.formatDataUsage(mContext, usageInfo.usageLevel),
usageInfo.period,
usageData.formatUsage(mContext),
usageData.formatDateRange(mContext),
)
}
return controller.getHistoricalUsageLevel(networkTemplate).takeIf { it > 0 }?.let {
mContext.getString(
R.string.data_used_template,
DataUsageUtils.formatDataUsage(mContext, it),
)
}
return repository.queryUsage(AllTimeRange).takeIf { it.usage > 0 }
?.getDataUsedString(mContext)
}
}

View File

@@ -19,8 +19,6 @@ package com.android.settings.spa.app.appinfo
import android.content.Context
import android.content.pm.ApplicationInfo
import android.net.NetworkTemplate
import android.text.format.DateUtils
import android.text.format.Formatter
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -114,8 +112,8 @@ private class AppDataUsagePresenter(
} else {
context.getString(
R.string.data_summary_format,
Formatter.formatFileSize(context, appUsageData.usage, Formatter.FLAG_IEC_UNITS),
DateUtils.formatDateTime(context, appUsageData.startTime, DATE_FORMAT),
appUsageData.formatUsage(context),
appUsageData.formatStartDate(context),
)
}
}
@@ -128,8 +126,4 @@ private class AppDataUsagePresenter(
AppInfoSettingsProvider.METRICS_CATEGORY,
)
}
private companion object {
const val DATE_FORMAT = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_ABBREV_MONTH
}
}