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
17 package com.android.settings.spa.network
18
19 import android.app.Activity
20 import android.content.Context
21 import android.content.ContextWrapper
22 import android.os.Bundle
23 import androidx.annotation.VisibleForTesting
24 import androidx.compose.foundation.layout.Column
25 import androidx.compose.foundation.layout.padding
26 import androidx.compose.runtime.Composable
27 import androidx.compose.runtime.LaunchedEffect
28 import androidx.compose.ui.Modifier
29 import androidx.compose.ui.platform.LocalContext
30 import androidx.navigation.NavHostController
31 import androidx.navigation.NavType
32 import androidx.navigation.compose.NavHost
33 import androidx.navigation.compose.composable
34 import androidx.navigation.compose.rememberNavController
35 import androidx.navigation.navArgument
36 import com.android.settings.R
37 import com.android.settings.network.SimOnboardingActivity
38 import com.android.settings.network.SimOnboardingActivity.Companion.CallbackType
39 import com.android.settings.network.SimOnboardingService
40 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
41 import com.android.settingslib.spa.framework.common.SettingsPageProvider
42 import com.android.settingslib.spa.framework.common.createSettingsPage
43 import com.android.settingslib.spa.framework.compose.navigator
44 import com.android.settingslib.spa.framework.theme.SettingsDimension
45 import com.android.settingslib.spa.widget.preference.Preference
46 import com.android.settingslib.spa.widget.preference.PreferenceModel
47 import com.android.settingslib.spa.widget.ui.SettingsBody
48
49 const val SUB_ID = "subId"
50
51 enum class SimOnboardingScreen(val stringResId: Int) {
52 LabelSim(R.string.sim_onboarding_label_sim_title),
53 SelectSim(R.string.sim_onboarding_select_sim_title),
54 PrimarySim(R.string.sim_onboarding_primary_sim_title)
55 }
56
57 /**
58 * Showing the sim onboarding which is the process flow of sim switching on.
59 */
60 object SimOnboardingPageProvider : SettingsPageProvider {
61 override val name = "SimOnboardingPageProvider"
62 override val parameter = listOf(
<lambda>null63 navArgument(SUB_ID) { type = NavType.IntType },
64 )
65
66 private val owner = createSettingsPage()
67 @VisibleForTesting
68 var onboardingService: SimOnboardingService = SimOnboardingActivity.onboardingService
69
buildInjectEntrynull70 fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner = owner)
71 .setUiLayoutFn {
72 // never using
73 Preference(object : PreferenceModel {
74 override val title = name
75 override val onClick = navigator(getRoute(-1))
76 })
77 }
78
79 @Composable
Pagenull80 override fun Page(arguments: Bundle?) {
81 PageImpl(onboardingService,rememberNavController())
82 }
83
getRoutenull84 fun getRoute(
85 subId: Int
86 ): String = "${name}/$subId"
87 }
88
89 fun Context.getActivity(): Activity? = when (this) {
90 is Activity -> this
91 is ContextWrapper -> baseContext.getActivity()
92 else -> null
93 }
94
95 @Composable
PageImplnull96 fun PageImpl(onboardingService:SimOnboardingService,navHostController: NavHostController) {
97 val context = LocalContext.current
98 var finishOnboarding: () -> Unit = {
99 context.getActivity()?.finish()
100 onboardingService.callback(CallbackType.CALLBACK_FINISH)
101 }
102
103 NavHost(
104 navController = navHostController,
105 startDestination = SimOnboardingScreen.LabelSim.name
106 ) {
107 composable(route = SimOnboardingScreen.LabelSim.name) {
108 val nextPage =
109 if (onboardingService.isMultipleEnabledProfilesSupported
110 && onboardingService.isAllOfSlotAssigned
111 && !onboardingService.doesTargetSimActive) {
112 SimOnboardingScreen.SelectSim.name
113 } else {
114 LaunchedEffect(Unit) {
115 onboardingService.addCurrentItemForSelectedSim()
116 }
117 SimOnboardingScreen.PrimarySim.name
118 }
119 SimOnboardingLabelSimImpl(
120 nextAction = { navHostController.navigate(nextPage) },
121 cancelAction = finishOnboarding,
122 onboardingService = onboardingService
123 )
124 }
125 composable(route = SimOnboardingScreen.PrimarySim.name) {
126 SimOnboardingPrimarySimImpl(
127 nextAction = {
128 onboardingService.callback(CallbackType.CALLBACK_ONBOARDING_COMPLETE)
129 context.getActivity()?.finish()
130 },
131 cancelAction = finishOnboarding,
132 onboardingService = onboardingService
133 )
134 }
135 composable(route = SimOnboardingScreen.SelectSim.name) {
136 SimOnboardingSelectSimImpl(
137 nextAction = { navHostController.navigate(SimOnboardingScreen.PrimarySim.name) },
138 cancelAction = finishOnboarding,
139 onboardingService = onboardingService
140 )
141 }
142 }
143 }
144
145 @Composable
SimOnboardingMessagenull146 fun SimOnboardingMessage(text: String) {
147 Column(
148 Modifier.padding(
149 start = SettingsDimension.itemPaddingStart,
150 end = SettingsDimension.itemPaddingEnd,
151 bottom = SettingsDimension.paddingExtraLarge,
152 )
153 ) {
154 SettingsBody(text)
155 }
156 }
157