Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e16afdb7 authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Optimize DataUsagePreferenceController" into main

parents 6402b83e 8603782b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
        }
+1 −2
Original line number Diff line number Diff line
@@ -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)
+13 −16
Original line number Diff line number Diff line
@@ -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(
    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),
    )
            }
        }.awaitAll()
    }

    private fun bucketRange(startTime: Long, endTime: Long, bucketSize: Long): List<Range<Long>> {
        val buckets = mutableListOf<Range<Long>>()
+19 −0
Original line number Diff line number Diff line
@@ -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 {
+12 −18
Original line number Diff line number Diff line
@@ -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)
    }
}
Loading