diff --git a/app-common/src/main/java/im/angry/openeuicc/core/LocalProfileAssistantWrapper.kt b/app-common/src/main/java/im/angry/openeuicc/core/LocalProfileAssistantWrapper.kt
index aab9e63..b715ca0 100644
--- a/app-common/src/main/java/im/angry/openeuicc/core/LocalProfileAssistantWrapper.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/core/LocalProfileAssistantWrapper.kt
@@ -54,8 +54,9 @@ class LocalProfileAssistantWrapper(orig: LocalProfileAssistant) :
override fun euiccMemoryReset() = lpa.euiccMemoryReset()
- override fun setNickname(iccid: String, nickname: String): Boolean =
+ override fun setNickname(iccid: String, nickname: String) {
lpa.setNickname(iccid, nickname)
+ }
override fun close() = lpa.close()
diff --git a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt
index c4d16df..a20c8db 100644
--- a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt
@@ -414,16 +414,12 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
getString(R.string.task_profile_rename_failure),
R.drawable.ic_task_rename
) {
- val res = euiccChannelManager.withEuiccChannel(slotId, portId) { channel ->
+ euiccChannelManager.withEuiccChannel(slotId, portId) { channel ->
channel.lpa.setNickname(
iccid,
name
)
}
-
- if (!res) {
- throw RuntimeException("Profile not renamed")
- }
}
fun launchProfileDeleteTask(
diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
index 8582278..a3e4571 100644
--- a/app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
@@ -14,6 +14,7 @@ import im.angry.openeuicc.common.R
import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone
import im.angry.openeuicc.util.*
import kotlinx.coroutines.launch
+import net.typeblog.lpac_jni.LocalProfileAssistant
class ProfileRenameFragment : BaseMaterialDialogFragment(), EuiccChannelFragmentMarker {
companion object {
@@ -95,21 +96,49 @@ class ProfileRenameFragment : BaseMaterialDialogFragment(), EuiccChannelFragment
lifecycleScope.launch {
ensureEuiccChannelManager()
euiccChannelManagerService.waitForForegroundTask()
- euiccChannelManagerService.launchProfileRenameTask(
+ val res = euiccChannelManagerService.launchProfileRenameTask(
slotId,
portId,
requireArguments().getString("iccid")!!,
name
).waitDone()
- if (parentFragment is EuiccProfilesChangedListener) {
- (parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
- }
+ when (res) {
+ is LocalProfileAssistant.ProfileNameTooLongException -> {
+ Toast.makeText(
+ requireContext(),
+ R.string.profile_rename_too_long,
+ Toast.LENGTH_LONG
+ ).show()
+ }
- try {
- dismiss()
- } catch (e: IllegalStateException) {
- // Ignored
+ is LocalProfileAssistant.ProfileNameIsInvalidUTF8Exception -> {
+ Toast.makeText(
+ requireContext(),
+ R.string.profile_rename_encoding_error,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+
+ is Throwable -> {
+ Toast.makeText(
+ requireContext(),
+ R.string.profile_rename_failure,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+
+ else -> {
+ if (parentFragment is EuiccProfilesChangedListener) {
+ (parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
+ }
+
+ try {
+ dismiss()
+ } catch (e: IllegalStateException) {
+ // Ignored
+ }
+ }
}
}
}
diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsActivity.kt
index bb299a3..9898558 100644
--- a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsActivity.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsActivity.kt
@@ -8,10 +8,7 @@ import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
-class SettingsActivity: AppCompatActivity() {
- private val appContainer
- get() = (application as OpenEuiccApplication).appContainer
-
+class SettingsActivity: AppCompatActivity(), EuiccChannelFragmentMarker {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardMethodSelectFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardMethodSelectFragment.kt
index d329048..6203364 100644
--- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardMethodSelectFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardMethodSelectFragment.kt
@@ -1,6 +1,7 @@
package im.angry.openeuicc.ui.wizard
import android.app.AlertDialog
+import android.content.ClipboardManager
import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.LayoutInflater
@@ -8,6 +9,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
+import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
@@ -68,6 +70,9 @@ class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizard
DownloadMethod(R.drawable.ic_gallery_black, R.string.download_wizard_method_gallery) {
gallerySelectorLauncher.launch("image/*")
},
+ DownloadMethod(R.drawable.ic_paste_go, R.string.download_wizard_method_clipboard) {
+ handleLoadFromClipboard()
+ },
DownloadMethod(R.drawable.ic_edit, R.string.download_wizard_method_manual) {
gotoNextFragment(DownloadWizardDetailsFragment())
}
@@ -103,6 +108,22 @@ class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizard
return view
}
+ private fun handleLoadFromClipboard() {
+ val clipboard = requireContext().getSystemService(ClipboardManager::class.java)
+ val text = clipboard.primaryClip?.getItemAt(0)?.text
+
+ if (text == null) {
+ Toast.makeText(
+ requireContext(),
+ R.string.profile_download_no_lpa_string,
+ Toast.LENGTH_SHORT
+ ).show()
+ return
+ }
+
+ processLpaString(text.toString())
+ }
+
private fun processLpaString(s: String) {
val components = s.split("$")
if (components.size < 3 || components[0] != "LPA:1") {
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 f16a086..3723aea 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
@@ -57,13 +57,15 @@ class DownloadWizardSlotSelectFragment : DownloadWizardActivity.DownloadWizardSt
super.beforeNext()
if (adapter.selected.freeSpace < LOW_NVRAM_THRESHOLD) {
+ val activity = requireActivity()
+
AlertDialog.Builder(requireContext()).apply {
setTitle(R.string.profile_download_low_nvram_title)
setMessage(R.string.profile_download_low_nvram_message)
setCancelable(true)
setPositiveButton(android.R.string.ok, null)
setNegativeButton(android.R.string.cancel) { _, _ ->
- requireActivity().finish()
+ activity.finish()
}
show()
}
diff --git a/app-common/src/main/res/drawable/ic_paste_go.xml b/app-common/src/main/res/drawable/ic_paste_go.xml
new file mode 100644
index 0000000..7536fff
--- /dev/null
+++ b/app-common/src/main/res/drawable/ic_paste_go.xml
@@ -0,0 +1,7 @@
+