Add the mechanism of enable DSDS

When the user click the "set up" on sim onboarding BottomSheet, settings
enable the DSDS mode and then start the sim onboarding flow

Bug: 318310357
Bug: 298898436
Bug: 298891941
Test: build pass and verify the UI flow
Change-Id: Ibd4fc2f482019f02738c3fedef7af7f4ef9b8e50
This commit is contained in:
songferngwang
2024-03-06 22:39:28 +00:00
parent 29286ec8c3
commit 2b5002ae6a
3 changed files with 198 additions and 82 deletions

View File

@@ -11667,6 +11667,13 @@
<!-- Body text of automatic data switching at dual sim onboarding's primary sim page or SIMs page. [CHAR LIMIT=NONE] --> <!-- Body text of automatic data switching at dual sim onboarding's primary sim page or SIMs page. [CHAR LIMIT=NONE] -->
<string name="primary_sim_automatic_data_msg">Use data from either SIM depending on coverage and availability</string> <string name="primary_sim_automatic_data_msg">Use data from either SIM depending on coverage and availability</string>
<!-- Title of asking the user whether to restart device after enabling DSDS. [CHAR LIMIT=NONE] -->
<string name="sim_action_restart_dialog_title">Restart to use 2 SIMs</string>
<!-- Body text of asking the user whether to restart device after enabling DSDS. [CHAR LIMIT=NONE] -->
<string name="sim_action_restart_dialog_msg">To use 2 SIMs at once, restart your device, then turn on both SIMs</string>
<!-- Button text to cancel dialog and then enable the sim -->
<string name="sim_action_restart_dialog_cancel">Use <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g> only</string>
<!-- Text of phone number item when the sim is data only. [CHAR LIMIT=NONE] --> <!-- Text of phone number item when the sim is data only. [CHAR LIMIT=NONE] -->
<string name="sim_onboarding_phoneNumber_data_only">Data only</string> <string name="sim_onboarding_phoneNumber_data_only">Data only</string>

View File

