Compare commits

..

No commits in common. "5dacb7571788e8cfd9f271fa4dd514565e7e5502" and "7215a2351bd5e31c6a9cc79da48920d6ab5630be" have entirely different histories.

4 changed files with 87 additions and 6 deletions

View file

@ -113,7 +113,25 @@ open class DefaultEuiccChannelManager(
findEuiccChannelBySlot(logicalSlotId) findEuiccChannelBySlot(logicalSlotId)
} }
private suspend fun findAllEuiccChannelsByPhysicalSlot(physicalSlotId: Int): List<EuiccChannel>? { override fun findEuiccChannelByPhysicalSlotBlocking(physicalSlotId: Int): EuiccChannel? =
runBlocking {
withContext(Dispatchers.IO) {
if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) {
return@withContext usbChannel
}
for (card in uiccCards) {
if (card.physicalSlotIndex != physicalSlotId) continue
for (port in card.ports) {
tryOpenEuiccChannel(port)?.let { return@withContext it }
}
}
null
}
}
override suspend fun findAllEuiccChannelsByPhysicalSlot(physicalSlotId: Int): List<EuiccChannel>? {
if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) { if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) {
return usbChannel?.let { listOf(it) } return usbChannel?.let { listOf(it) }
} }
@ -126,6 +144,11 @@ open class DefaultEuiccChannelManager(
return null return null
} }
override fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>? =
runBlocking {
findAllEuiccChannelsByPhysicalSlot(physicalSlotId)
}
override suspend fun findEuiccChannelByPort(physicalSlotId: Int, portId: Int): EuiccChannel? = override suspend fun findEuiccChannelByPort(physicalSlotId: Int, portId: Int): EuiccChannel? =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) { if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) {

View file

@ -52,6 +52,20 @@ interface EuiccChannelManager {
*/ */
fun findEuiccChannelBySlotBlocking(logicalSlotId: Int): EuiccChannel? fun findEuiccChannelBySlotBlocking(logicalSlotId: Int): EuiccChannel?
/**
* Returns the first EuiccChannel corresponding to a **physical** slot
* If the physical slot supports MEP and has multiple ports, it is undefined
* which of the two channels will be returned.
*/
fun findEuiccChannelByPhysicalSlotBlocking(physicalSlotId: Int): EuiccChannel?
/**
* Returns all EuiccChannels corresponding to a **physical** slot
* Multiple channels are possible in the case of MEP
*/
suspend fun findAllEuiccChannelsByPhysicalSlot(physicalSlotId: Int): List<EuiccChannel>?
fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>?
/** /**
* Returns the EuiccChannel corresponding to a **physical** slot and a port ID * Returns the EuiccChannel corresponding to a **physical** slot and a port ID
*/ */

View file

@ -3,6 +3,9 @@ package im.angry.openeuicc.util
import android.util.Log import android.util.Log
import im.angry.openeuicc.core.EuiccChannel import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager import im.angry.openeuicc.core.EuiccChannelManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import net.typeblog.lpac_jni.LocalProfileAssistant import net.typeblog.lpac_jni.LocalProfileAssistant
import net.typeblog.lpac_jni.LocalProfileInfo import net.typeblog.lpac_jni.LocalProfileInfo
@ -105,4 +108,40 @@ suspend inline fun EuiccChannelManager.beginTrackedOperation(
} }
} }
Log.d(TAG, "Operation complete") Log.d(TAG, "Operation complete")
}
/**
* Same as beginTrackedOperation but uses blocking primitives.
* TODO: This function needs to be phased out of use.
*/
inline fun EuiccChannelManager.beginTrackedOperationBlocking(
slotId: Int,
portId: Int,
op: () -> Boolean
) {
val latestSeq =
findEuiccChannelByPortBlocking(slotId, portId)!!.lpa.notifications.firstOrNull()?.seqNumber
?: 0
Log.d(TAG, "Latest notification is $latestSeq before operation")
if (op()) {
Log.d(TAG, "Operation has requested notification handling")
try {
// Note that the exact instance of "channel" might have changed here if reconnected;
// so we MUST use the automatic getter for "channel"
findEuiccChannelByPortBlocking(
slotId,
portId
)?.lpa?.notifications?.filter { it.seqNumber > latestSeq }?.forEach {
Log.d(TAG, "Handling notification $it")
findEuiccChannelByPortBlocking(
slotId,
portId
)?.lpa?.handleNotification(it.seqNumber)
}
} catch (e: Exception) {
// Ignore any error during notification handling
e.printStackTrace()
}
}
Log.d(TAG, "Operation complete")
} }

View file

@ -42,6 +42,15 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
) { ) {
val euiccChannelManager val euiccChannelManager
get() = euiccChannelManagerService.euiccChannelManager get() = euiccChannelManagerService.euiccChannelManager
fun findChannel(physicalSlotId: Int): EuiccChannel? =
euiccChannelManager.findEuiccChannelByPhysicalSlotBlocking(physicalSlotId)
fun findChannel(slotId: Int, portId: Int): EuiccChannel? =
euiccChannelManager.findEuiccChannelByPortBlocking(slotId, portId)
fun findAllChannels(physicalSlotId: Int): List<EuiccChannel>? =
euiccChannelManager.findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId)
} }
/** /**
@ -79,11 +88,7 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
} }
override fun onGetEid(slotId: Int): String? = withEuiccChannelManager { override fun onGetEid(slotId: Int): String? = withEuiccChannelManager {
val portId = euiccChannelManager.findFirstAvailablePort(slotId) findChannel(slotId)?.lpa?.eID
if (portId < 0) return@withEuiccChannelManager null
euiccChannelManager.withEuiccChannel(slotId, portId) { channel ->
channel.lpa.eID
}
} }
// When two eSIM cards are present on one device, the Android settings UI // When two eSIM cards are present on one device, the Android settings UI