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.ActivityManager 20 import android.content.Context 21 import android.net.NetworkTemplate 22 import android.os.Bundle 23 import androidx.annotation.OpenForTesting 24 import androidx.annotation.VisibleForTesting 25 import androidx.lifecycle.LifecycleCoroutineScope 26 import androidx.lifecycle.LifecycleOwner 27 import androidx.lifecycle.lifecycleScope 28 import androidx.preference.PreferenceGroup 29 import androidx.preference.PreferenceScreen 30 import com.android.settings.R 31 import com.android.settings.core.BasePreferenceController 32 import com.android.settings.core.SubSettingLauncher 33 import com.android.settings.datausage.lib.AppDataUsageRepository 34 import com.android.settings.datausage.lib.NetworkUsageData 35 import com.android.settingslib.AppItem 36 import com.android.settingslib.net.UidDetailProvider 37 import kotlinx.coroutines.Dispatchers 38 import kotlinx.coroutines.launch 39 import kotlinx.coroutines.withContext 40 41 @OpenForTesting 42 open class DataUsageListAppsController(context: Context, preferenceKey: String) : 43 BasePreferenceController(context, preferenceKey) { 44 45 private val uidDetailProvider = UidDetailProvider(context) 46 private lateinit var template: NetworkTemplate 47 private lateinit var repository: AppDataUsageRepository 48 private lateinit var preference: PreferenceGroup 49 private lateinit var lifecycleScope: LifecycleCoroutineScope 50 51 private var cycleData: List<NetworkUsageData>? = null 52 53 open fun init(template: NetworkTemplate) { 54 this.template = template 55 repository = AppDataUsageRepository( 56 context = mContext, 57 currentUserId = ActivityManager.getCurrentUser(), 58 template = template, 59 ) { appItem: AppItem -> uidDetailProvider.getUidDetail(appItem.key, true).packageName } 60 } 61 62 override fun getAvailabilityStatus() = AVAILABLE 63 64 override fun displayPreference(screen: PreferenceScreen) { 65 super.displayPreference(screen) 66 preference = screen.findPreference(preferenceKey)!! 67 } 68 69 override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { 70 lifecycleScope = viewLifecycleOwner.lifecycleScope 71 } 72 73 fun updateCycles(cycleData: List<NetworkUsageData>) { 74 this.cycleData = cycleData 75 } 76 77 fun update(carrierId: Int?, startTime: Long, endTime: Long) = lifecycleScope.launch { 78 val apps = withContext(Dispatchers.Default) { 79 repository.getAppPercent(carrierId, startTime, endTime).map { (appItem, percent) -> 80 AppDataUsagePreference(mContext, appItem, percent, uidDetailProvider).apply { 81 setOnPreferenceClickListener { 82 startAppDataUsage(appItem, endTime) 83 true 84 } 85 } 86 } 87 } 88 preference.removeAll() 89 for (app in apps) { 90 preference.addPreference(app) 91 } 92 } 93 94 @VisibleForTesting 95 fun startAppDataUsage(item: AppItem, endTime: Long) { 96 val cycleData = cycleData ?: return 97 val args = Bundle().apply { 98 putParcelable(AppDataUsage.ARG_APP_ITEM, item) 99 putParcelable(AppDataUsage.ARG_NETWORK_TEMPLATE, template) 100 val cycles = ArrayList<Long>().apply { 101 for (data in cycleData) { 102 if (isEmpty()) add(data.endTime) 103 add(data.startTime) 104 } 105 } 106 putSerializable(AppDataUsage.ARG_NETWORK_CYCLES, cycles) 107 putLong(AppDataUsage.ARG_SELECTED_CYCLE, endTime) 108 } 109 SubSettingLauncher(mContext).apply { 110 setDestination(AppDataUsage::class.java.name) 111 setTitleRes(R.string.data_usage_app_summary_title) 112 setArguments(args) 113 setSourceMetricsCategory(metricsCategory) 114 }.launch() 115 } 116 } 117