| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- package im.angry.openeuicc.util
- import android.os.Bundle
- import android.util.Log
- import androidx.fragment.app.Fragment
- import im.angry.openeuicc.core.EuiccChannel
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.withContext
- import net.typeblog.lpac_jni.LocalProfileAssistant
- private const val TAG = "EuiccChannelFragmentUtils"
- interface EuiccChannelFragmentMarker: OpenEuiccContextMarker
- // We must use extension functions because there is no way to add bounds to the type of "self"
- // in the definition of an interface, so the only way is to limit where the extension functions
- // can be applied.
- fun <T> newInstanceEuicc(clazz: Class<T>, slotId: Int, portId: Int, addArguments: Bundle.() -> Unit = {}): T where T: Fragment, T: EuiccChannelFragmentMarker {
- val instance = clazz.newInstance()
- instance.arguments = Bundle().apply {
- putInt("slotId", slotId)
- putInt("portId", portId)
- addArguments()
- }
- return instance
- }
- val <T> T.slotId: Int where T: Fragment, T: EuiccChannelFragmentMarker
- get() = requireArguments().getInt("slotId")
- val <T> T.portId: Int where T: Fragment, T: EuiccChannelFragmentMarker
- get() = requireArguments().getInt("portId")
- val <T> T.channel: EuiccChannel where T: Fragment, T: EuiccChannelFragmentMarker
- get() =
- euiccChannelManager.findEuiccChannelByPortBlocking(slotId, portId)!!
- /*
- * Begin a "tracked" operation where notifications may be generated by the eSIM
- * Automatically handle any newly generated notification during the operation
- * if the function "op" returns true.
- */
- suspend fun <T> T.beginTrackedOperation(op: suspend () -> Boolean) where T : Fragment, T : EuiccChannelFragmentMarker =
- withContext(Dispatchers.IO) {
- val latestSeq = channel.lpa.notifications.firstOrNull()?.seqNumber ?: 0
- Log.d(TAG, "Latest notification is $latestSeq before operation")
- if (op()) {
- Log.d(TAG, "Operation has requested notification handling")
- // Note that the exact instance of "channel" might have changed here if reconnected;
- // so we MUST use the automatic getter for "channel"
- channel.lpa.notifications.filter { it.seqNumber > latestSeq }.forEach {
- Log.d(TAG, "Handling notification $it")
- channel.lpa.handleNotification(it.seqNumber)
- }
- }
- Log.d(TAG, "Operation complete")
- }
- interface EuiccProfilesChangedListener {
- fun onEuiccProfilesChanged()
- }
|