Merge "Add the UI of dual sim onboarding" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
4601261f81
@@ -47,6 +47,7 @@ import com.android.settings.spa.development.UsageStatsPageProvider
|
||||
import com.android.settings.spa.development.compat.PlatformCompatAppListPageProvider
|
||||
import com.android.settings.spa.home.HomePageProvider
|
||||
import com.android.settings.spa.network.NetworkAndInternetPageProvider
|
||||
import com.android.settings.spa.network.SimOnboardingPageProvider
|
||||
import com.android.settings.spa.notification.AppListNotificationsPageProvider
|
||||
import com.android.settings.spa.notification.NotificationMainPageProvider
|
||||
import com.android.settings.spa.system.AppLanguagesPageProvider
|
||||
@@ -114,6 +115,7 @@ open class SettingsSpaEnvironment(context: Context) : SpaEnvironment(context) {
|
||||
StorageAppListPageProvider.Apps,
|
||||
StorageAppListPageProvider.Games,
|
||||
ApnEditPageProvider,
|
||||
SimOnboardingPageProvider,
|
||||
)
|
||||
|
||||
override val logger = if (FeatureFlagUtils.isEnabled(
|
||||
|
||||
113
src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
Normal file
113
src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.SignalCellularAlt
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.SimOnboardingService
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
|
||||
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
|
||||
import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField
|
||||
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.BottomAppBarButton
|
||||
import com.android.settingslib.spa.widget.scaffold.SuwScaffold
|
||||
import com.android.settingslib.spa.widget.ui.SettingsBody
|
||||
|
||||
/**
|
||||
* the sim onboarding label compose
|
||||
*/
|
||||
@Composable
|
||||
fun SimOnboardingLabelSimImpl(
|
||||
nextAction: () -> Unit,
|
||||
cancelAction: () -> Unit,
|
||||
onboardingService: SimOnboardingService
|
||||
) {
|
||||
SuwScaffold(
|
||||
imageVector = Icons.Outlined.SignalCellularAlt,
|
||||
title = stringResource(R.string.sim_onboarding_label_sim_title),
|
||||
actionButton = BottomAppBarButton(
|
||||
stringResource(R.string.sim_onboarding_next),
|
||||
nextAction
|
||||
),
|
||||
dismissButton = BottomAppBarButton(
|
||||
stringResource(R.string.cancel),
|
||||
cancelAction
|
||||
),
|
||||
) {
|
||||
labelSimBody(onboardingService)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun labelSimBody(onboardingService: SimOnboardingService) {
|
||||
Column(Modifier.padding(SettingsDimension.itemPadding)) {
|
||||
SettingsBody(stringResource(R.string.sim_onboarding_label_sim_msg))
|
||||
}
|
||||
|
||||
for (subInfo in onboardingService.getSelectableSubscriptionInfo()) {
|
||||
var titleSimName by remember {
|
||||
mutableStateOf(
|
||||
onboardingService.getSubscriptionInfoDisplayName(subInfo)
|
||||
)
|
||||
}
|
||||
var summaryNumber = subInfo.number
|
||||
// TODO using the SubscriptionUtil.getFormattedPhoneNumber
|
||||
val alertDialogPresenter = rememberAlertDialogPresenter(
|
||||
confirmButton = AlertDialogButton(
|
||||
stringResource(R.string.mobile_network_sim_name_rename)
|
||||
) {
|
||||
onboardingService.addItemForRenaming(subInfo, titleSimName)
|
||||
},
|
||||
dismissButton = AlertDialogButton(stringResource(R.string.cancel)) {
|
||||
titleSimName = onboardingService.getSubscriptionInfoDisplayName(subInfo)
|
||||
},
|
||||
title = stringResource(R.string.sim_onboarding_label_sim_dialog_title),
|
||||
text = {
|
||||
Text(summaryNumber)
|
||||
SettingsOutlinedTextField(
|
||||
value = titleSimName,
|
||||
label = stringResource(R.string.sim_onboarding_label_sim_dialog_label),
|
||||
enabled = true
|
||||
) {
|
||||
titleSimName = it
|
||||
}
|
||||
},
|
||||
)
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = titleSimName
|
||||
override val summary: () -> String
|
||||
get() = { summaryNumber }
|
||||
override val onClick = alertDialogPresenter::open
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.SimOnboardingService
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
const val SUB_ID = "subId"
|
||||
|
||||
enum class SimOnboardingScreen(val stringResId: Int) {
|
||||
LabelSim(R.string.sim_onboarding_label_sim_title),
|
||||
SelectSim(R.string.sim_onboarding_select_sim_title),
|
||||
PrimarySim(R.string.sim_onboarding_primary_sim_title)
|
||||
}
|
||||
|
||||
/**
|
||||
* Showing the sim onboarding which is the process flow of sim switching on.
|
||||
*/
|
||||
object SimOnboardingPageProvider : SettingsPageProvider {
|
||||
override val name = "SimOnboardingPageProvider"
|
||||
override val parameter = listOf(
|
||||
navArgument(SUB_ID) { type = NavType.IntType },
|
||||
)
|
||||
|
||||
private val owner = createSettingsPage()
|
||||
@VisibleForTesting
|
||||
var onboardingService: SimOnboardingService = SimOnboardingService()
|
||||
|
||||
fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
// never using
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = name
|
||||
override val onClick = navigator(getRoute(-1))
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
initServiceData(arguments!!.getInt(SUB_ID))
|
||||
PageImpl(onboardingService,rememberNavController())
|
||||
}
|
||||
|
||||
fun getRoute(
|
||||
subId: Int
|
||||
): String = "${name}/$subId"
|
||||
|
||||
@Composable
|
||||
fun initServiceData(targetSubId: Int) {
|
||||
onboardingService.initData(targetSubId, LocalContext.current)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Context.getActivity(): Activity? = when (this) {
|
||||
is Activity -> this
|
||||
is ContextWrapper -> baseContext.getActivity()
|
||||
else -> null
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PageImpl(onboardingService:SimOnboardingService,navHostController: NavHostController) {
|
||||
val context = LocalContext.current
|
||||
var previousPageOfOnboarding: () -> Unit = { context.getActivity()?.finish() }
|
||||
|
||||
NavHost(
|
||||
navController = navHostController,
|
||||
startDestination = SimOnboardingScreen.LabelSim.name
|
||||
) {
|
||||
composable(route = SimOnboardingScreen.LabelSim.name) {
|
||||
val nextPage =
|
||||
// Adding more conditions
|
||||
if (onboardingService.isMultipleEnabledProfilesSupported) {
|
||||
SimOnboardingScreen.SelectSim.name
|
||||
} else {
|
||||
SimOnboardingScreen.PrimarySim.name
|
||||
}
|
||||
SimOnboardingLabelSimImpl(
|
||||
nextAction = { navHostController.navigate(nextPage) },
|
||||
cancelAction = previousPageOfOnboarding,
|
||||
onboardingService = onboardingService
|
||||
)
|
||||
}
|
||||
composable(route = SimOnboardingScreen.PrimarySim.name) {
|
||||
SimOnboardingPrimarySimImpl(
|
||||
nextAction = {
|
||||
//go back and activate sim
|
||||
},
|
||||
cancelAction = previousPageOfOnboarding,
|
||||
onboardingService = onboardingService
|
||||
)
|
||||
}
|
||||
composable(route = SimOnboardingScreen.SelectSim.name) {
|
||||
SimOnboardingSelectSimImpl(
|
||||
nextAction = { navHostController.navigate(SimOnboardingScreen.PrimarySim.name) },
|
||||
cancelAction = previousPageOfOnboarding,
|
||||
onboardingService = onboardingService
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
160
src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
Normal file
160
src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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 androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.Message
|
||||
import androidx.compose.material.icons.outlined.DataUsage
|
||||
import androidx.compose.material.icons.outlined.SignalCellularAlt
|
||||
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.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.SimOnboardingService
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.widget.preference.ListPreference
|
||||
import com.android.settingslib.spa.widget.preference.ListPreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.ListPreferenceOption
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.BottomAppBarButton
|
||||
import com.android.settingslib.spa.widget.scaffold.SuwScaffold
|
||||
import com.android.settingslib.spa.widget.ui.SettingsBody
|
||||
import com.android.settingslib.spa.widget.ui.SettingsIcon
|
||||
|
||||
/**
|
||||
* the sim onboarding primary sim compose
|
||||
*/
|
||||
@Composable
|
||||
fun SimOnboardingPrimarySimImpl(
|
||||
nextAction: () -> Unit,
|
||||
cancelAction: () -> Unit,
|
||||
onboardingService: SimOnboardingService
|
||||
) {
|
||||
SuwScaffold(
|
||||
imageVector = Icons.Outlined.SignalCellularAlt,
|
||||
title = stringResource(id = R.string.sim_onboarding_primary_sim_title),
|
||||
actionButton = BottomAppBarButton(
|
||||
stringResource(id = R.string.done),
|
||||
nextAction
|
||||
),
|
||||
dismissButton = BottomAppBarButton(
|
||||
stringResource(id = R.string.cancel),
|
||||
cancelAction
|
||||
),
|
||||
) {
|
||||
primarySimBody(onboardingService)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun primarySimBody(onboardingService: SimOnboardingService) {
|
||||
//TODO: Load the status from the frameworks
|
||||
var callsSelectedId = rememberSaveable { mutableIntStateOf(1) }
|
||||
var textsSelectedId = rememberSaveable { mutableIntStateOf(1) }
|
||||
var mobileDataSelectedId = rememberSaveable { mutableIntStateOf(1) }
|
||||
var automaticDataChecked by rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
Column(Modifier.padding(SettingsDimension.itemPadding)) {
|
||||
SettingsBody(stringResource(id = R.string.sim_onboarding_primary_sim_msg))
|
||||
}
|
||||
var selectableSubscriptionInfo = onboardingService.getSelectableSubscriptionInfo()
|
||||
var list = listOf(ListPreferenceOption(id = -1, text = "Loading"))
|
||||
if (selectableSubscriptionInfo.size >= 2) {
|
||||
list = listOf(
|
||||
ListPreferenceOption(
|
||||
id = selectableSubscriptionInfo[0].subscriptionId,
|
||||
text = "${selectableSubscriptionInfo[0].displayName}"
|
||||
),
|
||||
ListPreferenceOption(
|
||||
id = selectableSubscriptionInfo[1].subscriptionId,
|
||||
text = "${selectableSubscriptionInfo[1].displayName}"
|
||||
),
|
||||
ListPreferenceOption(
|
||||
id = -1,
|
||||
text = stringResource(id = R.string.sim_calls_ask_first_prefs_title)
|
||||
),
|
||||
)
|
||||
} else {
|
||||
// set all of primary sim items' enable as false and showing that sim.
|
||||
}
|
||||
createPrimarySimListPreference(
|
||||
stringResource(id = R.string.primary_sim_calls_title),
|
||||
list,
|
||||
callsSelectedId,
|
||||
ImageVector.vectorResource(R.drawable.ic_phone),
|
||||
true
|
||||
)
|
||||
createPrimarySimListPreference(
|
||||
stringResource(id = R.string.primary_sim_texts_title),
|
||||
list,
|
||||
textsSelectedId,
|
||||
Icons.AutoMirrored.Outlined.Message,
|
||||
true
|
||||
)
|
||||
createPrimarySimListPreference(
|
||||
stringResource(id = R.string.mobile_data_settings_title),
|
||||
list,
|
||||
mobileDataSelectedId,
|
||||
Icons.Outlined.DataUsage,
|
||||
true
|
||||
)
|
||||
|
||||
val autoDataTitle = stringResource(id = R.string.primary_sim_automatic_data_title)
|
||||
val autoDataSummary = stringResource(id = R.string.primary_sim_automatic_data_msg)
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = autoDataTitle
|
||||
override val summary = { autoDataSummary }
|
||||
override val checked = { automaticDataChecked }
|
||||
override val onCheckedChange =
|
||||
{ newChecked: Boolean -> automaticDataChecked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun createPrimarySimListPreference(
|
||||
title: String,
|
||||
list: List<ListPreferenceOption>,
|
||||
selectedId: MutableIntState,
|
||||
icon: ImageVector,
|
||||
enable: Boolean
|
||||
) = ListPreference(remember {
|
||||
object : ListPreferenceModel {
|
||||
override val title = title
|
||||
override val options = list
|
||||
override val selectedId = selectedId
|
||||
override val onIdSelected: (id: Int) -> Unit = { selectedId.intValue = it }
|
||||
override val icon = @Composable {
|
||||
SettingsIcon(icon)
|
||||
}
|
||||
override val enabled: () -> Boolean
|
||||
get() = { enable }
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.SignalCellularAlt
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.SimOnboardingService
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.widget.preference.CheckboxPreference
|
||||
import com.android.settingslib.spa.widget.preference.CheckboxPreferenceModel
|
||||
|
||||
import com.android.settingslib.spa.widget.scaffold.BottomAppBarButton
|
||||
import com.android.settingslib.spa.widget.scaffold.SuwScaffold
|
||||
import com.android.settingslib.spa.widget.ui.SettingsBody
|
||||
|
||||
/**
|
||||
* the sim onboarding select sim compose
|
||||
*/
|
||||
@Composable
|
||||
fun SimOnboardingSelectSimImpl(
|
||||
nextAction: () -> Unit,
|
||||
cancelAction: () -> Unit,
|
||||
onboardingService: SimOnboardingService
|
||||
) {
|
||||
SuwScaffold(
|
||||
imageVector = Icons.Outlined.SignalCellularAlt,
|
||||
title = stringResource(id = R.string.sim_onboarding_select_sim_title),
|
||||
actionButton = BottomAppBarButton(
|
||||
stringResource(id = R.string.sim_onboarding_next),
|
||||
nextAction
|
||||
),
|
||||
dismissButton = BottomAppBarButton(
|
||||
stringResource(id = R.string.cancel),
|
||||
cancelAction
|
||||
),
|
||||
) {
|
||||
selectSimBody(onboardingService)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun selectSimBody(onboardingService: SimOnboardingService) {
|
||||
Column(Modifier.padding(SettingsDimension.itemPadding)) {
|
||||
SettingsBody(stringResource(id = R.string.sim_onboarding_select_sim_msg))
|
||||
}
|
||||
for (subInfo in onboardingService.getSelectableSubscriptionInfo()) {
|
||||
var title = onboardingService.getSubscriptionInfoDisplayName(subInfo)
|
||||
var summaryNumber =
|
||||
subInfo.number // TODO using the SubscriptionUtil.getFormattedPhoneNumber
|
||||
var changeable = subInfo.isActive
|
||||
var checked by rememberSaveable { mutableStateOf(!subInfo.isActive) }
|
||||
|
||||
CheckboxPreference(remember {
|
||||
object : CheckboxPreferenceModel {
|
||||
override val title = title
|
||||
override val summary: () -> String
|
||||
get() = { summaryNumber }
|
||||
override val checked = { checked }
|
||||
override val changeable = { changeable }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user