From 47b2a7060b2837e8f45cf9a7120856a4a015d664 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Tue, 28 Nov 2023 22:27:25 -0500 Subject: [PATCH] EuiccChannelManager: check privileges even in "unprivileged" mode There is no true "unprivileged" mode because we need carrier privileges either way. --- .../java/im/angry/openeuicc/core/EuiccChannelManager.kt | 9 +++++++++ app-common/src/main/res/values/strings.xml | 2 +- .../openeuicc/core/PrivilegedEuiccChannelManager.kt | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt index 369cab0..aaf1659 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt @@ -1,5 +1,6 @@ package im.angry.openeuicc.core +import android.annotation.SuppressLint import android.content.Context import android.os.Handler import android.os.HandlerThread @@ -16,6 +17,7 @@ import java.lang.IllegalArgumentException import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +@SuppressLint("MissingPermission") // We rely on ARA-based privileges, not READ_PRIVILEGED_PHONE_STATE open class EuiccChannelManager(protected val context: Context) { companion object { const val TAG = "EuiccChannelManager" @@ -33,6 +35,8 @@ open class EuiccChannelManager(protected val context: Context) { private val handler = Handler(HandlerThread("BaseEuiccChannelManager").also { it.start() }.looper) + protected open fun checkPrivileges() = tm.hasCarrierPrivileges() + private suspend fun connectSEService(): SEService = suspendCoroutine { cont -> handler.post { var service: SEService? = null @@ -99,12 +103,15 @@ open class EuiccChannelManager(protected val context: Context) { } fun findEuiccChannelBySlotBlocking(slotId: Int): EuiccChannel? = runBlocking { + if (!checkPrivileges()) return@runBlocking null withContext(Dispatchers.IO) { findEuiccChannelBySlot(slotId) } } suspend fun enumerateEuiccChannels() { + if (!checkPrivileges()) return + withContext(Dispatchers.IO) { ensureSEService() @@ -120,6 +127,8 @@ open class EuiccChannelManager(protected val context: Context) { get() = channels.toList() fun invalidate() { + if (!checkPrivileges()) return + for (channel in channels) { channel.close() } diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 785ba4e..ae6931f 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - No eUICC card on this device is accessible by this app.\nYou may want to try out the privileged OpenEUICC app instead. + No eUICC card on this device is accessible by this app.\nInsert a supported eUICC card, or try out the privileged OpenEUICC app instead. Enabled Disabled diff --git a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt index c149646..e7c19c9 100644 --- a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt +++ b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt @@ -9,6 +9,8 @@ import java.lang.Exception import java.lang.IllegalArgumentException class PrivilegedEuiccChannelManager(context: Context): EuiccChannelManager(context) { + override fun checkPrivileges() = true // TODO: Implement proper system app check + override fun tryOpenEuiccChannelPrivileged(uiccInfo: UiccCardInfo, channelInfo: EuiccChannelInfo): EuiccChannel? { if (uiccInfo.isEuicc && !uiccInfo.isRemovable) { Log.d(TAG, "Using TelephonyManager for slot ${uiccInfo.slotIndex}")