1 /* <lambda>null2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.datausage.lib 18 19 import android.content.Context 20 import android.net.NetworkPolicy 21 import android.net.NetworkPolicyManager 22 import android.net.NetworkTemplate 23 import android.text.format.DateUtils 24 import android.util.Range 25 import com.android.settingslib.NetworkPolicyEditor 26 27 interface INetworkCycleDataRepository { 28 fun getCycles(): List<Range<Long>> 29 fun getPolicy(): NetworkPolicy? 30 fun queryUsage(range: Range<Long>): NetworkUsageData 31 } 32 33 class NetworkCycleDataRepository( 34 context: Context, 35 private val networkTemplate: NetworkTemplate, 36 private val networkStatsRepository: NetworkStatsRepository = 37 NetworkStatsRepository(context, networkTemplate), 38 ) : INetworkCycleDataRepository { 39 40 private val policyManager = context.getSystemService(NetworkPolicyManager::class.java)!! 41 <lambda>null42 fun loadFirstCycle(): NetworkUsageData? = getCycles().firstOrNull()?.let { queryUsage(it) } 43 getCyclesnull44 override fun getCycles(): List<Range<Long>> = 45 getPolicy()?.getCycles().orEmpty().ifEmpty { queryCyclesAsFourWeeks() } 46 queryCyclesAsFourWeeksnull47 private fun queryCyclesAsFourWeeks(): List<Range<Long>> = 48 networkStatsRepository.getTimeRange().asFourWeeks() 49 50 override fun getPolicy(): NetworkPolicy? = 51 with(NetworkPolicyEditor(policyManager)) { 52 read() 53 getPolicy(networkTemplate) 54 } 55 queryUsagenull56 override fun queryUsage(range: Range<Long>) = NetworkUsageData( 57 startTime = range.lower, 58 endTime = range.upper, 59 usage = networkStatsRepository.querySummaryForDevice(range.lower, range.upper), 60 ) 61 62 companion object { 63 fun NetworkPolicy.getCycles() = cycleIterator().asSequence().map { 64 Range(it.lower.toInstant().toEpochMilli(), it.upper.toInstant().toEpochMilli()) 65 }.toList() 66 67 fun Range<Long>?.asFourWeeks(): List<Range<Long>> { 68 val timeRange = this ?: return emptyList() 69 return reverseBucketRange( 70 startTime = timeRange.lower, 71 endTime = timeRange.upper, 72 step = DateUtils.WEEK_IN_MILLIS * 4, 73 ) 74 } 75 76 fun bucketRange(startTime: Long, endTime: Long, step: Long): List<Range<Long>> = 77 (startTime..endTime step step).zipWithNext(::Range) 78 79 fun reverseBucketRange(startTime: Long, endTime: Long, step: Long): List<Range<Long>> = 80 (endTime downTo (startTime - step + 1) step step) 81 .zipWithNext { bucketEnd, bucketStart -> Range(bucketStart, bucketEnd) } 82 } 83 } 84