| /* |
| * 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<NetworkUsageDetailsData> = 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<Long>, 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 |
| } |
| } |
| } |