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 package com.android.settings.network.telephony 17 18 import android.util.Log 19 import androidx.lifecycle.Lifecycle 20 import androidx.lifecycle.coroutineScope 21 import com.android.settings.core.BasePreferenceController 22 import com.android.settingslib.core.AbstractPreferenceController 23 import com.google.common.collect.Sets 24 import kotlinx.coroutines.Dispatchers 25 import kotlinx.coroutines.Job 26 import kotlinx.coroutines.launch 27 import kotlinx.coroutines.yield 28 29 /** 30 * Session for controlling the status of TelephonyPreferenceController(s). 31 * 32 * Within this session, result of [BasePreferenceController.getAvailabilityStatus] 33 * would be under control. 34 */ 35 class TelephonyStatusControlSession( 36 private val controllers: Collection<AbstractPreferenceController>, 37 lifecycle: Lifecycle, 38 ) : AutoCloseable { 39 private var job: Job? = null 40 private val controllerSet = Sets.newConcurrentHashSet<TelephonyAvailabilityHandler>() 41 42 init { <lambda>null43 job = lifecycle.coroutineScope.launch(Dispatchers.Default) { 44 for (controller in controllers) { 45 launch { 46 setupAvailabilityStatus(controller) 47 } 48 } 49 } 50 } 51 52 /** 53 * Close the session. 54 * 55 * No longer control the status. 56 */ closenull57 override fun close() { 58 job?.cancel() 59 unsetAvailabilityStatus() 60 } 61 setupAvailabilityStatusnull62 private suspend fun setupAvailabilityStatus(controller: AbstractPreferenceController): Boolean = 63 try { 64 if (controller is TelephonyAvailabilityHandler) { 65 val status = (controller as BasePreferenceController).availabilityStatus 66 yield() // prompt cancellation guarantee 67 if (controllerSet.add(controller)) { 68 controller.setAvailabilityStatus(status) 69 } 70 } 71 true 72 } catch (exception: Exception) { 73 Log.e(LOG_TAG, "Setup availability status failed!", exception) 74 false 75 } 76 unsetAvailabilityStatusnull77 private fun unsetAvailabilityStatus() { 78 for (controller in controllerSet) { 79 controller.unsetAvailabilityStatus() 80 } 81 } 82 83 companion object { 84 private const val LOG_TAG = "TelephonyStatusControlSS" 85 } 86 } 87