diff --git a/.gitmodules b/.gitmodules
index 863f185..f888959 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "libs/lpac-jni/src/main/jni/lpac"]
path = libs/lpac-jni/src/main/jni/lpac
- url = https://github.com/estkme-group/lpac.git
+ url = https://github.com/estkme/lpac
diff --git a/app-common/src/main/java/im/angry/openeuicc/di/DefaultCustomizableTextProvider.kt b/app-common/src/main/java/im/angry/openeuicc/di/DefaultCustomizableTextProvider.kt
index 76227fd..b493611 100644
--- a/app-common/src/main/java/im/angry/openeuicc/di/DefaultCustomizableTextProvider.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/di/DefaultCustomizableTextProvider.kt
@@ -8,7 +8,7 @@ open class DefaultCustomizableTextProvider(private val context: Context) : Custo
get() = context.getString(R.string.no_euicc)
override val profileSwitchingTimeoutMessage: String
- get() = context.getString(R.string.profile_switch_timeout)
+ get() = context.getString(R.string.enable_disable_timeout)
override fun formatInternalChannelName(logicalSlotId: Int): String =
context.getString(R.string.channel_name_format, logicalSlotId)
diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
index 016e96f..3c94c6c 100644
--- a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
@@ -253,7 +253,7 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
if (!isUsb) {
withContext(Dispatchers.Main) {
AlertDialog.Builder(requireContext()).apply {
- setMessage(R.string.profile_switch_did_not_refresh)
+ setMessage(R.string.switch_did_not_refresh)
setPositiveButton(android.R.string.ok) { dialog, _ ->
dialog.dismiss()
requireActivity().finish()
@@ -380,9 +380,9 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
state.setText(
if (profile.isEnabled) {
- R.string.profile_state_enabled
+ R.string.enabled
} else {
- R.string.profile_state_disabled
+ R.string.disabled
}
)
provider.text = profile.providerName
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 281e625..c588254 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
@@ -65,7 +65,7 @@ class ProfileRenameFragment : BaseMaterialDialogFragment(), EuiccChannelFragment
super.onViewCreated(view, savedInstanceState)
profileRenameNewName.editText!!.setText(currentName)
toolbar.apply {
- setTitle(R.string.profile_rename)
+ setTitle(R.string.rename)
setNavigationOnClickListener {
if (!renaming) dismiss()
}
diff --git a/app-common/src/main/res/layout/euicc_profile.xml b/app-common/src/main/res/layout/euicc_profile.xml
index 021c53b..74c1d7a 100644
--- a/app-common/src/main/res/layout/euicc_profile.xml
+++ b/app-common/src/main/res/layout/euicc_profile.xml
@@ -54,7 +54,7 @@
\ No newline at end of file
diff --git a/app-common/src/main/res/menu/profile_options.xml b/app-common/src/main/res/menu/profile_options.xml
index 60722d6..6add53d 100644
--- a/app-common/src/main/res/menu/profile_options.xml
+++ b/app-common/src/main/res/menu/profile_options.xml
@@ -2,18 +2,18 @@
\ No newline at end of file
diff --git a/app-common/src/main/res/values-ja/strings.xml b/app-common/src/main/res/values-ja/strings.xml
index e631d52..d51e2c7 100644
--- a/app-common/src/main/res/values-ja/strings.xml
+++ b/app-common/src/main/res/values-ja/strings.xml
@@ -7,19 +7,19 @@
ヘルプ
スロットを再読み込み
論理スロット %d
- 有効済み
- 無効済み
- プロバイダー:
+ 有効済み
+ 無効済み
+ プロバイダー:
クラス:
テスト中
プロビジョニング
稼働中
- 有効化
- 無効化
- 削除
- 名前を変更
- eSIM チップがプロファイルの切り替えの待機中にタイムアウトしました。これはデバイスのモデムファームウェアのバグの可能性があります。機内モードに切り替えるかアプリを再起動、デバイスを再起動してください。
- 操作は成功しましたが、デバイスのモデムが更新を拒否しました。新しいプロファイルを使用するには機内モードに切り替えるか、再起動する必要があります。
+ 有効化
+ 無効化
+ 削除
+ 名前を変更
+ eSIM チップがプロファイルの切り替えの待機中にタイムアウトしました。これはデバイスのモデムファームウェアのバグの可能性があります。機内モードに切り替えるかアプリを再起動、デバイスを再起動してください。
+ 操作は成功しましたが、デバイスのモデムが更新を拒否しました。新しいプロファイルを使用するには機内モードに切り替えるか、再起動する必要があります。
新しい eSIM プロファイルに切り替えることができません。
確認文字列が一致しません
ICCID をクリップボードにコピーしました
diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml
index b0938d3..32ced90 100644
--- a/app-common/src/main/res/values-zh-rCN/strings.xml
+++ b/app-common/src/main/res/values-zh-rCN/strings.xml
@@ -6,16 +6,16 @@
帮助
重新加载卡槽
逻辑卡槽 %d
- 已启用
- 已禁用
- 提供商:
+ 已启用
+ 已禁用
+ 提供商:
类型:
- 启用
- 禁用
- 删除
- 重命名
- 等待 eSIM 芯片切换配置文件时超时。这可能是您手机基带固件中的一个错误。请尝试切换飞行模式、重新启动应用程序或重新启动手机
- 操作成功, 但是您手机的基带拒绝刷新。您可能需要切换飞行模式或重新启动,以便使用新的配置文件。
+ 启用
+ 禁用
+ 删除
+ 重命名
+ 等待 eSIM 芯片切换配置文件时超时。这可能是您手机基带固件中的一个错误。请尝试切换飞行模式、重新启动应用程序或重新启动手机
+ 操作成功, 但是您手机的基带拒绝刷新。您可能需要切换飞行模式或重新启动,以便使用新的配置文件。
无法切换到新的 eSIM 配置文件。
输入的确认文本不匹配
已复制 ICCID 到剪贴板
diff --git a/app-common/src/main/res/values-zh-rTW/strings.xml b/app-common/src/main/res/values-zh-rTW/strings.xml
index e0334c6..5136bf7 100644
--- a/app-common/src/main/res/values-zh-rTW/strings.xml
+++ b/app-common/src/main/res/values-zh-rTW/strings.xml
@@ -6,16 +6,16 @@
幫助
重新載入卡槽
虛擬卡槽 %d
- 已啟用
- 已停用
- 電信業者:
+ 已啟用
+ 已停用
+ 電信業者:
類型:
- 啟用
- 停用
- 刪除
- 重新命名
- 等待 eSIM 切換設定檔時逾時。這可能是您手機基頻處理器韌體中的一個錯誤。請嘗試切換飛航模式、重新啟動應用程式或重新啟動手機
- 操作成功, 但是您手機的基頻處理器沒有重新整理。您可能需要切換飛航模式或重新啟動,以便使用新的設定檔。
+ 啟用
+ 停用
+ 刪除
+ 重新命名
+ 等待 eSIM 切換設定檔時逾時。這可能是您手機基頻處理器韌體中的一個錯誤。請嘗試切換飛航模式、重新啟動應用程式或重新啟動手機
+ 操作成功, 但是您手機的基頻處理器沒有重新整理。您可能需要切換飛航模式或重新啟動,以便使用新的設定檔。
無法切換到新的 eSIM 設定檔。
輸入的確認文字不匹配
已複製 ICCID 到剪貼簿
diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml
index f28318f..45ec3a7 100644
--- a/app-common/src/main/res/values/strings.xml
+++ b/app-common/src/main/res/values/strings.xml
@@ -11,24 +11,23 @@
USB
OpenMobile API (OMAPI)
-
- Enabled
- Disabled
- Provider:
+ Enabled
+ Disabled
+ Provider:
Class:
Testing
Provisioning
Operational
- ICCID:
+ ICCID:
#%d
- Enable
- Disable
- Delete
- Rename
+ Enable
+ Disable
+ Delete
+ Rename
- Timed out waiting for the eSIM chip to switch profiles. This may be a bug in your phone\'s modem firmware. Try toggling airplane mode, restarting the application, or rebooting the phone.
- The operation was successful, but your phone\'s modem refused to refresh. You might need to toggle airplane mode or reboot in order to use the new profile.
+ Timed out waiting for the eSIM chip to switch profiles. This may be a bug in your phone\'s modem firmware. Try toggling airplane mode, restarting the application, or rebooting the phone.
+ The operation was successful, but your phone\'s modem refused to refresh. You might need to toggle airplane mode or reboot in order to use the new profile.
Cannot switch to new eSIM profile.
Confirmation string mismatch
diff --git a/app-unpriv/src/main/AndroidManifest.xml b/app-unpriv/src/main/AndroidManifest.xml
index 9c14163..ce985cd 100644
--- a/app-unpriv/src/main/AndroidManifest.xml
+++ b/app-unpriv/src/main/AndroidManifest.xml
@@ -24,9 +24,9 @@
+ android:label="@string/compatibility_check" />
by lazy { getCompatibilityChecks(this) }
+ private val adapter = CompatibilityChecksAdapter()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ enableEdgeToEdge()
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_compatibility_check)
+ setSupportActionBar(requireViewById(im.angry.openeuicc.common.R.id.toolbar))
+ setupToolbarInsets()
+ supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+
+ compatibilityCheckList = requireViewById(R.id.recycler_view).also {
+ it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
+ it.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
+ it.adapter = adapter
+ }
+
+ setupRootViewInsets(compatibilityCheckList)
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ override fun onStart() {
+ super.onStart()
+ lifecycleScope.launch {
+ compatibilityChecks.executeAll { adapter.notifyDataSetChanged() }
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean =
+ when (item.itemId) {
+ android.R.id.home -> {
+ finish()
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+
+ inner class ViewHolder(private val root: View): RecyclerView.ViewHolder(root) {
+ private val titleView: TextView = root.requireViewById(R.id.compatibility_check_title)
+ private val descView: TextView = root.requireViewById(R.id.compatibility_check_desc)
+ private val statusContainer: ViewGroup = root.requireViewById(R.id.compatibility_check_status_container)
+
+ fun bindItem(item: CompatibilityCheck) {
+ titleView.text = item.title
+ descView.text = Html.fromHtml(item.description, Html.FROM_HTML_MODE_COMPACT)
+
+ statusContainer.children.forEach {
+ it.isVisible = false
+ }
+
+ val viewId = when (item.state) {
+ CompatibilityCheck.State.SUCCESS -> R.id.compatibility_check_checkmark
+ CompatibilityCheck.State.FAILURE -> R.id.compatibility_check_error
+ CompatibilityCheck.State.FAILURE_UNKNOWN -> R.id.compatibility_check_unknown
+ else -> R.id.compatibility_check_progress_bar
+ }
+ root.requireViewById(viewId).isVisible = true
+ }
+ }
+
+ inner class CompatibilityChecksAdapter: RecyclerView.Adapter() {
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
+ ViewHolder(layoutInflater.inflate(R.layout.compatibility_check_item, parent, false))
+
+ override fun getItemCount(): Int =
+ compatibilityChecks.indexOfLast { it.state != CompatibilityCheck.State.NOT_STARTED } + 1
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindItem(compatibilityChecks[position])
+ }
+ }
+}
\ No newline at end of file
diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityActivity.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityActivity.kt
deleted file mode 100644
index d5e599f..0000000
--- a/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityActivity.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package im.angry.openeuicc.ui
-
-import android.os.Bundle
-import androidx.activity.enableEdgeToEdge
-import androidx.appcompat.app.AppCompatActivity
-import im.angry.easyeuicc.R
-import im.angry.openeuicc.di.UnprivilegedUiComponentFactory
-import im.angry.openeuicc.util.OpenEuiccContextMarker
-
-class QuickCompatibilityActivity : AppCompatActivity(), OpenEuiccContextMarker {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContentView(R.layout.activity_quick_compatibility)
-
- val quickCompatibilityFragment =
- (appContainer.uiComponentFactory as UnprivilegedUiComponentFactory)
- .createQuickCompatibilityFragment()
-
- supportFragmentManager.beginTransaction()
- .replace(R.id.quick_compatibility_container, quickCompatibilityFragment)
- .commit()
- }
-}
diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityFragment.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityFragment.kt
deleted file mode 100644
index 9b41730..0000000
--- a/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityFragment.kt
+++ /dev/null
@@ -1,186 +0,0 @@
-package im.angry.openeuicc.ui
-
-import android.content.pm.PackageManager
-import android.icu.text.ListFormatter
-import android.os.Build
-import android.os.Bundle
-import android.se.omapi.Reader
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.CheckBox
-import android.widget.TextView
-import androidx.core.view.isVisible
-import androidx.fragment.app.Fragment
-import androidx.lifecycle.lifecycleScope
-import im.angry.easyeuicc.R
-import im.angry.openeuicc.util.EUICC_DEFAULT_ISDR_AID
-import im.angry.openeuicc.util.UnprivilegedEuiccContextMarker
-import im.angry.openeuicc.util.connectSEService
-import im.angry.openeuicc.util.decodeHex
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withContext
-
-open class QuickCompatibilityFragment : Fragment(), UnprivilegedEuiccContextMarker {
- companion object {
- enum class Compatibility {
- COMPATIBLE,
- NOT_COMPATIBLE,
- }
-
- data class CompatibilityResult(
- val compatibility: Compatibility,
- val slotsOmapi: List = emptyList(),
- val slotsIsdr: List = emptyList()
- )
- }
-
- private val conclusion: TextView by lazy {
- requireView().requireViewById(R.id.quick_compatibility_conclusion)
- }
-
- private val resultSlots: TextView by lazy {
- requireView().requireViewById(R.id.quick_compatibility_result_slots)
- }
-
- private val resultSlotsIsdr: TextView by lazy {
- requireView().requireViewById(R.id.quick_compatibility_result_slots_isdr)
- }
-
- private val resultNotes: TextView by lazy {
- requireView().requireViewById(R.id.quick_compatibility_result_notes)
- }
-
- private val skipCheckBox: CheckBox by lazy {
- requireView().requireViewById(R.id.quick_compatibility_skip)
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View = inflater.inflate(R.layout.fragment_quick_compatibility, container, false).apply {
- requireViewById(R.id.quick_compatibility_device_information)
- .text = formatDeviceInformation()
- requireViewById