/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.datausage import android.content.Context import android.view.View import android.widget.AdapterView import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.preference.PreferenceScreen import com.android.settings.core.BasePreferenceController import com.android.settings.datausage.lib.IAppDataUsageDetailsRepository import com.android.settings.datausage.lib.NetworkUsageDetailsData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class AppDataUsageCycleController(context: Context, preferenceKey: String) : BasePreferenceController(context, preferenceKey) { private lateinit var repository: IAppDataUsageDetailsRepository private var onUsageDataUpdated: (NetworkUsageDetailsData) -> Unit = {} private lateinit var preference: SpinnerPreference private var cycleAdapter: CycleAdapter? = null private var usageDetailsDataList: List = emptyList() override fun getAvailabilityStatus() = AVAILABLE override fun displayPreference(screen: PreferenceScreen) { super.displayPreference(screen) preference = screen.findPreference(preferenceKey)!! if (cycleAdapter == null) { cycleAdapter = CycleAdapter(mContext, preference) } } fun init( repository: IAppDataUsageDetailsRepository, onUsageDataUpdated: (NetworkUsageDetailsData) -> Unit, ) { this.repository = repository this.onUsageDataUpdated = onUsageDataUpdated } /** * Sets the initial cycles. * * If coming from a page like DataUsageList where already has a selected cycle, display that * before loading to reduce flicker. */ fun setInitialCycles(initialCycles: List, initialSelectedEndTime: Long) { if (initialCycles.isNotEmpty()) { cycleAdapter?.setInitialCycleList(initialCycles, initialSelectedEndTime) preference.setHasCycles(true) } } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { update() } } } private suspend fun update() { usageDetailsDataList = withContext(Dispatchers.Default) { repository.queryDetailsForCycles() } if (usageDetailsDataList.isEmpty()) { preference.setHasCycles(false) onUsageDataUpdated(NetworkUsageDetailsData.AllZero) return } preference.setHasCycles(true) cycleAdapter?.updateCycleList(usageDetailsDataList.map { it.range }) preference.setOnItemSelectedListener(cycleListener) } private val cycleListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { usageDetailsDataList.getOrNull(position)?.let(onUsageDataUpdated) } override fun onNothingSelected(parent: AdapterView<*>?) { // ignored } } }