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 b7462e2..6ab6935 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 @@ -65,8 +65,6 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener, // This gives us access to the "latest" state without having to launch coroutines private lateinit var disableSafeguardFlow: StateFlow - private lateinit var unfilteredProfileListFlow: StateFlow - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -187,22 +185,15 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener, ensureEuiccChannelManager() euiccChannelManagerService.waitForForegroundTask() - if (!::disableSafeguardFlow.isInitialized) { + if (!this@EuiccManagementFragment::disableSafeguardFlow.isInitialized) { disableSafeguardFlow = preferenceRepository.disableSafeguardFlow.stateIn(lifecycleScope) } - if (!::unfilteredProfileListFlow.isInitialized) { - unfilteredProfileListFlow = - preferenceRepository.unfilteredProfileListFlow.stateIn(lifecycleScope) - } val profiles = withEuiccChannel { channel -> logicalSlotId = channel.logicalSlotId euiccChannelManager.notifyEuiccProfilesChanged(channel.logicalSlotId) - if (unfilteredProfileListFlow.value) - channel.lpa.profiles - else - channel.lpa.profiles.operational + channel.lpa.profiles.operational } withContext(Dispatchers.Main) { @@ -311,7 +302,7 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener, companion object { fun fromInt(value: Int) = - entries.first { it.value == value } + Type.values().first { it.value == value } } } } diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt index 9c071bd..89963cb 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt @@ -76,16 +76,13 @@ class SettingsFragment: PreferenceFragmentCompat() { findPreference("pref_developer_experimental_download_wizard") ?.bindBooleanFlow(preferenceRepository.experimentalDownloadWizardFlow, PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD) - findPreference("pref_developer_unfiltered_profile_list") - ?.bindBooleanFlow(preferenceRepository.unfilteredProfileListFlow, PreferenceKeys.UNFILTERED_PROFILE_LIST) - findPreference("pref_ignore_tls_certificate") ?.bindBooleanFlow(preferenceRepository.ignoreTLSCertificateFlow, PreferenceKeys.IGNORE_TLS_CERTIFICATE) } override fun onStart() { super.onStart() - setupRootViewInsets(requireView().requireViewById(R.id.recycler_view)) + setupRootViewInsets(requireView().requireViewById(androidx.preference.R.id.recycler_view)) } @Suppress("UNUSED_PARAMETER") diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index 807706e..505630e 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -32,30 +32,43 @@ object PreferenceKeys { // ---- Developer Options ---- val DEVELOPER_OPTIONS_ENABLED = booleanPreferencesKey("developer_options_enabled") val EXPERIMENTAL_DOWNLOAD_WIZARD = booleanPreferencesKey("experimental_download_wizard") - val UNFILTERED_PROFILE_LIST = booleanPreferencesKey("unfiltered_profile_list") val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate") } -class PreferenceRepository(private val context: Context) { +class PreferenceRepository(context: Context) { + private val dataStore = context.dataStore + // Expose flows so that we can also handle default values // ---- Profile Notifications ---- - val notificationDownloadFlow = bindFlow(PreferenceKeys.NOTIFICATION_DOWNLOAD, true) - val notificationDeleteFlow = bindFlow(PreferenceKeys.NOTIFICATION_DELETE, true) - val notificationSwitchFlow = bindFlow(PreferenceKeys.NOTIFICATION_SWITCH, false) + val notificationDownloadFlow: Flow = + dataStore.data.map { it[PreferenceKeys.NOTIFICATION_DOWNLOAD] ?: true } + + val notificationDeleteFlow: Flow = + dataStore.data.map { it[PreferenceKeys.NOTIFICATION_DELETE] ?: true } + + val notificationSwitchFlow: Flow = + dataStore.data.map { it[PreferenceKeys.NOTIFICATION_SWITCH] ?: false } // ---- Advanced ---- - val disableSafeguardFlow = bindFlow(PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM, false) - val verboseLoggingFlow = bindFlow(PreferenceKeys.VERBOSE_LOGGING, false) + val disableSafeguardFlow: Flow = + dataStore.data.map { it[PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM] ?: false } + + val verboseLoggingFlow: Flow = + dataStore.data.map { it[PreferenceKeys.VERBOSE_LOGGING] ?: false } // ---- Developer Options ---- - val developerOptionsEnabledFlow = bindFlow(PreferenceKeys.DEVELOPER_OPTIONS_ENABLED, false) - val experimentalDownloadWizardFlow = bindFlow(PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD, false) - val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false) - val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false) + val developerOptionsEnabledFlow: Flow = + dataStore.data.map { it[PreferenceKeys.DEVELOPER_OPTIONS_ENABLED] ?: false } - private fun bindFlow(key: Preferences.Key, defaultValue: T): Flow = - context.dataStore.data.map { it[key] ?: defaultValue } + val experimentalDownloadWizardFlow: Flow = + dataStore.data.map { it[PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD] ?: false } - suspend fun updatePreference(key: Preferences.Key, value: T) = - context.dataStore.edit { it[key] = value } + val ignoreTLSCertificateFlow: Flow = + dataStore.data.map { it[PreferenceKeys.IGNORE_TLS_CERTIFICATE] ?: false } + + suspend fun updatePreference(key: Preferences.Key, value: T) { + dataStore.edit { + it[key] = value + } + } } \ 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 deleted file mode 100644 index 72b88a8..0000000 --- a/app-common/src/main/res/values-ja/strings.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - このアプリでアクセスできるリムーバブル eUICC カードがデバイス上で検出されていません。互換性のあるカード挿入または USB リーダーを接続してください。 - この eSIM にはプロファイルがありません。 - 不明 - ヘルプ - スロットを再読み込み - 論理スロット %d - USB - OpenMobile API (OMAPI) - 有効済み - 無効済み - プロバイダー: - ICCID: - 有効化 - 無効化 - 削除 - 名前を変更 - eSIM チップがプロファイルの切り替えの待機中にタイムアウトしました。これはデバイスのモデムファームウェアのバグの可能性があります。機内モードに切り替えるかアプリを再起動、デバイスを再起動してください。 - 操作は成功しましたが、デバイスのモデムが更新を拒否しました。新しいプロファイルを使用するには機内モードに切り替えるか、再起動する必要があります。 - 新しい eSIM プロファイルに切り替えることができません。 - ニックネームは 64 文字以内にしてください - ICCID をクリップボードにコピーしました - スロットを選択 - 選択 - USB の権限を許可 - USB スマートカードリーダーにアクセスするには許可が必要です。 - USB スマートカードリーダー経由で eSIM に接続できません。 - 長時間実行されるタスク - eSIM プロファイルをダウンロード中です - eSIM プロファイルのダウンロードに失敗しました - eSIM プロファイルの名前を変更中です - eSIM プロファイルの名前の変更に失敗しました - eSIM プロファイルを削除中です - eSIM プロファイルの削除に失敗しました - eSIM プロファイルを切り替え中 - eSIM プロファイルの切り替えに失敗しました - 新しい eSIM - サーバー (RSP / SM-DP+) - アクティベーションコード - 確認コード (オプション) - IMEI (オプション) - 残りの容量: %s - QR コードをスキャン - ギャラリーから QR コードをスキャン - ダウンロード - eSIM のダウンロードに失敗しました。アクティベーションまたは QR コードを確認してください。 - ダウンロードに失敗する可能性があります - 残り容量が少ないため、ダウンロードに失敗する可能性があります。 - ダウンロードウィザード - 戻る - 次へ - ダウンロードする eSIM を選択または確認: - 論理スロット %d - タイプ: - リムーバブル - 内部 - 内部 - ポート: %d - eID: - 有効なプロファイル: - 空き容量: - eSIM プロファイルをどの方法でダウンロードしますか? - カメラで QR コードをスキャン - ギャラリーから QR コードをスキャン - 手動で入力 - eSIM をダウンロードするための詳細情報を入力または確認: - eSIM をダウンロード中です… - 準備中 - サーバーへの接続を確立しています - サーバーでデバイスを認証中です - eSIM プロファイルをダウンロード中です - eSIM プロファイルをストレージに読み込み中です - エラー診断 - 最終の HTTP ステータス (サーバー): %d - 最終の HTTP レスポンス (サーバー): - 最終の HTTP 例外: - 最終の APDU レスポンス (SIM): %s - 最終の APDU レスポンス (SIM) は成功しました - 最終の APDU レスポンス (SIM) は失敗しました - 最終の APDU 例外: - 新しいニックネーム - %s のプロファイルを削除してもよろしいですか?この操作は元に戻せません。 - 削除を確認するには「%s」を入力してください - 通知 - 通知 (%s) - 通知の管理 - eSIM プロファイルはダウンロードや削除、有効化や無効化されたときに通信事業者に通知を送信できます。送信されるこれらの通知のキューはここにリストされます。\n\n設定では、各タイプの通知を自動的に送信するかどうかを指定できます。通知が送信された場合でもキューのスペースが不足していない限り、記録から自動的に削除されることはありません。\n\nここでは保留中の各通知を手動で送信または削除できます。 - ダウンロードしました - 削除しました - 有効化しました - 無効化しました - <b>%1$s</b> %2$s (%3$s) - 処理 - 削除 - eUICC 情報 - eUICC 情報 (%s) - アクセスモード - リムーバブル - EID - eUICC OS のバージョン - グローバルプラットフォームのバージョン - SAS 認定番号 - 保護されたプロファイルのバージョン - NVRAM の空き容量 (eSIM プロファイルストレージ) - GSMA プロダクション証明書 - GSMA テスト証明書 - 対応 - 非対応 - はい - いいえ - 保存 - %s のログ - 開発者になるまであと %d ステップです。 - あなたは開発者になりました! - 設定 - 通知 - eSIM のプロファイル操作により、通信事業者に通知が送信されます。必要に応じてこの動作を微調整できます。 - ダウンロード - プロファイルをダウンロード中の通知を送信します - 削除 - プロファイルを削除中の通知を送信します - 切り替え中 - プロファイルを切り替え中の通知を送信します\nこのタイプの通知は信頼できないことに注意してください。 - 高度な設定 - 有効なプロファイルの無効化と削除を許可する - デフォルトでは、このアプリでデバイスに挿入された取り外し可能な eSIM の有効なプロファイルを無効化することを防いでいます。なぜなのかというと時々アクセスができなくなるからです。\nこのチェックボックスを ON にすることで、この保護機能を解除します。 - 詳細ログ - 詳細ログを有効化します。これには個人的な情報が含まれている可能性があります。この機能を ON にした後は、信頼できるユーザーとのみログを共有してください。 - ログ - アプリの最新デバッグログを表示します - 開発者オプション - 実験的なダウンロードウィザード - 実験的な新しいダウンロードウィザードを有効化します。まだ完全に機能していないことにご注意ください。 - SM-DP+ TLS 証明書を無視する - SM-DP+ TLS 証明書を無視して任意の RSP を許可します - 情報 - アプリバージョン - ソースコード - diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 73b1938..a3067dd 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -151,8 +151,6 @@ Developer Options Experimental Download Wizard Enable the experimental new download wizard. Note that it is not fully working yet. - Show unfiltered profile list - Display any profile class in the list Ignore SM-DP+ TLS certificate Ignore SM-DP+ TLS certificate, allow any RSP Info diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index 60646bc..d43c84b 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -55,12 +55,6 @@ app:title="@string/pref_developer_experimental_download_wizard" app:summary="@string/pref_developer_experimental_download_wizard_desc" /> - - - - SIM %d - 互換性のチェック - SIM ツールキットを開く - - システムの機能 - デバイスにリムーバブル eUICC カードの管理に必要なすべての機能が備わっているかどうか。例えば基本的な電話機能や OMAPI のサポートなど。 - 使用しているデバイスには電話機能がありません。 - 使用しているデバイスまたはシステムには OMAPI のサポートを宣言していません。これは、ハードウェアからのサポートが不足していることが原因の可能性があります。または、フラグが不足していることが原因の可能性もあります。OMAPI が実際にサポートされているかどうかを判断するには次の 2 つのチェック項目を参照してください。 - OMAPI の接続 - 使用しているデバイスは、OMAPI 経由で SIM カード上のセキュアエレメントへのアクセスを許可していますか? - OMAPI 経由で SIM カードのセキュアエレメントリーダーを検出できません。このデバイスに SIM を挿入していない場合は、SIM を挿入後にこのチェックを再試行してください。 - セキュアエレメントアクセスが正常に検出されましたが、次の SIM スロットでのみ有効です: SIM%s. - ISD-R チャネルアクセス - 使用しているデバイスは、OMAPI 経由で eSIM への ISD-R (管理) チャネルを開くことをサポートしていますか? - OMAPI 経由での ISD-R アクセスがサポートされているかどうかを確認できません。まだ SIM カードが挿入されていない場合は、挿入した状態で再試行してください (どの SIM カードでも構いません)。 - ISD-R への OMAPI アクセスは、次のスロットでのみ可能です: SIM%s. - 既知の破損リストに掲載されていない - 取り外し可能な eSIM に関連するバグがデバイスに存在しないかを確認します。 - おっと...使用しているデバイスには、取り外し可能な eSIM へのアクセス時にバグが存在します。これは必ずしも全く機能しないことを意味するわけではありませんが、注意して進める必要があります。 - USB カードリーダーのサポート - 使用しているデバイスは、USB カードリーダー経由の eSIM の管理をサポートしていますか? - このデバイスの標準 USB CCID リーダーを介して eSIM を管理できます (ここで他のチェック項目に失敗した場合でも)。カードリーダーを挿入し、このアプリを開いてこの方法で eSIM を管理できます。 - 使用しているデバイスは USB ホストとしての機能をサポートしていません。 - 判定 (USB 以外) - これまでのすべてのチェック項目に基づいて、デバイスに挿入された取り外し可能な eSIM の管理と互換性がある可能性はどのくらいありますか? - このデバイスに挿入された取り外し可能な eSIM の使用および管理が使用できる可能性があります。 - 挿入された取り外し可能な eSIM にアクセスするとデバイスにバグが発生することが知られています。\n%s - 挿入された取り外し可能な eSIM が使用しているデバイスで管理できるかはわかりません。ただし、このデバイスは OMAPI のサポートを宣言しているため、動作する可能性はわずかに高くなります。\n%s - 挿入された取り外し可能な eSIM がデバイス上で管理できるかどうかは判断できません。デバイスが OMAPI のサポートを宣言していないため、このデバイス上で取り外し可能な eSIM を管理することはサポートされていない可能性があります。\n%s - 挿入された取り外し可能な eSIM がデバイス上で管理できるかどうかを確認できません。\n%s - ただし、eSIM プロファイルがすでに読み込まれている場合、有効化されたプロファイル自体は引き続き機能します。また、プロファイルが管理できない場合は、このデバイスで USB カードリーダーを介してプロファイルを管理できる可能性があります。 - 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 d626333..aeda3e4 100644 --- a/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt +++ b/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt @@ -13,7 +13,6 @@ import im.angry.openeuicc.core.EuiccChannelManager import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone import im.angry.openeuicc.util.* import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import kotlin.IllegalStateException @@ -191,12 +190,7 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { slotId, port ) { channel -> - val filteredProfiles = - if (runBlocking { preferenceRepository.unfilteredProfileListFlow.first() }) - channel.lpa.profiles - else - channel.lpa.profiles.operational - val profiles = filteredProfiles.map { + val profiles = channel.lpa.profiles.operational.map { EuiccProfileInfo.Builder(it.iccid).apply { setProfileName(it.name) setNickname(it.displayName) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml deleted file mode 100644 index add6e93..0000000 --- a/app/src/main/res/values-ja/strings.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - OpenEUICC - このデバイスで eUICC が見つかりません。\nデバイスによってはアプリのメニューからデュアル SIM を有効化する必要があります。 - TelephonyManager (特権) - デュアル SIM - DSDS の状態が切り替わりました。モデムが再起動するまでお待ちください。 - このスロットは MEP (Multiple Enabled Profiles) をサポートしています。この機能を有効化または無効化するには「スロットマッピングツール」を使用してください。 - スロットマッピング - 論理スロット %d: - スロット %1$d ポート %2$d - 使用しているデバイスは、%1$d 個の論理 SIM スロットと %2$d 個の物理 SIM スロットがあります。%3$s\n\n各論理スロットに対応する物理スロットまたはポートを選択してください。すべてのマッピングモードがハードウェアでサポートされているわけではないことにご注意ください。 - \n\n物理スロット %1$d は、複数の有効なプロファイル (MEP) をサポートしています。この機能を使用するには、%2$d の仮想ポートを上記の異なる論理スロットに割り当てます。\n\nMEP を有効化すると、ポートは共有プロファイルの一覧を除いて OpenEUICC の個別の eSIM スロットのように動作します。 - \nデュアル SIM モードはサポートされていますが、無効化されています。デバイスに内部 eSIM チップが搭載されている場合は、デフォルトで有効化されていない可能性があります。上記のマッピングを変更するか、デュアル SIM を有効化して eSIM にアクセスしてください。 - 新しいスロットマッピングが設定されました。モデムがスロットを更新するまでお待ちください。 - 指定されたマッピングが無効化されているか、ハードウェアがサポートをしていない可能性があります。 - eSIM をダウンロードしてモバイルネットワークに接続 - 使用しているデバイスは eSIM をサポートしています。モバイルネットワークに接続するには通信事業者が発行した eSIM をダウンロードするか、物理 SIM を挿入してください。 - スキップ - eSIM をダウンロード -