refactor: simplify profile switch logic in EuiccChannelManagerService

This commit is contained in:
septs 2025-03-07 20:41:14 +08:00
parent 71368b6fc5
commit dbad335366
Signed by: septs
SSH key fingerprint: SHA256:ElK0p6DNkbsqYUdJ3I9QHDVf21SQD0c2r+hd7s/r5Co

View file

@ -11,6 +11,7 @@ import androidx.core.app.NotificationManagerCompat
import androidx.lifecycle.LifecycleService
import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.*
import kotlinx.coroutines.Dispatchers
@ -446,31 +447,30 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
iccid: String,
enable: Boolean, // Enable or disable the profile indicated in iccid
reconnectTimeoutMillis: Long = 0 // 0 = do not wait for reconnect
): ForegroundTaskSubscriberFlow =
) =
launchForegroundTask(
getString(R.string.task_profile_switch),
getString(R.string.task_profile_switch_failure),
R.drawable.ic_task_switch
) {
euiccChannelManager.beginTrackedOperation(slotId, portId) {
val (res, refreshed) = euiccChannelManager.withEuiccChannel(
slotId,
portId
) { channel ->
val refresh = preferenceRepository.refreshAfterSwitchFlow.first()
if (!channel.lpa.switchProfile(iccid, enable, refresh = refresh)) {
// Sometimes, we *can* enable or disable the profile, but we cannot
// send the refresh command to the modem because the profile somehow
// makes the modem "busy". In this case, we can still switch by setting
// refresh to false, but then the switch cannot take effect until the
// user resets the modem manually by toggling airplane mode or rebooting.
Pair(channel.lpa.switchProfile(iccid, enable, refresh = false), false)
} else {
Pair(true, refresh)
}
}
suspend fun onSwitch(channel: EuiccChannel): Pair<Boolean, Boolean> {
val refresh = preferenceRepository.refreshAfterSwitchFlow.first()
val response = channel.lpa.switchProfile(iccid, enable, refresh)
if (response || !refresh) return Pair(response, refresh)
// refresh failed, but refresh was requested
// Sometimes, we *can* enable or disable the profile, but we cannot
// send the refresh command to the modem because the profile somehow
// makes the modem "busy". In this case, we can still switch by setting
// refresh to false, but then the switch cannot take effect until the
// user resets the modem manually by toggling airplane mode or rebooting.
return Pair(channel.lpa.switchProfile(iccid, enable, refresh = false), false)
}
if (!res) {
euiccChannelManager.beginTrackedOperation(slotId, portId) {
val (response, refreshed) =
euiccChannelManager.withEuiccChannel(slotId, portId, ::onSwitch)
if (!response) {
throw RuntimeException("Could not switch profile")
}