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.network.telephony
18 
19 import android.content.Context
20 import android.provider.Settings
21 import android.telecom.TelecomManager
22 import android.telephony.SubscriptionManager
23 import android.telephony.TelephonyManager
24 import android.telephony.ims.ImsMmTelManager
25 import android.util.Log
26 import androidx.lifecycle.LifecycleOwner
27 import androidx.preference.Preference
28 import androidx.preference.PreferenceScreen
29 import com.android.settings.R
30 import com.android.settings.network.telephony.wificalling.WifiCallingRepository
31 import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
32 import kotlinx.coroutines.Dispatchers
33 import kotlinx.coroutines.withContext
34 
35 /**
36  * Preference controller for "Wifi Calling".
37  *
38  * TODO: Remove the class once Provider Model is always enabled in the future.
39  */
40 open class WifiCallingPreferenceController @JvmOverloads constructor(
41     context: Context,
42     key: String,
43     private val callStateRepository: CallStateRepository = CallStateRepository(context),
44     private val wifiCallingRepositoryFactory: (subId: Int) -> WifiCallingRepository = { subId ->
45         WifiCallingRepository(context, subId)
46     },
47 ) : TelephonyBasePreferenceController(context, key) {
48 
49     private lateinit var preference: Preference
50     private lateinit var callingPreferenceCategoryController: CallingPreferenceCategoryController
51 
<lambda>null52     private val resourcesForSub by lazy {
53         SubscriptionManager.getResourcesForSubId(mContext, mSubId)
54     }
55 
initnull56     fun init(
57         subId: Int,
58         callingPreferenceCategoryController: CallingPreferenceCategoryController,
59     ): WifiCallingPreferenceController {
60         mSubId = subId
61         this.callingPreferenceCategoryController = callingPreferenceCategoryController
62         return this
63     }
64 
65     /**
66      * Note: Visibility also controlled by [onViewCreated].
67      */
getAvailabilityStatusnull68     override fun getAvailabilityStatus(subId: Int) =
69         if (SubscriptionManager.isValidSubscriptionId(subId)) AVAILABLE
70         else CONDITIONALLY_UNAVAILABLE
71 
72     override fun displayPreference(screen: PreferenceScreen) {
73         // Not call super here, to avoid preference.isVisible changed unexpectedly
74         preference = screen.findPreference(preferenceKey)!!
75         preference.intent?.putExtra(Settings.EXTRA_SUB_ID, mSubId)
76     }
77 
onViewCreatednull78     override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
79         if(mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID){
80             Log.e(
81                 this.javaClass.simpleName,
82                 "mSubId is INVALID_SUBSCRIPTION_ID"
83             )
84             return
85         }
86         wifiCallingRepositoryFactory(mSubId).wifiCallingReadyFlow()
87             .collectLatestWithLifecycle(viewLifecycleOwner) { isReady ->
88                 preference.isVisible = isReady
89                 callingPreferenceCategoryController.updateChildVisible(preferenceKey, isReady)
90                 if (isReady) update()
91             }
92 
93         callStateRepository.callStateFlow(mSubId).collectLatestWithLifecycle(viewLifecycleOwner) {
94             preference.isEnabled = (it == TelephonyManager.CALL_STATE_IDLE)
95         }
96     }
97 
updatenull98     private suspend fun update() {
99         val simCallManager = mContext.getSystemService(TelecomManager::class.java)
100             ?.getSimCallManagerForSubscription(mSubId)
101         if (simCallManager != null) {
102             val intent = withContext(Dispatchers.Default) {
103                 MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext, simCallManager)
104             } ?: return // Do nothing in this case since preference is invisible
105             val title = withContext(Dispatchers.Default) {
106                 mContext.packageManager.resolveActivity(intent, 0)
107                     ?.loadLabel(mContext.packageManager)
108             } ?: return
109             preference.intent = intent
110             preference.title = title
111             preference.summary = null
112         } else {
113             preference.title = resourcesForSub.getString(R.string.wifi_calling_settings_title)
114             preference.summary = withContext(Dispatchers.Default) { getSummaryForWfcMode() }
115         }
116     }
117 
getSummaryForWfcModenull118     private fun getSummaryForWfcMode(): String {
119         val resId = when (wifiCallingRepositoryFactory(mSubId).getWiFiCallingMode()) {
120             ImsMmTelManager.WIFI_MODE_WIFI_ONLY ->
121                 com.android.internal.R.string.wfc_mode_wifi_only_summary
122 
123             ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED ->
124                 com.android.internal.R.string.wfc_mode_cellular_preferred_summary
125 
126             ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED ->
127                 com.android.internal.R.string.wfc_mode_wifi_preferred_summary
128 
129             else -> com.android.internal.R.string.wifi_calling_off_summary
130         }
131         return resourcesForSub.getString(resId)
132     }
133 }
134