1 /* <lambda>null2 * Copyright (C) 2017 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 package com.android.settings.applications.specialaccess 17 18 import android.content.Context 19 import android.net.NetworkPolicyManager 20 import android.os.UserHandle 21 import androidx.lifecycle.Lifecycle 22 import androidx.lifecycle.LifecycleOwner 23 import androidx.lifecycle.lifecycleScope 24 import androidx.lifecycle.repeatOnLifecycle 25 import androidx.preference.Preference 26 import androidx.preference.PreferenceScreen 27 import com.android.settings.R 28 import com.android.settings.core.BasePreferenceController 29 import com.android.settingslib.spa.framework.util.formatString 30 import com.android.settingslib.spaprivileged.model.app.AppListRepository 31 import com.android.settingslib.spaprivileged.model.app.AppListRepositoryImpl 32 import com.google.common.annotations.VisibleForTesting 33 import kotlinx.coroutines.Dispatchers 34 import kotlinx.coroutines.async 35 import kotlinx.coroutines.coroutineScope 36 import kotlinx.coroutines.launch 37 import kotlinx.coroutines.withContext 38 39 class DataSaverController(context: Context, key: String) : BasePreferenceController(context, key) { 40 41 private lateinit var preference: Preference 42 43 @AvailabilityStatus 44 override fun getAvailabilityStatus(): Int = when { 45 mContext.resources.getBoolean(R.bool.config_show_data_saver) -> AVAILABLE 46 else -> UNSUPPORTED_ON_DEVICE 47 } 48 49 override fun displayPreference(screen: PreferenceScreen) { 50 super.displayPreference(screen) 51 preference = screen.findPreference(preferenceKey)!! 52 } 53 54 override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { 55 viewLifecycleOwner.lifecycleScope.launch { 56 viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { 57 preference.summary = getUnrestrictedSummary(mContext) 58 } 59 } 60 } 61 62 companion object { 63 @VisibleForTesting 64 suspend fun getUnrestrictedSummary( 65 context: Context, 66 appListRepository: AppListRepository = 67 AppListRepositoryImpl(context.applicationContext), 68 ) = context.formatString( 69 R.string.data_saver_unrestricted_summary, 70 "count" to getAllowCount(context.applicationContext, appListRepository), 71 ) 72 73 private suspend fun getAllowCount(context: Context, appListRepository: AppListRepository) = 74 withContext(Dispatchers.IO) { 75 coroutineScope { 76 val appsDeferred = async { 77 appListRepository.loadAndFilterApps( 78 userId = UserHandle.myUserId(), 79 isSystemApp = false, 80 ) 81 } 82 val uidsAllowed = NetworkPolicyManager.from(context) 83 .getUidsWithPolicy(NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND) 84 appsDeferred.await().count { app -> app.uid in uidsAllowed } 85 } 86 } 87 } 88 }