diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardActivity.kt index 6d810cf..66b31bc 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardActivity.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardActivity.kt @@ -2,6 +2,7 @@ package im.angry.openeuicc.ui.wizard import android.os.Bundle import android.view.View +import android.view.inputmethod.InputMethodManager import android.widget.Button import android.widget.ProgressBar import androidx.activity.OnBackPressedCallback @@ -84,6 +85,7 @@ class DownloadWizardActivity: BaseEuiccAccessActivity() { val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() + or WindowInsetsCompat.Type.ime() ) v.updatePadding(bars.left, 0, bars.right, bars.bottom) val newParams = navigation.layoutParams @@ -132,6 +134,8 @@ class DownloadWizardActivity: BaseEuiccAccessActivity() { } private fun onPrevPressed() { + hideIme() + if (currentFragment?.hasPrev == true) { val prevFrag = currentFragment?.createPrevFragment() if (prevFrag == null) { @@ -143,6 +147,8 @@ class DownloadWizardActivity: BaseEuiccAccessActivity() { } private fun onNextPressed() { + hideIme() + if (currentFragment?.hasNext == true) { currentFragment?.beforeNext() val nextFrag = currentFragment?.createNextFragment() @@ -192,6 +198,13 @@ class DownloadWizardActivity: BaseEuiccAccessActivity() { } } + private fun hideIme() { + currentFocus?.let { + val imm = getSystemService(InputMethodManager::class.java) + imm.hideSoftInputFromWindow(it.windowToken, 0) + } + } + abstract class DownloadWizardStepFragment : Fragment(), OpenEuiccContextMarker { protected val state: DownloadWizardState get() = (requireActivity() as DownloadWizardActivity).state diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt index eb36710..5fa8002 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt @@ -22,7 +22,7 @@ class DownloadWizardDetailsFragment : DownloadWizardActivity.DownloadWizardStepF private lateinit var confirmationCode: TextInputLayout private lateinit var imei: TextInputLayout - override fun beforeNext() { + private fun saveState() { state.smdp = smdp.editText!!.text.toString().trim() // Treat empty inputs as null -- this is important for the download step state.matchingId = matchingId.editText!!.text.toString().trim().ifBlank { null } @@ -30,6 +30,8 @@ class DownloadWizardDetailsFragment : DownloadWizardActivity.DownloadWizardStepF state.imei = imei.editText!!.text.toString().ifBlank { null } } + override fun beforeNext() = saveState() + override fun createNextFragment(): DownloadWizardActivity.DownloadWizardStepFragment = DownloadWizardProgressFragment() @@ -61,6 +63,11 @@ class DownloadWizardDetailsFragment : DownloadWizardActivity.DownloadWizardStepF updateInputCompleteness() } + override fun onPause() { + super.onPause() + saveState() + } + private fun updateInputCompleteness() { inputComplete = Patterns.DOMAIN_NAME.matcher(smdp.editText!!.text).matches() refreshButtons() diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardSlotSelectFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardSlotSelectFragment.kt index 3723aea..5510fb0 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardSlotSelectFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardSlotSelectFragment.kt @@ -111,7 +111,7 @@ class DownloadWizardSlotSelectFragment : DownloadWizardActivity.DownloadWizardSt } catch (e: Exception) { "" }, - channel.lpa.profiles.find { it.state == LocalProfileInfo.State.Enabled }?.displayName, + channel.lpa.profiles.enabled?.displayName, channel.intrinsicChannelName, ) } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt index 0fe44c1..9f95412 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt @@ -16,9 +16,10 @@ val LocalProfileInfo.isEnabled: Boolean get() = state == LocalProfileInfo.State.Enabled val List.operational: List - get() = filter { - it.profileClass == LocalProfileInfo.Clazz.Operational - } + get() = filter { it.profileClass == LocalProfileInfo.Clazz.Operational } + +val List.enabled: LocalProfileInfo? + get() = find { it.isEnabled } val List.hasMultipleChips: Boolean get() = distinctBy { it.slotId }.size > 1 @@ -39,7 +40,7 @@ fun LocalProfileAssistant.switchProfile( * See EuiccManager.waitForReconnect() */ fun LocalProfileAssistant.disableActiveProfile(refresh: Boolean): Boolean = - profiles.find { it.isEnabled }?.let { + profiles.enabled?.let { Log.i(TAG, "Disabling active profile ${it.iccid}") disableProfile(it.iccid, refresh) } ?: true @@ -52,7 +53,7 @@ fun LocalProfileAssistant.disableActiveProfile(refresh: Boolean): Boolean = * disable. */ fun LocalProfileAssistant.disableActiveProfileKeepIccId(refresh: Boolean): String? = - profiles.find { it.isEnabled }?.let { + profiles.enabled?.let { Log.i(TAG, "Disabling active profile ${it.iccid}") if (disableProfile(it.iccid, refresh)) { it.iccid diff --git a/app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt index c8e481c..a73d7fe 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt @@ -1,5 +1,6 @@ package im.angry.openeuicc.util +import android.content.ClipData import android.content.Context import android.content.Intent import android.content.res.Resources @@ -81,6 +82,8 @@ fun T.setupLogSaving( getLogFileName: () -> String, getLogText: () -> String ): () -> Unit { + var lastFileName = "untitled" + val launchSaveIntent = registerForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { uri -> if (uri == null) return@registerForActivityResult @@ -101,10 +104,12 @@ fun T.setupLogSaving( setMessage(R.string.logs_saved_message) setNegativeButton(R.string.no) { _, _ -> } setPositiveButton(R.string.yes) { _, _ -> - val intent = Intent().apply { - action = Intent.ACTION_SEND + val intent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" + clipData = ClipData.newUri(context.contentResolver, lastFileName, uri) + putExtra(Intent.EXTRA_TITLE, lastFileName) putExtra(Intent.EXTRA_STREAM, uri) + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } context.startActivity(Intent.createChooser(intent, null)) @@ -113,6 +118,7 @@ fun T.setupLogSaving( } return { - launchSaveIntent.launch(getLogFileName()) + lastFileName = getLogFileName() + launchSaveIntent.launch(lastFileName) } } \ No newline at end of file diff --git a/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt b/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt index 3c522c5..02b3baf 100644 --- a/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt +++ b/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt @@ -186,13 +186,10 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { ) } - try { - return@withEuiccChannelManager euiccChannelManager.withEuiccChannel( - slotId, - port - ) { channel -> + return@withEuiccChannelManager try { + euiccChannelManager.withEuiccChannel(slotId, port) { channel -> val filteredProfiles = - if (runBlocking { preferenceRepository.unfilteredProfileListFlow.first() }) + if (preferenceRepository.unfilteredProfileListFlow.first()) channel.lpa.profiles else channel.lpa.profiles.operational @@ -224,7 +221,7 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { ) } } catch (e: EuiccChannelManager.EuiccChannelNotFoundException) { - return@withEuiccChannelManager GetEuiccProfileInfoListResult( + GetEuiccProfileInfoListResult( RESULT_FIRST_USER, arrayOf(), true @@ -246,11 +243,7 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { // Check that the profile has been disabled on all slots val enabledAnywhere = ports.any { port -> euiccChannelManager.withEuiccChannel(slotId, port) { channel -> - val profile = channel.lpa.profiles.find { - it.iccid == iccid - } ?: return@withEuiccChannel false - - profile.state == LocalProfileInfo.State.Enabled + channel.lpa.profiles.enabled?.iccid == iccid } } @@ -354,8 +347,8 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { // iccid == null means disabling val foundIccid = euiccChannelManager.withEuiccChannel(foundSlotId, foundPortId) { channel -> - channel.lpa.profiles.find { it.state == LocalProfileInfo.State.Enabled } - }?.iccid ?: return@withEuiccChannelManager RESULT_FIRST_USER + channel.lpa.profiles.enabled?.iccid + } ?: return@withEuiccChannelManager RESULT_FIRST_USER Pair(foundIccid, false) } else { Pair(iccid, true)