|
@@ -1,5 +1,6 @@
|
|
|
package im.angry.openeuicc.core
|
|
package im.angry.openeuicc.core
|
|
|
|
|
|
|
|
|
|
+import android.annotation.SuppressLint
|
|
|
import android.content.Context
|
|
import android.content.Context
|
|
|
import android.os.Handler
|
|
import android.os.Handler
|
|
|
import android.os.HandlerThread
|
|
import android.os.HandlerThread
|
|
@@ -16,6 +17,7 @@ import java.lang.IllegalArgumentException
|
|
|
import kotlin.coroutines.resume
|
|
import kotlin.coroutines.resume
|
|
|
import kotlin.coroutines.suspendCoroutine
|
|
import kotlin.coroutines.suspendCoroutine
|
|
|
|
|
|
|
|
|
|
+@SuppressLint("MissingPermission") // We rely on ARA-based privileges, not READ_PRIVILEGED_PHONE_STATE
|
|
|
open class EuiccChannelManager(protected val context: Context) {
|
|
open class EuiccChannelManager(protected val context: Context) {
|
|
|
companion object {
|
|
companion object {
|
|
|
const val TAG = "EuiccChannelManager"
|
|
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)
|
|
private val handler = Handler(HandlerThread("BaseEuiccChannelManager").also { it.start() }.looper)
|
|
|
|
|
|
|
|
|
|
+ protected open fun checkPrivileges() = tm.hasCarrierPrivileges()
|
|
|
|
|
+
|
|
|
private suspend fun connectSEService(): SEService = suspendCoroutine { cont ->
|
|
private suspend fun connectSEService(): SEService = suspendCoroutine { cont ->
|
|
|
handler.post {
|
|
handler.post {
|
|
|
var service: SEService? = null
|
|
var service: SEService? = null
|
|
@@ -99,12 +103,15 @@ open class EuiccChannelManager(protected val context: Context) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fun findEuiccChannelBySlotBlocking(slotId: Int): EuiccChannel? = runBlocking {
|
|
fun findEuiccChannelBySlotBlocking(slotId: Int): EuiccChannel? = runBlocking {
|
|
|
|
|
+ if (!checkPrivileges()) return@runBlocking null
|
|
|
withContext(Dispatchers.IO) {
|
|
withContext(Dispatchers.IO) {
|
|
|
findEuiccChannelBySlot(slotId)
|
|
findEuiccChannelBySlot(slotId)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
suspend fun enumerateEuiccChannels() {
|
|
suspend fun enumerateEuiccChannels() {
|
|
|
|
|
+ if (!checkPrivileges()) return
|
|
|
|
|
+
|
|
|
withContext(Dispatchers.IO) {
|
|
withContext(Dispatchers.IO) {
|
|
|
ensureSEService()
|
|
ensureSEService()
|
|
|
|
|
|
|
@@ -120,6 +127,8 @@ open class EuiccChannelManager(protected val context: Context) {
|
|
|
get() = channels.toList()
|
|
get() = channels.toList()
|
|
|
|
|
|
|
|
fun invalidate() {
|
|
fun invalidate() {
|
|
|
|
|
+ if (!checkPrivileges()) return
|
|
|
|
|
+
|
|
|
for (channel in channels) {
|
|
for (channel in channels) {
|
|
|
channel.close()
|
|
channel.close()
|
|
|
}
|
|
}
|