• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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.spa.network
18 
19 import android.content.Context
20 import android.content.Intent
21 import android.os.UserManager
22 import android.telephony.SubscriptionInfo
23 import android.telephony.euicc.EuiccManager
24 import androidx.compose.material.icons.Icons
25 import androidx.compose.material.icons.outlined.Add
26 import androidx.compose.material.icons.outlined.SimCard
27 import androidx.compose.material.icons.outlined.SimCardDownload
28 import androidx.compose.runtime.Composable
29 import androidx.compose.runtime.State
30 import androidx.compose.runtime.getValue
31 import androidx.compose.runtime.remember
32 import androidx.compose.runtime.rememberCoroutineScope
33 import androidx.compose.ui.platform.LocalContext
34 import androidx.compose.ui.res.stringResource
35 import androidx.lifecycle.compose.collectAsStateWithLifecycle
36 import com.android.settings.R
37 import com.android.settings.Utils
38 import com.android.settings.network.SatelliteWarningDialogActivity
39 import com.android.settings.network.SatelliteWarningDialogActivity.Companion.CUSTOM_CONTENT_BUTTON_NAME
40 import com.android.settings.network.SatelliteWarningDialogActivity.Companion.CUSTOM_CONTENT_DESCRIPTION
41 import com.android.settings.network.SatelliteWarningDialogActivity.Companion.CUSTOM_CONTENT_TITLE
42 import com.android.settings.network.SubscriptionUtil
43 import com.android.settings.network.telephony.MobileNetworkUtils
44 import com.android.settings.network.telephony.SubscriptionActivationRepository
45 import com.android.settings.network.telephony.SubscriptionRepository
46 import com.android.settings.network.telephony.euicc.EuiccRepository
47 import com.android.settings.network.telephony.phoneNumberFlow
48 import com.android.settingslib.spa.widget.preference.PreferenceModel
49 import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
50 import com.android.settingslib.spa.widget.ui.Category
51 import com.android.settingslib.spa.widget.ui.SettingsIcon
52 import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
53 import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference
54 import com.android.settingslib.spaprivileged.template.preference.RestrictedTwoTargetSwitchPreference
55 import kotlinx.coroutines.flow.flow
56 import kotlinx.coroutines.launch
57 
58 @Composable
59 fun SimsSection(subscriptionInfoList: List<SubscriptionInfo>) {
60     Category {
61         for (subInfo in subscriptionInfoList) {
62             SimPreference(subInfo)
63         }
64 
65         AddSim()
66     }
67 }
68 
69 @Composable
SimPreferencenull70 private fun SimPreference(subInfo: SubscriptionInfo) {
71     val context = LocalContext.current
72     val checked = remember(subInfo.subscriptionId) {
73         SubscriptionRepository(context).isSubscriptionEnabledFlow(subInfo.subscriptionId)
74     }.collectAsStateWithLifecycle(initialValue = false)
75     val phoneNumber = phoneNumber(subInfo)
76     val isConvertedPsim by remember(subInfo) {
77         flow {
78             emit(SubscriptionUtil.isConvertedPsimSubscription(subInfo))
79         }
80     }.collectAsStateWithLifecycle(initialValue = false)
81     val subscriptionActivationRepository = remember { SubscriptionActivationRepository(context) }
82     val isActivationChangeable by remember {
83         subscriptionActivationRepository.isActivationChangeableFlow()
84     }.collectAsStateWithLifecycle(initialValue = false)
85     val coroutineScope = rememberCoroutineScope()
86     RestrictedTwoTargetSwitchPreference(
87         model = object : SwitchPreferenceModel {
88             override val title = subInfo.displayName.toString()
89             override val summary = {
90                 if (isConvertedPsim) {
91                     context.getString(R.string.sim_category_converted_sim)
92                 } else {
93                     phoneNumber.value ?: ""
94                 }
95             }
96             override val icon = @Composable { SimIcon(subInfo.isEmbedded) }
97             override val changeable = { isActivationChangeable && !isConvertedPsim }
98             override val checked = { checked.value }
99             override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
100                 coroutineScope.launch {
101                     subscriptionActivationRepository.setActive(subInfo.subscriptionId, newChecked)
102                 }
103             }
104         },
105         restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)),
106         primaryEnabled = { !isConvertedPsim },
107     ) {
108         MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo)
109     }
110 }
111 
112 @Composable
SimIconnull113 private fun SimIcon(isEmbedded: Boolean) {
114     SettingsIcon(if (isEmbedded) Icons.Outlined.SimCardDownload else Icons.Outlined.SimCard)
115 }
116 
117 @Composable
phoneNumbernull118 fun phoneNumber(subInfo: SubscriptionInfo): State<String?> {
119     val context = LocalContext.current
120     return remember(subInfo) {
121         context.phoneNumberFlow(subInfo)
122     }.collectAsStateWithLifecycle(initialValue = null)
123 }
124 
125 @Composable
AddSimnull126 private fun AddSim() {
127     val context = LocalContext.current
128     val isShow by
129         remember { EuiccRepository(context).showEuiccSettingsFlow() }
130             .collectAsStateWithLifecycle(initialValue = false)
131     if (isShow) {
132         RestrictedPreference(
133             model =
134                 object : PreferenceModel {
135                     override val title = stringResource(id = R.string.mobile_network_list_add_more)
136                     override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) }
137                     override val onClick = { startAddSimFlow(context) }
138                 },
139             restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)),
140         )
141     }
142 }
143 
startAddSimFlownull144 fun startAddSimFlow(context: Context) = context.startActivity(getAddSimIntent())
145 
146 fun getAddSimIntent() = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION).apply {
147     setPackage(Utils.PHONE_PACKAGE_NAME)
148     putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true)
149 }
150 
startSatelliteWarningDialogFlownull151 fun startSatelliteWarningDialogFlow(context: Context) = context.startActivity(getSatelliteWarningDialogIntent(context))
152 
153 fun getSatelliteWarningDialogIntent(context: Context) = Intent(context,
154     SatelliteWarningDialogActivity::class.java).apply {
155     val content = HashMap<Int, String>()
156     content.put(CUSTOM_CONTENT_TITLE, context.getString(R.string.title_satellite_dialog_for_sim_restriction))
157     content.put(CUSTOM_CONTENT_DESCRIPTION, context.getString(R.string.description_satellite_dialog_for_sim_restriction))
158     content.put(CUSTOM_CONTENT_BUTTON_NAME, context.getString(R.string.okay))
159     putExtra(SatelliteWarningDialogActivity.EXTRA_TYPE_OF_SATELLITE_CUSTOMIZED_CONTENT, content)
160 }
161