OpenEuiccService: Start migrating to withEuiccChannel()
All checks were successful
/ build-debug (push) Successful in 6m30s
All checks were successful
/ build-debug (push) Successful in 6m30s
This commit is contained in:
parent
32f5e3f71a
commit
22ec3e3baf
3 changed files with 77 additions and 35 deletions
|
@ -165,6 +165,15 @@ open class DefaultEuiccChannelManager(
|
|||
findEuiccChannelByPort(physicalSlotId, portId)
|
||||
}
|
||||
|
||||
override suspend fun findFirstAvailablePort(physicalSlotId: Int): Int =
|
||||
withContext(Dispatchers.IO) {
|
||||
if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) {
|
||||
return@withContext 0
|
||||
}
|
||||
|
||||
findAllEuiccChannelsByPhysicalSlot(physicalSlotId)?.getOrNull(0)?.portId ?: -1
|
||||
}
|
||||
|
||||
override suspend fun <R> withEuiccChannel(
|
||||
physicalSlotId: Int,
|
||||
portId: Int,
|
||||
|
|
|
@ -72,6 +72,12 @@ interface EuiccChannelManager {
|
|||
suspend fun findEuiccChannelByPort(physicalSlotId: Int, portId: Int): EuiccChannel?
|
||||
fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel?
|
||||
|
||||
/**
|
||||
* Returns the first mapped & available port ID for a physical slot, or -1 if
|
||||
* not found.
|
||||
*/
|
||||
suspend fun findFirstAvailablePort(physicalSlotId: Int): Int
|
||||
|
||||
class EuiccChannelNotFoundException: Exception("EuiccChannel not found")
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,7 @@ import im.angry.openeuicc.core.EuiccChannel
|
|||
import im.angry.openeuicc.core.EuiccChannelManager
|
||||
import im.angry.openeuicc.util.*
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.last
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
|
@ -37,8 +38,11 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
|
|||
}
|
||||
|
||||
private data class EuiccChannelManagerContext(
|
||||
val euiccChannelManager: EuiccChannelManager
|
||||
val euiccChannelManagerService: EuiccChannelManagerService
|
||||
) {
|
||||
val euiccChannelManager
|
||||
get() = euiccChannelManagerService.euiccChannelManager
|
||||
|
||||
fun findChannel(physicalSlotId: Int): EuiccChannel? =
|
||||
euiccChannelManager.findEuiccChannelByPhysicalSlotBlocking(physicalSlotId)
|
||||
|
||||
|
@ -59,7 +63,7 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
|
|||
*
|
||||
* This function cannot be inline because non-local returns may bypass the unbind
|
||||
*/
|
||||
private fun <T> withEuiccChannelManager(fn: EuiccChannelManagerContext.() -> T): T {
|
||||
private fun <T> withEuiccChannelManager(fn: suspend EuiccChannelManagerContext.() -> T): T {
|
||||
val (binder, unbind) = runBlocking {
|
||||
bindServiceSuspended(
|
||||
Intent(
|
||||
|
@ -73,8 +77,11 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
|
|||
throw RuntimeException("Unable to bind to EuiccChannelManagerService; aborting")
|
||||
}
|
||||
|
||||
val ret =
|
||||
EuiccChannelManagerContext((binder as EuiccChannelManagerService.LocalBinder).service.euiccChannelManager).fn()
|
||||
val localBinder = binder as EuiccChannelManagerService.LocalBinder
|
||||
|
||||
val ret = runBlocking {
|
||||
EuiccChannelManagerContext(localBinder.service).fn()
|
||||
}
|
||||
|
||||
unbind()
|
||||
return ret
|
||||
|
@ -177,38 +184,54 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
|
|||
}
|
||||
|
||||
// TODO: Temporarily enable the slot to access its profiles if it is currently unmapped
|
||||
val channel =
|
||||
findChannel(slotId) ?: return@withEuiccChannelManager GetEuiccProfileInfoListResult(
|
||||
val port = euiccChannelManager.findFirstAvailablePort(slotId)
|
||||
if (port == -1) {
|
||||
return@withEuiccChannelManager GetEuiccProfileInfoListResult(
|
||||
RESULT_FIRST_USER,
|
||||
arrayOf(),
|
||||
true
|
||||
)
|
||||
val profiles = channel.lpa.profiles.operational.map {
|
||||
EuiccProfileInfo.Builder(it.iccid).apply {
|
||||
setProfileName(it.name)
|
||||
setNickname(it.displayName)
|
||||
setServiceProviderName(it.providerName)
|
||||
setState(
|
||||
when (it.state) {
|
||||
LocalProfileInfo.State.Enabled -> EuiccProfileInfo.PROFILE_STATE_ENABLED
|
||||
LocalProfileInfo.State.Disabled -> EuiccProfileInfo.PROFILE_STATE_DISABLED
|
||||
}
|
||||
)
|
||||
setProfileClass(
|
||||
when (it.profileClass) {
|
||||
LocalProfileInfo.Clazz.Testing -> EuiccProfileInfo.PROFILE_CLASS_TESTING
|
||||
LocalProfileInfo.Clazz.Provisioning -> EuiccProfileInfo.PROFILE_CLASS_PROVISIONING
|
||||
LocalProfileInfo.Clazz.Operational -> EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
}
|
||||
|
||||
return@withEuiccChannelManager GetEuiccProfileInfoListResult(
|
||||
RESULT_OK,
|
||||
profiles.toTypedArray(),
|
||||
channel.port.card.isRemovable
|
||||
)
|
||||
try {
|
||||
return@withEuiccChannelManager euiccChannelManager.withEuiccChannel(
|
||||
slotId,
|
||||
port
|
||||
) { channel ->
|
||||
val profiles = channel.lpa.profiles.operational.map {
|
||||
EuiccProfileInfo.Builder(it.iccid).apply {
|
||||
setProfileName(it.name)
|
||||
setNickname(it.displayName)
|
||||
setServiceProviderName(it.providerName)
|
||||
setState(
|
||||
when (it.state) {
|
||||
LocalProfileInfo.State.Enabled -> EuiccProfileInfo.PROFILE_STATE_ENABLED
|
||||
LocalProfileInfo.State.Disabled -> EuiccProfileInfo.PROFILE_STATE_DISABLED
|
||||
}
|
||||
)
|
||||
setProfileClass(
|
||||
when (it.profileClass) {
|
||||
LocalProfileInfo.Clazz.Testing -> EuiccProfileInfo.PROFILE_CLASS_TESTING
|
||||
LocalProfileInfo.Clazz.Provisioning -> EuiccProfileInfo.PROFILE_CLASS_PROVISIONING
|
||||
LocalProfileInfo.Clazz.Operational -> EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
}
|
||||
|
||||
GetEuiccProfileInfoListResult(
|
||||
RESULT_OK,
|
||||
profiles.toTypedArray(),
|
||||
channel.port.card.isRemovable
|
||||
)
|
||||
}
|
||||
} catch (e: EuiccChannelManager.EuiccChannelNotFoundException) {
|
||||
return@withEuiccChannelManager GetEuiccProfileInfoListResult(
|
||||
RESULT_FIRST_USER,
|
||||
arrayOf(),
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGetEuiccInfo(slotId: Int): EuiccInfo {
|
||||
|
@ -335,13 +358,17 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
|
|||
"onUpdateSubscriptionNickname slotId=$slotId iccid=$iccid nickname=$nickname"
|
||||
)
|
||||
if (shouldIgnoreSlot(slotId)) return@withEuiccChannelManager RESULT_FIRST_USER
|
||||
val channel = findChannel(slotId) ?: return@withEuiccChannelManager RESULT_FIRST_USER
|
||||
if (!channel.profileExists(iccid)) {
|
||||
val port = euiccChannelManager.findFirstAvailablePort(slotId)
|
||||
if (port < 0) {
|
||||
return@withEuiccChannelManager RESULT_FIRST_USER
|
||||
}
|
||||
val success = channel.lpa
|
||||
.setNickname(iccid, nickname!!)
|
||||
appContainer.subscriptionManager.tryRefreshCachedEuiccInfo(channel.cardId)
|
||||
val success =
|
||||
(euiccChannelManagerService.launchProfileRenameTask(slotId, port, iccid, nickname!!)
|
||||
?.last() as? EuiccChannelManagerService.ForegroundTaskState.Done)?.error == null
|
||||
|
||||
euiccChannelManager.withEuiccChannel(slotId, port) { channel ->
|
||||
appContainer.subscriptionManager.tryRefreshCachedEuiccInfo(channel.cardId)
|
||||
}
|
||||
return@withEuiccChannelManager if (success) {
|
||||
RESULT_OK
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue