Compare commits

...

4 commits

Author SHA1 Message Date
43f247a71b fix: share file name display (#122)
Co-authored-by: Peter Cai <peter@typeblog.net>
Reviewed-on: PeterCxy/OpenEUICC#122
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
2024-12-19 00:19:34 +01:00
960f8855ad refactor: simplify profile operation (#129)
Co-authored-by: Peter Cai <peter@typeblog.net>
Reviewed-on: PeterCxy/OpenEUICC#129
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
2024-12-19 00:18:59 +01:00
de3ae19a10 ui: wizard: Resize activity root view with IME
...and hide the IME whenever we switch between the fragments.
2024-12-18 18:16:33 -05:00
75d3894462 ui: wizard: Save input state on pause
Fixes #131 and supersedes #132.
2024-12-18 18:02:24 -05:00
6 changed files with 44 additions and 24 deletions

View file

@ -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

View file

@ -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()

View file

@ -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,
)
}

View file

@ -16,9 +16,10 @@ val LocalProfileInfo.isEnabled: Boolean
get() = state == LocalProfileInfo.State.Enabled
val List<LocalProfileInfo>.operational: List<LocalProfileInfo>
get() = filter {
it.profileClass == LocalProfileInfo.Clazz.Operational
}
get() = filter { it.profileClass == LocalProfileInfo.Clazz.Operational }
val List<LocalProfileInfo>.enabled: LocalProfileInfo?
get() = find { it.isEnabled }
val List<EuiccChannel>.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

View file

@ -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 : ActivityResultCaller> 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 : ActivityResultCaller> 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 : ActivityResultCaller> T.setupLogSaving(
}
return {
launchSaveIntent.launch(getLogFileName())
lastFileName = getLogFileName()
launchSaveIntent.launch(lastFileName)
}
}

View file

@ -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)