@@ -21,7 +21,6 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import android.util.Log import android.util.Log
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@@ -45,7 +44,6 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
@@ -67,7 +65,6 @@ import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import com.android.settingslib.spa.widget.dialog.AlertDialogButton import com.android.settingslib.spa.widget.dialog.AlertDialogButton
import com.android.settingslib.spa.widget.dialog.getDialogWidth import com.android.settingslib.spa.widget.dialog.getDialogWidth
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField
import com.android.settingslib.spa.widget.ui.SettingsTitle import com.android.settingslib.spa.widget.ui.SettingsTitle
import com.android.settingslib.spaprivileged.framework.common.userManager import com.android.settingslib.spaprivileged.framework.common.userManager
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -83,6 +80,8 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
lateinit var showBottomSheet: MutableState<Boolean> lateinit var showBottomSheet: MutableState<Boolean>
lateinit var showError: MutableState<ErrorType> lateinit var showError: MutableState<ErrorType>
lateinit var showProgressDialog: MutableState<Boolean> lateinit var showProgressDialog: MutableState<Boolean>
lateinit var showDsdsProgressDialog: MutableState<Boolean>
lateinit var showRestartDialog: MutableState<Boolean>
private var switchToEuiccSubscriptionSidecar: SwitchToEuiccSubscriptionSidecar? = null private var switchToEuiccSubscriptionSidecar: SwitchToEuiccSubscriptionSidecar? = null
private var switchToRemovableSlotSidecar: SwitchToRemovableSlotSidecar? = null private var switchToRemovableSlotSidecar: SwitchToRemovableSlotSidecar? = null
@@ -132,6 +131,12 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
setProgressDialog(false) setProgressDialog(false)
} }
CallbackType.CALLBACK_ENABLE_DSDS-> {
scope.launch {
onboardingService.startEnableDsds(this@SimOnboardingActivity)
}
}
CallbackType.CALLBACK_ONBOARDING_COMPLETE -> { CallbackType.CALLBACK_ONBOARDING_COMPLETE -> {
showBottomSheet.value = false showBottomSheet.value = false
setProgressDialog(true) setProgressDialog(true)
@@ -179,12 +184,14 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
showBottomSheet = remember { mutableStateOf(false) } showBottomSheet = remember { mutableStateOf(false) }
showError = remember { mutableStateOf(ErrorType.ERROR_NONE) } showError = remember { mutableStateOf(ErrorType.ERROR_NONE) }
showProgressDialog = remember { mutableStateOf(false) } showProgressDialog = remember { mutableStateOf(false) }
showDsdsProgressDialog = remember { mutableStateOf(false) }
showRestartDialog = remember { mutableStateOf(false) }
scope = rememberCoroutineScope() scope = rememberCoroutineScope()
registerSidecarReceiverFlow() registerSidecarReceiverFlow()
ErrorDialogImpl() ErrorDialogImpl()
RestartDialogImpl()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
if (onboardingService.activeSubInfoList.isNotEmpty()) { if (onboardingService.activeSubInfoList.isNotEmpty()) {
showBottomSheet.value = true showBottomSheet.value = true
@@ -196,29 +203,76 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
BottomSheetImpl( BottomSheetImpl(
sheetState = sheetState, sheetState = sheetState,
nextAction = { nextAction = {
// TODO: if the phone is SS mode and the isDsdsConditionSatisfied is true, then if (onboardingService.isDsdsConditionSatisfied()) {
// enable the DSDS mode. // TODO: if the phone is SS mode and the isDsdsConditionSatisfied is true,
// case#1: the device need the reboot after enabling DSDS. Showing the confirm // then enable the DSDS mode.
// dialog to user whether reboot device or not. // case#1: the device need the reboot after enabling DSDS. Showing the
// case#2: The device don't need the reboot. Enabling DSDS and then showing // confirm dialog to user whether reboot device or not.
// the SIM onboarding UI. // case#2: The device don't need the reboot. Enabling DSDS and then showing
// the SIM onboarding UI.
// case#2 if (onboardingService.doesSwitchMultiSimConfigTriggerReboot) {
val route = getRoute(onboardingService.targetSubId) // case#1
startSpaActivity(route) Log.d(TAG, "Device does not support reboot free DSDS.")
showRestartDialog.value = true
} else {
// case#2
Log.d(TAG, "Enable DSDS mode")
showDsdsProgressDialog.value = true
enableMultiSimSidecar?.run(SimOnboardingService.NUM_OF_SIMS_FOR_DSDS)
}
} else {
startSimOnboardingProvider()
}
}, },
cancelAction = { finish() }, cancelAction = { finish() },
) )
} }
if(showProgressDialog.value) { if (showProgressDialog.value) {
ProgressDialogImpl() ProgressDialogImpl(
stringResource(
R.string.sim_onboarding_progressbar_turning_sim_on,
onboardingService.targetSubInfo?.displayName ?: ""
)
)
}
if (showDsdsProgressDialog.value) {
ProgressDialogImpl(
stringResource(R.string.sim_action_enabling_sim_without_carrier_name)
)
}
}
@Composable
private fun RestartDialogImpl() {
val restartDialogPresenter = rememberAlertDialogPresenter(
confirmButton = AlertDialogButton(
stringResource(R.string.sim_action_reboot)
) {
callbackListener(CallbackType.CALLBACK_ENABLE_DSDS)
},
dismissButton = AlertDialogButton(
stringResource(
R.string.sim_action_restart_dialog_cancel,
onboardingService.targetSubInfo?.displayName ?: "")
) {
callbackListener(CallbackType.CALLBACK_ONBOARDING_COMPLETE)
},
title = stringResource(R.string.sim_action_restart_dialog_title),
text = {
Text(stringResource(R.string.sim_action_restart_dialog_msg))
},
)
if(showRestartDialog.value){
LaunchedEffect(Unit) {
restartDialogPresenter.open()
}
} }
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ProgressDialogImpl() { fun ProgressDialogImpl(title: String) {
// TODO: Create the SPA's ProgressDialog and using SPA's widget // TODO: Create the SPA's ProgressDialog and using SPA's widget
BasicAlertDialog( BasicAlertDialog(
onDismissRequest = {}, onDismissRequest = {},
@@ -232,19 +286,14 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(SettingsDimension.itemPaddingStart), .padding(SettingsDimension.itemPaddingStart),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
CircularProgressIndicator() CircularProgressIndicator()
Column(modifier = Modifier Column(modifier = Modifier
.padding(start = SettingsDimension.itemPaddingStart)) { .padding(start = SettingsDimension.itemPaddingStart)) {
SettingsTitle( SettingsTitle(title)
stringResource(
R.string.sim_onboarding_progressbar_turning_sim_on,
onboardingService.targetSubInfo?.displayName ?: ""
)
)
} }
} }
} }
@@ -329,7 +378,7 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
Log.e(TAG, "Error while sidecarReceiverFlow", e) Log.e(TAG, "Error while sidecarReceiverFlow", e)
}.conflate() }.conflate()
fun startSimSwitching(){ fun startSimSwitching() {
Log.d(TAG, "startSimSwitching:") Log.d(TAG, "startSimSwitching:")
var targetSubInfo = onboardingService.targetSubInfo var targetSubInfo = onboardingService.targetSubInfo
@@ -376,8 +425,6 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
switchToEuiccSubscriptionSidecar!!.reset() switchToEuiccSubscriptionSidecar!!.reset()
showError.value = ErrorType.ERROR_EUICC_SLOT showError.value = ErrorType.ERROR_EUICC_SLOT
callbackListener(CallbackType.CALLBACK_ERROR) callbackListener(CallbackType.CALLBACK_ERROR)
// TODO: showErrorDialog and using privileged_action_disable_fail_title and
// privileged_action_disable_fail_text
} }
} }
} }
@@ -396,18 +443,19 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
switchToRemovableSlotSidecar!!.reset() switchToRemovableSlotSidecar!!.reset()
showError.value = ErrorType.ERROR_REMOVABLE_SLOT showError.value = ErrorType.ERROR_REMOVABLE_SLOT
callbackListener(CallbackType.CALLBACK_ERROR) callbackListener(CallbackType.CALLBACK_ERROR)
// TODO: showErrorDialog and using sim_action_enable_sim_fail_title and
// sim_action_enable_sim_fail_text
} }
} }
} }
fun handleEnableMultiSimSidecarStateChange() { fun handleEnableMultiSimSidecarStateChange() {
showDsdsProgressDialog.value = false
when (enableMultiSimSidecar!!.state) { when (enableMultiSimSidecar!!.state) {
SidecarFragment.State.SUCCESS -> { SidecarFragment.State.SUCCESS -> {
enableMultiSimSidecar!!.reset() enableMultiSimSidecar!!.reset()
Log.i(TAG, "Successfully switched to DSDS without reboot.") Log.i(TAG, "Successfully switched to DSDS without reboot.")
handleEnableSubscriptionAfterEnablingDsds() // refresh data
initServiceData(this, onboardingService.targetSubId, callbackListener)
startSimOnboardingProvider()
} }
SidecarFragment.State.ERROR -> { SidecarFragment.State.ERROR -> {
@@ -415,34 +463,14 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
Log.i(TAG, "Failed to switch to DSDS without rebooting.") Log.i(TAG, "Failed to switch to DSDS without rebooting.")
showError.value = ErrorType.ERROR_ENABLE_DSDS showError.value = ErrorType.ERROR_ENABLE_DSDS
callbackListener(CallbackType.CALLBACK_ERROR) callbackListener(CallbackType.CALLBACK_ERROR)
// TODO: showErrorDialog and using dsds_activation_failure_title and
// dsds_activation_failure_body_msg2
} }
} }
} }
fun handleEnableSubscriptionAfterEnablingDsds() {
var targetSubInfo = onboardingService.targetSubInfo
if (targetSubInfo?.isEmbedded == true) {
Log.i(TAG,
"DSDS enabled, start to enable profile: " + targetSubInfo.getSubscriptionId()
)
// For eSIM operations, we simply switch to the selected eSIM profile.
switchToEuiccSubscriptionSidecar!!.run(
targetSubInfo.subscriptionId,
UiccSlotUtil.INVALID_PORT_ID,
null
)
return
}
Log.i(TAG, "DSDS enabled, start to enable pSIM profile.")
onboardingService.handleTogglePsimAction()
callbackListener(CallbackType.CALLBACK_FINISH)
}
@Composable @Composable
fun BottomSheetBody(nextAction: () -> Unit) { fun BottomSheetBody(nextAction: () -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(bottom = SettingsDimension.itemPaddingVertical)) { Column(horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(bottom = SettingsDimension.itemPaddingVertical)) {
Icon( Icon(
imageVector = Icons.Outlined.SignalCellularAlt, imageVector = Icons.Outlined.SignalCellularAlt,
contentDescription = null, contentDescription = null,
@@ -497,6 +525,11 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
onboardingService.initData(targetSubId, context,callback) onboardingService.initData(targetSubId, context,callback)
} }
private fun startSimOnboardingProvider() {
val route = getRoute(onboardingService.targetSubId)
startSpaActivity(route)
}
companion object { companion object {
@JvmStatic @JvmStatic
fun startSimOnboardingActivity( fun startSimOnboardingActivity(
@@ -523,9 +556,10 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
enum class CallbackType(val value:Int){ enum class CallbackType(val value:Int){
CALLBACK_ERROR(-1), CALLBACK_ERROR(-1),
CALLBACK_ONBOARDING_COMPLETE(1), CALLBACK_ONBOARDING_COMPLETE(1),
CALLBACK_SETUP_NAME(2), CALLBACK_ENABLE_DSDS(2),
CALLBACK_SETUP_PRIMARY_SIM(3), CALLBACK_SETUP_NAME(3),
CALLBACK_FINISH(4) CALLBACK_SETUP_PRIMARY_SIM(4),
CALLBACK_FINISH(5)
} }
} }
} }

View File

@@ -24,6 +24,7 @@ import android.telephony.UiccCardInfo
import android.telephony.UiccSlotInfo import android.telephony.UiccSlotInfo
import android.util.Log import android.util.Log
import com.android.settings.network.SimOnboardingActivity.Companion.CallbackType import com.android.settings.network.SimOnboardingActivity.Companion.CallbackType
import com.android.settings.sim.SimActivationNotifier
import com.android.settings.spa.network.setAutomaticData import com.android.settings.spa.network.setAutomaticData
import com.android.settings.spa.network.setDefaultData import com.android.settings.spa.network.setDefaultData
import com.android.settings.spa.network.setDefaultSms import com.android.settings.spa.network.setDefaultSms
@@ -32,9 +33,6 @@ import com.android.settingslib.utils.ThreadUtils
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
private const val TAG = "SimOnboardingService"
private const val INVALID = SubscriptionManager.INVALID_SUBSCRIPTION_ID
class SimOnboardingService { class SimOnboardingService {
var subscriptionManager:SubscriptionManager? = null var subscriptionManager:SubscriptionManager? = null
var telephonyManager:TelephonyManager? = null var telephonyManager:TelephonyManager? = null
@@ -70,7 +68,7 @@ class SimOnboardingService {
} }
return uiccCardInfoList.any { it.isMultipleEnabledProfilesSupported } return uiccCardInfoList.any { it.isMultipleEnabledProfilesSupported }
} }
var isRemovableSimEnabled: Boolean = false var isRemovablePsimProfileEnabled: Boolean = false
get() { get() {
if(slotInfoList.isEmpty()) { if(slotInfoList.isEmpty()) {
Log.w(TAG, "UICC Slot info list is empty.") Log.w(TAG, "UICC Slot info list is empty.")
@@ -78,7 +76,11 @@ class SimOnboardingService {
} }
return UiccSlotUtil.isRemovableSimEnabled(slotInfoList) return UiccSlotUtil.isRemovableSimEnabled(slotInfoList)
} }
var isEsimProfileEnabled: Boolean = false
get() {
activeSubInfoList.stream().anyMatch { it.isEmbedded }
return false
}
var doesTargetSimHaveEsimOperation = false var doesTargetSimHaveEsimOperation = false
get() { get() {
return targetSubInfo?.isEmbedded ?: false return targetSubInfo?.isEmbedded ?: false
@@ -109,6 +111,19 @@ class SimOnboardingService {
} }
return getActiveModemCount != 0 && activeSubInfoList.size == getActiveModemCount return getActiveModemCount != 0 && activeSubInfoList.size == getActiveModemCount
} }
var isMultiSimEnabled = false
get() {
return getActiveModemCount > 1
}
var isMultiSimSupported = false
get() {
return telephonyManager?.isMultiSimSupported == TelephonyManager.MULTISIM_ALLOWED
}
var doesSwitchMultiSimConfigTriggerReboot = false
get() {
return telephonyManager?.doesSwitchMultiSimConfigTriggerReboot() ?: false
}
fun isValid(): Boolean { fun isValid(): Boolean {
return targetSubId != INVALID return targetSubId != INVALID
@@ -161,9 +176,10 @@ class SimOnboardingService {
targetPrimarySimCalls = SubscriptionManager.getDefaultVoiceSubscriptionId() targetPrimarySimCalls = SubscriptionManager.getDefaultVoiceSubscriptionId()
targetPrimarySimTexts = SubscriptionManager.getDefaultSmsSubscriptionId() targetPrimarySimTexts = SubscriptionManager.getDefaultSmsSubscriptionId()
targetPrimarySimMobileData = SubscriptionManager.getDefaultDataSubscriptionId() targetPrimarySimMobileData = SubscriptionManager.getDefaultDataSubscriptionId()
Log.d( Log.d(
TAG,"doesTargetSimHaveEsimOperation: $doesTargetSimHaveEsimOperation" + TAG,"doesTargetSimHaveEsimOperation: $doesTargetSimHaveEsimOperation" +
", isRemovableSimEnabled: $isRemovableSimEnabled" + ", isRemovableSimEnabled: $isRemovablePsimProfileEnabled" +
", isMultipleEnabledProfilesSupported: $isMultipleEnabledProfilesSupported" + ", isMultipleEnabledProfilesSupported: $isMultipleEnabledProfilesSupported" +
", targetPrimarySimCalls: $targetPrimarySimCalls" + ", targetPrimarySimCalls: $targetPrimarySimCalls" +
", targetPrimarySimTexts: $targetPrimarySimTexts" + ", targetPrimarySimTexts: $targetPrimarySimTexts" +
@@ -261,6 +277,45 @@ class SimOnboardingService {
} }
} }
fun isDsdsConditionSatisfied(): Boolean {
if (isMultiSimEnabled) {
Log.d(
TAG,
"DSDS is already enabled. Condition not satisfied."
)
return false
}
if (!isMultiSimSupported) {
Log.d(TAG, "Hardware does not support DSDS.")
return false
}
val isActiveSim = activeSubInfoList.isNotEmpty()
if (isMultipleEnabledProfilesSupported && isActiveSim) {
Log.d(TAG,
"Device supports MEP and eSIM operation and eSIM profile is enabled."
+ " DSDS condition satisfied."
)
return true
}
if (doesTargetSimHaveEsimOperation && isRemovablePsimProfileEnabled) {
Log.d(TAG,
"eSIM operation and removable PSIM is enabled. DSDS condition satisfied."
)
return true
}
if (!doesTargetSimHaveEsimOperation && isEsimProfileEnabled) {
Log.d(TAG,
"Removable SIM operation and eSIM profile is enabled. DSDS condition"
+ " satisfied."
)
return true
}
Log.d(TAG, "DSDS condition not satisfied.")
return false
}
fun startActivatingSim(){ fun startActivatingSim(){
// TODO: start to activate sim // TODO: start to activate sim
callback(CallbackType.CALLBACK_FINISH) callback(CallbackType.CALLBACK_FINISH)
@@ -281,30 +336,50 @@ class SimOnboardingService {
suspend fun startSetupPrimarySim(context: Context) { suspend fun startSetupPrimarySim(context: Context) {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
setDefaultVoice(subscriptionManager,targetPrimarySimCalls) if (SubscriptionUtil.getActiveSubscriptions(subscriptionManager).size <= 1) {
setDefaultSms(subscriptionManager,targetPrimarySimTexts) Log.d(TAG,
setDefaultData( "startSetupPrimarySim: number of active subscriptionInfo is less than 2"
context, )
subscriptionManager, } else {
null, setDefaultVoice(subscriptionManager, targetPrimarySimCalls)
targetPrimarySimMobileData setDefaultSms(subscriptionManager, targetPrimarySimTexts)
) setDefaultData(
context,
subscriptionManager,
null,
targetPrimarySimMobileData
)
var nonDds = targetNonDds var nonDds = targetNonDds
Log.d( Log.d(
TAG, TAG,
"setAutomaticData: targetNonDds: $nonDds," + "setAutomaticData: targetNonDds: $nonDds," +
" targetPrimarySimAutoDataSwitch: $targetPrimarySimAutoDataSwitch" " targetPrimarySimAutoDataSwitch: $targetPrimarySimAutoDataSwitch"
) )
if (nonDds != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { if (nonDds != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
val telephonyManagerForNonDds: TelephonyManager? = val telephonyManagerForNonDds: TelephonyManager? =
context.getSystemService(TelephonyManager::class.java) context.getSystemService(TelephonyManager::class.java)
?.createForSubscriptionId(nonDds) ?.createForSubscriptionId(nonDds)
setAutomaticData(telephonyManagerForNonDds, targetPrimarySimAutoDataSwitch) setAutomaticData(telephonyManagerForNonDds, targetPrimarySimAutoDataSwitch)
}
} }
// no next action, send finish // no next action, send finish
callback(CallbackType.CALLBACK_FINISH) callback(CallbackType.CALLBACK_FINISH)
} }
} }
suspend fun startEnableDsds(context: Context) {
withContext(Dispatchers.Default) {
Log.d(TAG, "User confirmed reboot to enable DSDS.")
SimActivationNotifier.setShowSimSettingsNotification(context, true)
telephonyManager?.switchMultiSimConfig(NUM_OF_SIMS_FOR_DSDS)
callback(CallbackType.CALLBACK_FINISH)
}
}
companion object{
private const val TAG = "SimOnboardingService"
private const val INVALID = SubscriptionManager.INVALID_SUBSCRIPTION_ID
const val NUM_OF_SIMS_FOR_DSDS = 2
}
} }