diff --git a/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt index 6636bc1..5c7d217 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt @@ -27,34 +27,6 @@ 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 * based on real Uicc{Card,Port}Info reported by TelephonyManager. diff --git a/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt b/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt index cc89df3..5d4221e 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt @@ -2,9 +2,16 @@ package im.angry.openeuicc.util import android.content.Context 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 java.lang.RuntimeException +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine val Context.selfAppVersion: String get() = @@ -19,4 +26,32 @@ val LocalProfileInfo.isEnabled: Boolean get() = state == LocalProfileInfo.State.Enabled val List.hasMultipleChips: Boolean - get() = distinctBy { it.slotId }.size > 1 \ No newline at end of file + 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) + } + } + } +} \ No newline at end of file