Compare commits
No commits in common. "7c0be54fd77784053d470789aa79381f47073a11" and "efeaea256708a892a44502969f4f24b5b3190088" have entirely different histories.
7c0be54fd7
...
efeaea2567
3 changed files with 32 additions and 56 deletions
|
@ -3,7 +3,7 @@ package im.angry.openeuicc.ui
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import im.angry.openeuicc.util.*
|
import im.angry.openeuicc.util.openEuiccApplication
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -16,21 +16,8 @@ class DirectProfileDownloadActivity : AppCompatActivity(), SlotSelectFragment.Sl
|
||||||
openEuiccApplication.euiccChannelManager.enumerateEuiccChannels()
|
openEuiccApplication.euiccChannelManager.enumerateEuiccChannels()
|
||||||
}
|
}
|
||||||
|
|
||||||
val knownChannels = openEuiccApplication.euiccChannelManager.knownChannels
|
SlotSelectFragment.newInstance()
|
||||||
when {
|
.show(supportFragmentManager, SlotSelectFragment.TAG)
|
||||||
knownChannels.isEmpty() -> {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
knownChannels.hasMultipleChips -> {
|
|
||||||
SlotSelectFragment.newInstance()
|
|
||||||
.show(supportFragmentManager, SlotSelectFragment.TAG)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// If the device has only one eSIM "chip" (but may be mapped to multiple slots),
|
|
||||||
// we can skip the slot selection dialog since there is only one chip to save to.
|
|
||||||
onSlotSelected(knownChannels[0].slotId, knownChannels[0].portId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,34 @@ fun SEService.getUiccReaderCompat(slotNumber: Int): Reader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an instance of OMAPI SEService in a manner that "makes sense" without unpredictable callbacks
|
||||||
|
suspend fun connectSEService(context: Context): SEService = suspendCoroutine { cont ->
|
||||||
|
// Use a Mutex to make sure the continuation is run *after* the "service" variable is assigned
|
||||||
|
val lock = Mutex()
|
||||||
|
var service: SEService? = null
|
||||||
|
val callback = {
|
||||||
|
runBlocking {
|
||||||
|
lock.withLock {
|
||||||
|
cont.resume(service!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runBlocking {
|
||||||
|
// If this were not protected by a Mutex, callback might be run before service is even assigned
|
||||||
|
// Yes, we are on Android, we could have used something like a Handler, but we cannot really
|
||||||
|
// assume the coroutine is run on a thread that has a Handler. We either use our own HandlerThread
|
||||||
|
// (and then cleanup becomes an issue), or we use a lock
|
||||||
|
lock.withLock {
|
||||||
|
try {
|
||||||
|
service = SEService(context, { it.run() }, callback)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
cont.resumeWithException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In the privileged version, the EuiccChannelManager should work
|
* In the privileged version, the EuiccChannelManager should work
|
||||||
* based on real Uicc{Card,Port}Info reported by TelephonyManager.
|
* based on real Uicc{Card,Port}Info reported by TelephonyManager.
|
||||||
|
|
|
@ -2,16 +2,8 @@ package im.angry.openeuicc.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.se.omapi.SEService
|
|
||||||
import im.angry.openeuicc.core.EuiccChannel
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import net.typeblog.lpac_jni.LocalProfileInfo
|
import net.typeblog.lpac_jni.LocalProfileInfo
|
||||||
import java.lang.RuntimeException
|
import java.lang.RuntimeException
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.coroutines.resumeWithException
|
|
||||||
import kotlin.coroutines.suspendCoroutine
|
|
||||||
|
|
||||||
val Context.selfAppVersion: String
|
val Context.selfAppVersion: String
|
||||||
get() =
|
get() =
|
||||||
|
@ -23,35 +15,4 @@ val Context.selfAppVersion: String
|
||||||
}
|
}
|
||||||
|
|
||||||
val LocalProfileInfo.isEnabled: Boolean
|
val LocalProfileInfo.isEnabled: Boolean
|
||||||
get() = state == LocalProfileInfo.State.Enabled
|
get() = state == LocalProfileInfo.State.Enabled
|
||||||
|
|
||||||
val List<EuiccChannel>.hasMultipleChips: Boolean
|
|
||||||
get() = distinctBy { it.slotId }.size > 1
|
|
||||||
|
|
||||||
// Create an instance of OMAPI SEService in a manner that "makes sense" without unpredictable callbacks
|
|
||||||
suspend fun connectSEService(context: Context): SEService = suspendCoroutine { cont ->
|
|
||||||
// Use a Mutex to make sure the continuation is run *after* the "service" variable is assigned
|
|
||||||
val lock = Mutex()
|
|
||||||
var service: SEService? = null
|
|
||||||
val callback = {
|
|
||||||
runBlocking {
|
|
||||||
lock.withLock {
|
|
||||||
cont.resume(service!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runBlocking {
|
|
||||||
// If this were not protected by a Mutex, callback might be run before service is even assigned
|
|
||||||
// Yes, we are on Android, we could have used something like a Handler, but we cannot really
|
|
||||||
// assume the coroutine is run on a thread that has a Handler. We either use our own HandlerThread
|
|
||||||
// (and then cleanup becomes an issue), or we use a lock
|
|
||||||
lock.withLock {
|
|
||||||
try {
|
|
||||||
service = SEService(context, { it.run() }, callback)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
cont.resumeWithException(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue