Make OpenEuiccUIContextMarker usable for services as well

This commit is contained in:
Peter Cai 2024-02-04 20:29:57 -05:00
parent 632b6b4931
commit 1c8918e7f0
9 changed files with 36 additions and 44 deletions

View file

@ -8,7 +8,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class DirectProfileDownloadActivity : AppCompatActivity(), SlotSelectFragment.SlotSelectedListener, OpenEuiccUIContextMarker {
class DirectProfileDownloadActivity : AppCompatActivity(), SlotSelectFragment.SlotSelectedListener, OpenEuiccContextMarker {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {

View file

@ -5,7 +5,7 @@ import androidx.fragment.app.Fragment
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.util.*
interface EuiccFragmentMarker: OpenEuiccUIContextMarker
interface EuiccFragmentMarker: OpenEuiccContextMarker
fun <T> newInstanceEuicc(clazz: Class<T>, slotId: Int, portId: Int, addArguments: Bundle.() -> Unit = {}): T where T: Fragment, T: EuiccFragmentMarker {
val instance = clazz.newInstance()

View file

@ -20,7 +20,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
open class MainActivity : AppCompatActivity(), OpenEuiccUIContextMarker {
open class MainActivity : AppCompatActivity(), OpenEuiccContextMarker {
companion object {
const val TAG = "MainActivity"
}

View file

@ -27,7 +27,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.typeblog.lpac_jni.LocalProfileNotification
class NotificationsActivity: AppCompatActivity(), OpenEuiccUIContextMarker {
class NotificationsActivity: AppCompatActivity(), OpenEuiccContextMarker {
private lateinit var swipeRefresh: SwipeRefreshLayout
private lateinit var notificationList: RecyclerView
private val notificationAdapter = NotificationAdapter()

View file

@ -12,7 +12,7 @@ import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.util.*
class SlotSelectFragment : BaseMaterialDialogFragment(), OpenEuiccUIContextMarker {
class SlotSelectFragment : BaseMaterialDialogFragment(), OpenEuiccContextMarker {
companion object {
const val TAG = "SlotSelectFragment"

View file

@ -1,32 +1,9 @@
package im.angry.openeuicc.util
import android.content.Context
import android.content.res.Resources
import android.graphics.Rect
import android.telephony.TelephonyManager
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.core.EuiccChannelManager
interface OpenEuiccUIContextMarker
val OpenEuiccUIContextMarker.context: Context
get() = when (this) {
is Context -> this
is Fragment -> requireContext()
else -> throw RuntimeException("OpenEuiccUIContextMarker shall only be used on Fragments or UI types that derive from Context")
}
val OpenEuiccUIContextMarker.openEuiccApplication: OpenEuiccApplication
get() = context.applicationContext as OpenEuiccApplication
val OpenEuiccUIContextMarker.euiccChannelManager: EuiccChannelManager
get() = openEuiccApplication.euiccChannelManager
val OpenEuiccUIContextMarker.telephonyManager: TelephonyManager
get() = openEuiccApplication.telephonyManager
// Source: <https://stackoverflow.com/questions/12478520/how-to-set-dialogfragments-width-and-height>
/**

View file

@ -3,7 +3,11 @@ package im.angry.openeuicc.util
import android.content.Context
import android.content.pm.PackageManager
import android.se.omapi.SEService
import android.telephony.TelephonyManager
import androidx.fragment.app.Fragment
import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@ -22,6 +26,24 @@ val Context.selfAppVersion: String
throw RuntimeException(e)
}
interface OpenEuiccContextMarker
val OpenEuiccContextMarker.context: Context
get() = when (this) {
is Context -> this
is Fragment -> requireContext()
else -> throw RuntimeException("OpenEuiccUIContextMarker shall only be used on Fragments or UI types that derive from Context")
}
val OpenEuiccContextMarker.openEuiccApplication: OpenEuiccApplication
get() = context.applicationContext as OpenEuiccApplication
val OpenEuiccContextMarker.euiccChannelManager: EuiccChannelManager
get() = openEuiccApplication.euiccChannelManager
val OpenEuiccContextMarker.telephonyManager: TelephonyManager
get() = openEuiccApplication.telephonyManager
val LocalProfileInfo.isEnabled: Boolean
get() = state == LocalProfileInfo.State.Enabled

View file

@ -6,30 +6,23 @@ import android.telephony.euicc.DownloadableSubscription
import android.telephony.euicc.EuiccInfo
import android.util.Log
import net.typeblog.lpac_jni.LocalProfileInfo
import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.util.*
import java.lang.IllegalStateException
class OpenEuiccService : EuiccService() {
class OpenEuiccService : EuiccService(), OpenEuiccContextMarker {
companion object {
const val TAG = "OpenEuiccService"
}
private val openEuiccApplication
get() = application as OpenEuiccApplication
private fun findChannel(physicalSlotId: Int): EuiccChannel? =
openEuiccApplication.euiccChannelManager
.findEuiccChannelByPhysicalSlotBlocking(physicalSlotId)
euiccChannelManager.findEuiccChannelByPhysicalSlotBlocking(physicalSlotId)
private fun findChannel(slotId: Int, portId: Int): EuiccChannel? =
openEuiccApplication.euiccChannelManager
.findEuiccChannelByPortBlocking(slotId, portId)
euiccChannelManager.findEuiccChannelByPortBlocking(slotId, portId)
private fun findAllChannels(physicalSlotId: Int): List<EuiccChannel>? =
openEuiccApplication.euiccChannelManager
.findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId)
euiccChannelManager.findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId)
override fun onGetEid(slotId: Int): String? =
findChannel(slotId)?.lpa?.eID
@ -41,7 +34,7 @@ class OpenEuiccService : EuiccService() {
lpa.profiles.any { it.iccid == iccid }
private fun ensurePortIsMapped(slotId: Int, portId: Int) {
val mappings = openEuiccApplication.telephonyManager.simSlotMapping.toMutableList()
val mappings = telephonyManager.simSlotMapping.toMutableList()
mappings.firstOrNull { it.physicalSlotIndex == slotId && it.portIndex == portId }?.let {
throw IllegalStateException("Slot $slotId port $portId has already been mapped")
@ -57,14 +50,14 @@ class OpenEuiccService : EuiccService() {
}
try {
openEuiccApplication.telephonyManager.simSlotMapping = mappings
telephonyManager.simSlotMapping = mappings
return
} catch (_: Exception) {
}
// Sometimes hardware supports one ordering but not the reverse
openEuiccApplication.telephonyManager.simSlotMapping = mappings.reversed()
telephonyManager.simSlotMapping = mappings.reversed()
}
private fun <T> retryWithTimeout(timeoutMillis: Int, backoff: Int = 1000, f: () -> T?): T? {
@ -233,7 +226,7 @@ class OpenEuiccService : EuiccService() {
} catch (e: Exception) {
return RESULT_FIRST_USER
} finally {
openEuiccApplication.euiccChannelManager.invalidate()
euiccChannelManager.invalidate()
}
}

View file

@ -27,7 +27,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class SlotMappingFragment: BaseMaterialDialogFragment(),
OnMenuItemClickListener, OpenEuiccUIContextMarker {
OnMenuItemClickListener, OpenEuiccContextMarker {
companion object {
const val TAG = "SlotMappingFragment"
}