1 /* 2 * 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.content.Context 20 import android.view.View 21 import android.widget.AdapterView 22 import androidx.lifecycle.Lifecycle 23 import androidx.lifecycle.LifecycleOwner 24 import androidx.lifecycle.lifecycleScope 25 import androidx.lifecycle.repeatOnLifecycle 26 import androidx.preference.PreferenceScreen 27 import com.android.settings.core.BasePreferenceController 28 import com.android.settings.datausage.lib.IAppDataUsageDetailsRepository 29 import com.android.settings.datausage.lib.NetworkUsageDetailsData 30 import kotlinx.coroutines.Dispatchers 31 import kotlinx.coroutines.launch 32 import kotlinx.coroutines.withContext 33 34 class AppDataUsageCycleController(context: Context, preferenceKey: String) : 35 BasePreferenceController(context, preferenceKey) { 36 37 private lateinit var repository: IAppDataUsageDetailsRepository <lambda>null38 private var onUsageDataUpdated: (NetworkUsageDetailsData) -> Unit = {} 39 private lateinit var preference: SpinnerPreference 40 private var cycleAdapter: CycleAdapter? = null 41 42 private var usageDetailsDataList: List<NetworkUsageDetailsData> = emptyList() 43 getAvailabilityStatusnull44 override fun getAvailabilityStatus() = AVAILABLE 45 46 override fun displayPreference(screen: PreferenceScreen) { 47 super.displayPreference(screen) 48 preference = screen.findPreference(preferenceKey)!! 49 if (cycleAdapter == null) { 50 cycleAdapter = CycleAdapter(mContext, preference) 51 } 52 } 53 initnull54 fun init( 55 repository: IAppDataUsageDetailsRepository, 56 onUsageDataUpdated: (NetworkUsageDetailsData) -> Unit, 57 ) { 58 this.repository = repository 59 this.onUsageDataUpdated = onUsageDataUpdated 60 } 61 62 /** 63 * Sets the initial cycles. 64 * 65 * If coming from a page like DataUsageList where already has a selected cycle, display that 66 * before loading to reduce flicker. 67 */ setInitialCyclesnull68 fun setInitialCycles(initialCycles: List<Long>, initialSelectedEndTime: Long) { 69 if (initialCycles.isNotEmpty()) { 70 cycleAdapter?.setInitialCycleList(initialCycles, initialSelectedEndTime) 71 preference.setHasCycles(true) 72 } 73 } 74 onViewCreatednull75 override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { 76 viewLifecycleOwner.lifecycleScope.launch { 77 viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { 78 update() 79 } 80 } 81 } 82 updatenull83 private suspend fun update() { 84 usageDetailsDataList = withContext(Dispatchers.Default) { 85 repository.queryDetailsForCycles() 86 } 87 if (usageDetailsDataList.isEmpty()) { 88 preference.setHasCycles(false) 89 onUsageDataUpdated(NetworkUsageDetailsData.AllZero) 90 return 91 } 92 93 preference.setHasCycles(true) 94 cycleAdapter?.updateCycleList(usageDetailsDataList.map { it.range }) 95 preference.setOnItemSelectedListener(cycleListener) 96 } 97 98 private val cycleListener = object : AdapterView.OnItemSelectedListener { onItemSelectednull99 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { 100 usageDetailsDataList.getOrNull(position)?.let(onUsageDataUpdated) 101 } 102 onNothingSelectednull103 override fun onNothingSelected(parent: AdapterView<*>?) { 104 // ignored 105 } 106 } 107 } 108