Loading src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +0 −1 Original line number Diff line number Diff line Loading @@ -686,7 +686,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment)); controllers.add(new BluetoothLeAudioHwOffloadPreferenceController(context, fragment)); controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context)); controllers.add(new NfcStackDebugLogPreferenceController(context)); controllers.add(new NfcSnoopLogPreferenceController(context, fragment)); controllers.add(new NfcVerboseVendorLogPreferenceController(context, fragment)); controllers.add(new ShowTapsPreferenceController(context)); Loading src/com/android/settings/development/NfcStackDebugLogPreferenceController.javadeleted 100644 → 0 +0 −82 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.development; import android.content.Context; import android.os.SystemProperties; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.TwoStatePreference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.development.DeveloperOptionsPreferenceController; public class NfcStackDebugLogPreferenceController extends DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { private static final String NFC_STACK_DEBUGLOG_ENABLED_KEY = "nfc_stack_debuglog_enabled"; @VisibleForTesting static final String NFC_STACK_DEBUGLOG_ENABLED_PROPERTY = "persist.nfc.debug_enabled"; public NfcStackDebugLogPreferenceController(Context context) { super(context); } @Override public String getPreferenceKey() { return NFC_STACK_DEBUGLOG_ENABLED_KEY; } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean isEnabled = (Boolean) newValue; try { SystemProperties.set(NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, isEnabled ? "true" : "false"); } catch (RuntimeException e) { Log.e(TAG, "Fail to set nfc system property: " + e.getMessage()); } return true; } @Override public void updateState(Preference preference) { try { final boolean isEnabled = SystemProperties.getBoolean( NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, false /* default */); ((TwoStatePreference) mPreference).setChecked(isEnabled); } catch (RuntimeException e) { Log.e(TAG, "Fail to get nfc system property: " + e.getMessage()); } } @Override protected void onDeveloperOptionsSwitchDisabled() { super.onDeveloperOptionsSwitchDisabled(); try { SystemProperties.set(NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, "false"); ((TwoStatePreference) mPreference).setChecked(false); } catch (RuntimeException e) { Log.e(TAG, "Fail to set nfc system property: " + e.getMessage()); } } } src/com/android/settings/network/telephony/SubscriptionRepository.kt +7 −0 Original line number Diff line number Diff line Loading @@ -25,10 +25,17 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach private const val TAG = "SubscriptionRepository" fun Context.isSubscriptionEnabledFlow(subId: Int) = subscriptionsChangedFlow().map { val subscriptionManager = getSystemService(SubscriptionManager::class.java) subscriptionManager?.isSubscriptionEnabled(subId) ?: false }.flowOn(Dispatchers.Default) fun Context.subscriptionsChangedFlow() = callbackFlow { val subscriptionManager = getSystemService(SubscriptionManager::class.java)!! Loading src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt +40 −132 Original line number Diff line number Diff line Loading @@ -16,37 +16,33 @@ package com.android.settings.spa.network import android.app.Application import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Bundle import android.os.UserManager import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.euicc.EuiccManager import android.util.Log import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.Message import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.DataUsage import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableIntState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import com.android.settings.R import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settings.network.SubscriptionUtil import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.wifi.WifiPickerTrackerHelper import com.android.settingslib.spa.framework.common.SettingsEntryBuilder Loading @@ -59,17 +55,13 @@ import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.ui.Category import com.android.settingslib.spa.widget.ui.SettingsIcon import com.android.settingslib.spaprivileged.framework.common.broadcastReceiverFlow import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.flowOf Loading @@ -85,10 +77,8 @@ import kotlinx.coroutines.withContext object NetworkCellularGroupProvider : SettingsPageProvider { override val name = "NetworkCellularGroupProvider" private lateinit var subscriptionViewModel: SubscriptionInfoListViewModel private val owner = createSettingsPage() var selectableSubscriptionInfoList: List<SubscriptionInfo> = listOf() var defaultVoiceSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID var defaultSmsSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID var defaultDataSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID Loading @@ -106,9 +96,6 @@ object NetworkCellularGroupProvider : SettingsPageProvider { @Composable override fun Page(arguments: Bundle?) { val context = LocalContext.current var selectableSubscriptionInfoListRemember = remember { mutableListOf<SubscriptionInfo>().toMutableStateList() } var callsSelectedId = rememberSaveable { mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID) } Loading @@ -122,24 +109,24 @@ object NetworkCellularGroupProvider : SettingsPageProvider { mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID) } subscriptionViewModel = SubscriptionInfoListViewModel( context.applicationContext as Application) val subscriptionViewModel = viewModel<SubscriptionInfoListViewModel>() remember { allOfFlows(context, subscriptionViewModel.selectableSubscriptionInfoListFlow) .collectLatestWithLifecycle(LocalLifecycleOwner.current) { selectableSubscriptionInfoListRemember.clear() selectableSubscriptionInfoListRemember.addAll(selectableSubscriptionInfoList) }.collectLatestWithLifecycle(LocalLifecycleOwner.current) { callsSelectedId.intValue = defaultVoiceSubId textsSelectedId.intValue = defaultSmsSubId mobileDataSelectedId.intValue = defaultDataSubId nonDdsRemember.intValue = nonDds } PageImpl(selectableSubscriptionInfoListRemember, PageImpl( subscriptionViewModel.selectableSubscriptionInfoListFlow, callsSelectedId, textsSelectedId, mobileDataSelectedId, nonDdsRemember) nonDdsRemember ) } private fun allOfFlows(context: Context, Loading @@ -152,13 +139,12 @@ object NetworkCellularGroupProvider : SettingsPageProvider { NetworkCellularGroupProvider::refreshUiStates, ).flowOn(Dispatchers.Default) fun refreshUiStates( inputSelectableSubscriptionInfoList: List<SubscriptionInfo>, private fun refreshUiStates( selectableSubscriptionInfoList: List<SubscriptionInfo>, inputDefaultVoiceSubId: Int, inputDefaultSmsSubId: Int, inputDefaultDateSubId: Int ): Unit { selectableSubscriptionInfoList = inputSelectableSubscriptionInfoList ) { defaultVoiceSubId = inputDefaultVoiceSubId defaultSmsSubId = inputDefaultSmsSubId defaultDataSubId = inputDefaultDateSubId Loading @@ -178,25 +164,23 @@ object NetworkCellularGroupProvider : SettingsPageProvider { } @Composable fun PageImpl(selectableSubscriptionInfoList: List<SubscriptionInfo>, fun PageImpl( selectableSubscriptionInfoListFlow: StateFlow<List<SubscriptionInfo>>, defaultVoiceSubId: MutableIntState, defaultSmsSubId: MutableIntState, defaultDataSubId: MutableIntState, nonDds: MutableIntState) { val context = LocalContext.current var activeSubscriptionInfoList: List<SubscriptionInfo> = nonDds: MutableIntState ) { val selectableSubscriptionInfoList by selectableSubscriptionInfoListFlow .collectAsStateWithLifecycle(initialValue = emptyList()) val activeSubscriptionInfoList: List<SubscriptionInfo> = selectableSubscriptionInfoList.filter { subscriptionInfo -> subscriptionInfo.simSlotIndex != -1 } var subscriptionManager = context.getSystemService(SubscriptionManager::class.java) val stringSims = stringResource(R.string.provider_network_settings_title) RegularScaffold(title = stringSims) { SimsSectionImpl( context, subscriptionManager, selectableSubscriptionInfoList ) SimsSection(selectableSubscriptionInfoList) PrimarySimSectionImpl( activeSubscriptionInfoList, defaultVoiceSubId, Loading @@ -207,56 +191,6 @@ fun PageImpl(selectableSubscriptionInfoList: List<SubscriptionInfo>, } } @Composable fun SimsSectionImpl( context: Context, subscriptionManager: SubscriptionManager?, subscriptionInfoList: List<SubscriptionInfo> ) { val coroutineScope = rememberCoroutineScope() for (subInfo in subscriptionInfoList) { val checked = rememberSaveable() { mutableStateOf(false) } //TODO: Add the Restricted TwoTargetSwitchPreference in SPA TwoTargetSwitchPreference( object : SwitchPreferenceModel { override val title = subInfo.displayName.toString() override val summary = { subInfo.number } override val checked = { coroutineScope.launch { withContext(Dispatchers.Default) { checked.value = subscriptionManager?.isSubscriptionEnabled( subInfo.subscriptionId)?:false } } checked.value } override val onCheckedChange = { newChecked: Boolean -> startToggleSubscriptionDialog(context, subInfo, newChecked) } } ) { startMobileNetworkSettings(context, subInfo) } } // + add sim if (showEuiccSettings(context)) { RestrictedPreference( model = object : PreferenceModel { override val title = stringResource(id = R.string.mobile_network_list_add_more) override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) } override val onClick = { startAddSimFlow(context) } }, restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)), ) } } @Composable fun PrimarySimImpl( subscriptionInfoList: List<SubscriptionInfo>, Loading Loading @@ -440,32 +374,6 @@ private fun Context.defaultDefaultDataSubscriptionFlow(): Flow<Int> = ).map { SubscriptionManager.getDefaultDataSubscriptionId() } .conflate().flowOn(Dispatchers.Default) private fun startToggleSubscriptionDialog( context: Context, subInfo: SubscriptionInfo, newStatus: Boolean ) { SubscriptionUtil.startToggleSubscriptionDialogActivity( context, subInfo.subscriptionId, newStatus ) } private fun startMobileNetworkSettings(context: Context, subInfo: SubscriptionInfo) { MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo) } private fun startAddSimFlow(context: Context) { val intent = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION) intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true) context.startActivity(intent) } private fun showEuiccSettings(context: Context): Boolean { return MobileNetworkUtils.showEuiccSettings(context) } suspend fun setDefaultVoice( subscriptionManager: SubscriptionManager?, subId: Int Loading src/com/android/settings/spa/network/SimsSection.kt 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.spa.network import android.content.Context import android.content.Intent import android.os.UserManager import android.telephony.SubscriptionInfo import android.telephony.euicc.EuiccManager import androidx.compose.foundation.layout.Column import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Add import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.settings.R import com.android.settings.network.SubscriptionUtil import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.network.telephony.isSubscriptionEnabledFlow import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference import com.android.settingslib.spa.widget.ui.SettingsIcon import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference @Composable fun SimsSection(subscriptionInfoList: List<SubscriptionInfo>) { Column { for (subInfo in subscriptionInfoList) { SimPreference(subInfo) } AddSim() } } @Composable private fun SimPreference(subInfo: SubscriptionInfo) { val context = LocalContext.current val checked = remember(subInfo.subscriptionId) { context.isSubscriptionEnabledFlow(subInfo.subscriptionId) }.collectAsStateWithLifecycle(initialValue = false) //TODO: Add the Restricted TwoTargetSwitchPreference in SPA TwoTargetSwitchPreference( object : SwitchPreferenceModel { override val title = subInfo.displayName.toString() override val summary = { subInfo.number } override val checked = { checked.value } override val onCheckedChange = { newChecked: Boolean -> SubscriptionUtil.startToggleSubscriptionDialogActivity( context, subInfo.subscriptionId, newChecked, ) } } ) { MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo) } } @Composable private fun AddSim() { val context = LocalContext.current if (remember { MobileNetworkUtils.showEuiccSettings(context) }) { RestrictedPreference( model = object : PreferenceModel { override val title = stringResource(id = R.string.mobile_network_list_add_more) override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) } override val onClick = { startAddSimFlow(context) } }, restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)), ) } } private fun startAddSimFlow(context: Context) { val intent = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION) intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true) context.startActivity(intent) } Loading
src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +0 −1 Original line number Diff line number Diff line Loading @@ -686,7 +686,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment)); controllers.add(new BluetoothLeAudioHwOffloadPreferenceController(context, fragment)); controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context)); controllers.add(new NfcStackDebugLogPreferenceController(context)); controllers.add(new NfcSnoopLogPreferenceController(context, fragment)); controllers.add(new NfcVerboseVendorLogPreferenceController(context, fragment)); controllers.add(new ShowTapsPreferenceController(context)); Loading
src/com/android/settings/development/NfcStackDebugLogPreferenceController.javadeleted 100644 → 0 +0 −82 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.development; import android.content.Context; import android.os.SystemProperties; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.TwoStatePreference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.development.DeveloperOptionsPreferenceController; public class NfcStackDebugLogPreferenceController extends DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { private static final String NFC_STACK_DEBUGLOG_ENABLED_KEY = "nfc_stack_debuglog_enabled"; @VisibleForTesting static final String NFC_STACK_DEBUGLOG_ENABLED_PROPERTY = "persist.nfc.debug_enabled"; public NfcStackDebugLogPreferenceController(Context context) { super(context); } @Override public String getPreferenceKey() { return NFC_STACK_DEBUGLOG_ENABLED_KEY; } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean isEnabled = (Boolean) newValue; try { SystemProperties.set(NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, isEnabled ? "true" : "false"); } catch (RuntimeException e) { Log.e(TAG, "Fail to set nfc system property: " + e.getMessage()); } return true; } @Override public void updateState(Preference preference) { try { final boolean isEnabled = SystemProperties.getBoolean( NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, false /* default */); ((TwoStatePreference) mPreference).setChecked(isEnabled); } catch (RuntimeException e) { Log.e(TAG, "Fail to get nfc system property: " + e.getMessage()); } } @Override protected void onDeveloperOptionsSwitchDisabled() { super.onDeveloperOptionsSwitchDisabled(); try { SystemProperties.set(NFC_STACK_DEBUGLOG_ENABLED_PROPERTY, "false"); ((TwoStatePreference) mPreference).setChecked(false); } catch (RuntimeException e) { Log.e(TAG, "Fail to set nfc system property: " + e.getMessage()); } } }
src/com/android/settings/network/telephony/SubscriptionRepository.kt +7 −0 Original line number Diff line number Diff line Loading @@ -25,10 +25,17 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach private const val TAG = "SubscriptionRepository" fun Context.isSubscriptionEnabledFlow(subId: Int) = subscriptionsChangedFlow().map { val subscriptionManager = getSystemService(SubscriptionManager::class.java) subscriptionManager?.isSubscriptionEnabled(subId) ?: false }.flowOn(Dispatchers.Default) fun Context.subscriptionsChangedFlow() = callbackFlow { val subscriptionManager = getSystemService(SubscriptionManager::class.java)!! Loading
src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt +40 −132 Original line number Diff line number Diff line Loading @@ -16,37 +16,33 @@ package com.android.settings.spa.network import android.app.Application import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Bundle import android.os.UserManager import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.euicc.EuiccManager import android.util.Log import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.Message import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.DataUsage import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableIntState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import com.android.settings.R import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settings.network.SubscriptionUtil import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.wifi.WifiPickerTrackerHelper import com.android.settingslib.spa.framework.common.SettingsEntryBuilder Loading @@ -59,17 +55,13 @@ import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.ui.Category import com.android.settingslib.spa.widget.ui.SettingsIcon import com.android.settingslib.spaprivileged.framework.common.broadcastReceiverFlow import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.flowOf Loading @@ -85,10 +77,8 @@ import kotlinx.coroutines.withContext object NetworkCellularGroupProvider : SettingsPageProvider { override val name = "NetworkCellularGroupProvider" private lateinit var subscriptionViewModel: SubscriptionInfoListViewModel private val owner = createSettingsPage() var selectableSubscriptionInfoList: List<SubscriptionInfo> = listOf() var defaultVoiceSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID var defaultSmsSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID var defaultDataSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID Loading @@ -106,9 +96,6 @@ object NetworkCellularGroupProvider : SettingsPageProvider { @Composable override fun Page(arguments: Bundle?) { val context = LocalContext.current var selectableSubscriptionInfoListRemember = remember { mutableListOf<SubscriptionInfo>().toMutableStateList() } var callsSelectedId = rememberSaveable { mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID) } Loading @@ -122,24 +109,24 @@ object NetworkCellularGroupProvider : SettingsPageProvider { mutableIntStateOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID) } subscriptionViewModel = SubscriptionInfoListViewModel( context.applicationContext as Application) val subscriptionViewModel = viewModel<SubscriptionInfoListViewModel>() remember { allOfFlows(context, subscriptionViewModel.selectableSubscriptionInfoListFlow) .collectLatestWithLifecycle(LocalLifecycleOwner.current) { selectableSubscriptionInfoListRemember.clear() selectableSubscriptionInfoListRemember.addAll(selectableSubscriptionInfoList) }.collectLatestWithLifecycle(LocalLifecycleOwner.current) { callsSelectedId.intValue = defaultVoiceSubId textsSelectedId.intValue = defaultSmsSubId mobileDataSelectedId.intValue = defaultDataSubId nonDdsRemember.intValue = nonDds } PageImpl(selectableSubscriptionInfoListRemember, PageImpl( subscriptionViewModel.selectableSubscriptionInfoListFlow, callsSelectedId, textsSelectedId, mobileDataSelectedId, nonDdsRemember) nonDdsRemember ) } private fun allOfFlows(context: Context, Loading @@ -152,13 +139,12 @@ object NetworkCellularGroupProvider : SettingsPageProvider { NetworkCellularGroupProvider::refreshUiStates, ).flowOn(Dispatchers.Default) fun refreshUiStates( inputSelectableSubscriptionInfoList: List<SubscriptionInfo>, private fun refreshUiStates( selectableSubscriptionInfoList: List<SubscriptionInfo>, inputDefaultVoiceSubId: Int, inputDefaultSmsSubId: Int, inputDefaultDateSubId: Int ): Unit { selectableSubscriptionInfoList = inputSelectableSubscriptionInfoList ) { defaultVoiceSubId = inputDefaultVoiceSubId defaultSmsSubId = inputDefaultSmsSubId defaultDataSubId = inputDefaultDateSubId Loading @@ -178,25 +164,23 @@ object NetworkCellularGroupProvider : SettingsPageProvider { } @Composable fun PageImpl(selectableSubscriptionInfoList: List<SubscriptionInfo>, fun PageImpl( selectableSubscriptionInfoListFlow: StateFlow<List<SubscriptionInfo>>, defaultVoiceSubId: MutableIntState, defaultSmsSubId: MutableIntState, defaultDataSubId: MutableIntState, nonDds: MutableIntState) { val context = LocalContext.current var activeSubscriptionInfoList: List<SubscriptionInfo> = nonDds: MutableIntState ) { val selectableSubscriptionInfoList by selectableSubscriptionInfoListFlow .collectAsStateWithLifecycle(initialValue = emptyList()) val activeSubscriptionInfoList: List<SubscriptionInfo> = selectableSubscriptionInfoList.filter { subscriptionInfo -> subscriptionInfo.simSlotIndex != -1 } var subscriptionManager = context.getSystemService(SubscriptionManager::class.java) val stringSims = stringResource(R.string.provider_network_settings_title) RegularScaffold(title = stringSims) { SimsSectionImpl( context, subscriptionManager, selectableSubscriptionInfoList ) SimsSection(selectableSubscriptionInfoList) PrimarySimSectionImpl( activeSubscriptionInfoList, defaultVoiceSubId, Loading @@ -207,56 +191,6 @@ fun PageImpl(selectableSubscriptionInfoList: List<SubscriptionInfo>, } } @Composable fun SimsSectionImpl( context: Context, subscriptionManager: SubscriptionManager?, subscriptionInfoList: List<SubscriptionInfo> ) { val coroutineScope = rememberCoroutineScope() for (subInfo in subscriptionInfoList) { val checked = rememberSaveable() { mutableStateOf(false) } //TODO: Add the Restricted TwoTargetSwitchPreference in SPA TwoTargetSwitchPreference( object : SwitchPreferenceModel { override val title = subInfo.displayName.toString() override val summary = { subInfo.number } override val checked = { coroutineScope.launch { withContext(Dispatchers.Default) { checked.value = subscriptionManager?.isSubscriptionEnabled( subInfo.subscriptionId)?:false } } checked.value } override val onCheckedChange = { newChecked: Boolean -> startToggleSubscriptionDialog(context, subInfo, newChecked) } } ) { startMobileNetworkSettings(context, subInfo) } } // + add sim if (showEuiccSettings(context)) { RestrictedPreference( model = object : PreferenceModel { override val title = stringResource(id = R.string.mobile_network_list_add_more) override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) } override val onClick = { startAddSimFlow(context) } }, restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)), ) } } @Composable fun PrimarySimImpl( subscriptionInfoList: List<SubscriptionInfo>, Loading Loading @@ -440,32 +374,6 @@ private fun Context.defaultDefaultDataSubscriptionFlow(): Flow<Int> = ).map { SubscriptionManager.getDefaultDataSubscriptionId() } .conflate().flowOn(Dispatchers.Default) private fun startToggleSubscriptionDialog( context: Context, subInfo: SubscriptionInfo, newStatus: Boolean ) { SubscriptionUtil.startToggleSubscriptionDialogActivity( context, subInfo.subscriptionId, newStatus ) } private fun startMobileNetworkSettings(context: Context, subInfo: SubscriptionInfo) { MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo) } private fun startAddSimFlow(context: Context) { val intent = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION) intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true) context.startActivity(intent) } private fun showEuiccSettings(context: Context): Boolean { return MobileNetworkUtils.showEuiccSettings(context) } suspend fun setDefaultVoice( subscriptionManager: SubscriptionManager?, subId: Int Loading
src/com/android/settings/spa/network/SimsSection.kt 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.spa.network import android.content.Context import android.content.Intent import android.os.UserManager import android.telephony.SubscriptionInfo import android.telephony.euicc.EuiccManager import androidx.compose.foundation.layout.Column import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Add import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.settings.R import com.android.settings.network.SubscriptionUtil import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.network.telephony.isSubscriptionEnabledFlow import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference import com.android.settingslib.spa.widget.ui.SettingsIcon import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference @Composable fun SimsSection(subscriptionInfoList: List<SubscriptionInfo>) { Column { for (subInfo in subscriptionInfoList) { SimPreference(subInfo) } AddSim() } } @Composable private fun SimPreference(subInfo: SubscriptionInfo) { val context = LocalContext.current val checked = remember(subInfo.subscriptionId) { context.isSubscriptionEnabledFlow(subInfo.subscriptionId) }.collectAsStateWithLifecycle(initialValue = false) //TODO: Add the Restricted TwoTargetSwitchPreference in SPA TwoTargetSwitchPreference( object : SwitchPreferenceModel { override val title = subInfo.displayName.toString() override val summary = { subInfo.number } override val checked = { checked.value } override val onCheckedChange = { newChecked: Boolean -> SubscriptionUtil.startToggleSubscriptionDialogActivity( context, subInfo.subscriptionId, newChecked, ) } } ) { MobileNetworkUtils.launchMobileNetworkSettings(context, subInfo) } } @Composable private fun AddSim() { val context = LocalContext.current if (remember { MobileNetworkUtils.showEuiccSettings(context) }) { RestrictedPreference( model = object : PreferenceModel { override val title = stringResource(id = R.string.mobile_network_list_add_more) override val icon = @Composable { SettingsIcon(Icons.Outlined.Add) } override val onClick = { startAddSimFlow(context) } }, restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)), ) } } private fun startAddSimFlow(context: Context) { val intent = Intent(EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION) intent.putExtra(EuiccManager.EXTRA_FORCE_PROVISION, true) context.startActivity(intent) }