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
18 
19 import android.app.Application
20 import android.net.NetworkTemplate
21 import androidx.lifecycle.AndroidViewModel
22 import androidx.lifecycle.viewModelScope
23 import com.android.settings.datausage.lib.NetworkCycleBucketRepository
24 import com.android.settings.datausage.lib.NetworkStatsRepository
25 import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.Bucket
26 import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.filterTime
27 import com.android.settings.datausage.lib.NetworkUsageData
28 import kotlinx.coroutines.Dispatchers
29 import kotlinx.coroutines.flow.MutableStateFlow
30 import kotlinx.coroutines.flow.SharingStarted
31 import kotlinx.coroutines.flow.combine
32 import kotlinx.coroutines.flow.filterNotNull
33 import kotlinx.coroutines.flow.flowOn
34 import kotlinx.coroutines.flow.map
35 import kotlinx.coroutines.flow.stateIn
36 import kotlinx.coroutines.plus
37 
38 data class SelectedBuckets(
39     val selectedCycle: NetworkUsageData,
40     val buckets: List<Bucket>,
41 )
42 
43 class DataUsageListViewModel(application: Application) : AndroidViewModel(application) {
44     private val scope = viewModelScope + Dispatchers.Default
45 
46     val templateFlow = MutableStateFlow<NetworkTemplate?>(null)
47 
48     private val bucketsFlow = templateFlow.filterNotNull().map { template ->
49         NetworkStatsRepository(getApplication(), template).queryDetailsForDevice()
50     }.stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
51 
52     val cyclesFlow = combine(templateFlow.filterNotNull(), bucketsFlow) { template, buckets ->
53         NetworkCycleBucketRepository(application, template, buckets).loadCycles()
54     }.flowOn(Dispatchers.Default)
55 
56     val selectedCycleFlow = MutableStateFlow<NetworkUsageData?>(null)
57 
58     private val selectedBucketsFlow =
59         combine(selectedCycleFlow.filterNotNull(), bucketsFlow) { selectedCycle, buckets ->
60             SelectedBuckets(
61                 selectedCycle = selectedCycle,
62                 buckets = buckets.filterTime(selectedCycle.startTime, selectedCycle.endTime),
63             )
64         }.flowOn(Dispatchers.Default)
65 
66     val chartDataFlow =
67         combine(templateFlow.filterNotNull(), selectedBucketsFlow) { template, selectedBuckets ->
68             NetworkCycleBucketRepository(application, template, selectedBuckets.buckets)
69                 .queryChartData(selectedBuckets.selectedCycle)
70         }.flowOn(Dispatchers.Default)
71 }
72