Refactor automatic notification handling
Sometimes there could be more than one notification queued for each operation.
This commit is contained in:
parent
74f6313e52
commit
6784eae43b
|
@ -152,19 +152,15 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi
|
|||
}
|
||||
|
||||
private suspend fun doEnableProfile(iccid: String) =
|
||||
withContext(Dispatchers.IO) {
|
||||
channel.lpa.beginOperation {
|
||||
channel.lpa.enableProfile(iccid)
|
||||
if (preferenceRepository.notificationEnableFlow.first()) {
|
||||
channel.lpa.handleLatestNotification(LocalProfileNotification.Operation.Enable)
|
||||
}
|
||||
preferenceRepository.notificationEnableFlow.first()
|
||||
}
|
||||
|
||||
private suspend fun doDisableProfile(iccid: String) =
|
||||
withContext(Dispatchers.IO) {
|
||||
channel.lpa.beginOperation {
|
||||
channel.lpa.disableProfile(iccid)
|
||||
if (preferenceRepository.notificationDisableFlow.first()) {
|
||||
channel.lpa.handleLatestNotification(LocalProfileNotification.Operation.Disable)
|
||||
}
|
||||
preferenceRepository.notificationDisableFlow.first()
|
||||
}
|
||||
|
||||
sealed class ViewHolder(root: View) : RecyclerView.ViewHolder(root) {
|
||||
|
|
|
@ -73,10 +73,8 @@ class ProfileDeleteFragment : DialogFragment(), EuiccFragmentMarker {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun doDelete() = withContext(Dispatchers.IO) {
|
||||
private suspend fun doDelete() = channel.lpa.beginOperation {
|
||||
channel.lpa.deleteProfile(requireArguments().getString("iccid")!!)
|
||||
if (preferenceRepository.notificationDeleteFlow.first()) {
|
||||
channel.lpa.handleLatestNotification(LocalProfileNotification.Operation.Delete)
|
||||
}
|
||||
preferenceRepository.notificationDeleteFlow.first()
|
||||
}
|
||||
}
|
|
@ -184,8 +184,8 @@ class ProfileDownloadFragment : DialogFragment(), EuiccFragmentMarker, Toolbar.O
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun doDownloadProfile(server: String, code: String?, confirmationCode: String?, imei: String?) = withContext(Dispatchers.IO) {
|
||||
channel.lpa.downloadProfile(server, code, imei, confirmationCode, object : ProfileDownloadCallback {
|
||||
private suspend fun doDownloadProfile(server: String, code: String?, confirmationCode: String?, imei: String?) = channel.lpa.beginOperation {
|
||||
downloadProfile(server, code, imei, confirmationCode, object : ProfileDownloadCallback {
|
||||
override fun onStateUpdate(state: ProfileDownloadCallback.DownloadState) {
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
progress.isIndeterminate = false
|
||||
|
@ -195,8 +195,7 @@ class ProfileDownloadFragment : DialogFragment(), EuiccFragmentMarker, Toolbar.O
|
|||
})
|
||||
|
||||
// If we get here, we are successful
|
||||
if (preferenceRepository.notificationDownloadFlow.first()) {
|
||||
channel.lpa.handleLatestNotification(LocalProfileNotification.Operation.Install)
|
||||
}
|
||||
// Only send notifications if the user allowed us to
|
||||
preferenceRepository.notificationDownloadFlow.first()
|
||||
}
|
||||
}
|
|
@ -1,12 +1,22 @@
|
|||
package net.typeblog.lpac_jni
|
||||
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
interface LocalProfileAssistant {
|
||||
companion object {
|
||||
private const val TAG = "LocalProfileAssistant"
|
||||
}
|
||||
|
||||
val profiles: List<LocalProfileInfo>
|
||||
val notifications: List<LocalProfileNotification>
|
||||
val eID: String
|
||||
// Extended EuiccInfo for use with LUIs, containing information such as firmware version
|
||||
val euiccInfo2: EuiccInfo2?
|
||||
|
||||
// All blocking functions in this class assume that they are executed on non-Main threads
|
||||
// The IO context in Kotlin's coroutine library is recommended.
|
||||
fun enableProfile(iccid: String): Boolean
|
||||
fun disableProfile(iccid: String): Boolean
|
||||
fun deleteProfile(iccid: String): Boolean
|
||||
|
@ -16,9 +26,24 @@ interface LocalProfileAssistant {
|
|||
|
||||
fun deleteNotification(seqNumber: Long): Boolean
|
||||
fun handleNotification(seqNumber: Long): Boolean
|
||||
// Handle the latest entry of a particular type of notification
|
||||
// Note that this is not guaranteed to always be reliable and no feedback will be provided on errors.
|
||||
fun handleLatestNotification(operation: LocalProfileNotification.Operation)
|
||||
|
||||
// Wraps an operation on the eSIM chip (any of the other blocking functions)
|
||||
// Handles notifications automatically after the operation, unless the lambda executing
|
||||
// the operation returns false, which inhibits automatic notification processing.
|
||||
// All code executed within are also wrapped automatically in the IO context.
|
||||
suspend fun beginOperation(op: suspend LocalProfileAssistant.() -> Boolean) =
|
||||
withContext(Dispatchers.IO) {
|
||||
val latestSeq = notifications.firstOrNull()?.seqNumber ?: 0
|
||||
Log.d(TAG, "Latest notification is $latestSeq before operation")
|
||||
if (op(this@LocalProfileAssistant)) {
|
||||
Log.d(TAG, "Operation has requested notification handling")
|
||||
notifications.filter { it.seqNumber > latestSeq }.forEach {
|
||||
Log.d(TAG, "Handling notification $it")
|
||||
handleNotification(it.seqNumber)
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Operation complete")
|
||||
}
|
||||
|
||||
fun setNickname(
|
||||
iccid: String, nickname: String
|
||||
|
|
|
@ -64,13 +64,6 @@ class LocalProfileAssistantImpl(
|
|||
Log.d(TAG, "handleNotification $seqNumber = $it")
|
||||
} == 0
|
||||
|
||||
override fun handleLatestNotification(operation: LocalProfileNotification.Operation) {
|
||||
notifications.find { it.profileManagementOperation == operation }?.let {
|
||||
Log.d(TAG, "handleLatestNotification: $it")
|
||||
handleNotification(it.seqNumber)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setNickname(iccid: String, nickname: String): Boolean {
|
||||
return LpacJni.es10cSetNickname(contextHandle, iccid, nickname) == 0
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue