diff --git a/app-common/src/main/AndroidManifest.xml b/app-common/src/main/AndroidManifest.xml index b0324dc..464ae0f 100644 --- a/app-common/src/main/AndroidManifest.xml +++ b/app-common/src/main/AndroidManifest.xml @@ -28,10 +28,6 @@ android:name="im.angry.openeuicc.ui.LogsActivity" android:label="@string/pref_advanced_logs" /> - - get() = (0.. EuiccChannel?): EuiccChannel? { - val isdrAidList = - parseIsdrAidList(appContainer.preferenceRepository.isdrAidListFlow.first()) - - return isdrAidList.firstNotNullOfOrNull { - Log.i(TAG, "Opening channel, trying ISDR AID ${it.encodeHex()}") - - openFn(it)?.let { channel -> - if (channel.valid) { - channel - } else { - channel.close() - null - } - } - } - } - private suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? { lock.withLock { if (port.card.physicalSlotIndex == EuiccChannelManager.USB_CHANNEL_ID) { @@ -95,10 +76,9 @@ open class DefaultEuiccChannelManager( return null } - val channel = - tryOpenChannelFirstValidAid { euiccChannelFactory.tryOpenEuiccChannel(port, it) } + val channel = euiccChannelFactory.tryOpenEuiccChannel(port) ?: return null - if (channel != null) { + if (channel.valid) { channelCache.add(channel) return channel } else { @@ -106,6 +86,7 @@ open class DefaultEuiccChannelManager( TAG, "Was able to open channel for logical slot ${port.logicalSlotIndex}, but the channel is invalid (cannot get eID or profiles without errors). This slot might be broken, aborting." ) + channel.close() return null } } @@ -231,10 +212,7 @@ open class DefaultEuiccChannelManager( check(channel.valid) { "Invalid channel" } break } catch (e: Exception) { - Log.d( - TAG, - "Slot $physicalSlotId port $portId reconnect failure, retrying in 1000 ms" - ) + Log.d(TAG, "Slot $physicalSlotId port $portId reconnect failure, retrying in 1000 ms") } delay(1000) } @@ -271,18 +249,9 @@ open class DefaultEuiccChannelManager( // If we don't have permission, tell UI code that we found a candidate device, but we // need permission to be able to do anything with it if (!usbManager.hasPermission(device)) return@withContext Pair(device, false) - Log.i( - TAG, - "Found CCID interface on ${device.deviceId}:${device.vendorId}, and has permission; trying to open channel" - ) + Log.i(TAG, "Found CCID interface on ${device.deviceId}:${device.vendorId}, and has permission; trying to open channel") try { - val channel = tryOpenChannelFirstValidAid { - euiccChannelFactory.tryOpenUsbEuiccChannel( - device, - iface, - it - ) - } + val channel = euiccChannelFactory.tryOpenUsbEuiccChannel(device, iface) if (channel != null && channel.lpa.valid) { usbChannel = channel return@withContext Pair(device, true) @@ -291,10 +260,7 @@ open class DefaultEuiccChannelManager( // Ignored -- skip forward e.printStackTrace() } - Log.i( - TAG, - "No valid eUICC channel found on USB device ${device.deviceId}:${device.vendorId}" - ) + Log.i(TAG, "No valid eUICC channel found on USB device ${device.deviceId}:${device.vendorId}") } return@withContext Pair(null, false) } diff --git a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelFactory.kt b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelFactory.kt index 87f5885..fb5d95d 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelFactory.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelFactory.kt @@ -7,13 +7,9 @@ import im.angry.openeuicc.util.* // This class is here instead of inside DI because it contains a bit more logic than just // "dumb" dependency injection. interface EuiccChannelFactory { - suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat, isdrAid: ByteArray): EuiccChannel? + suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? - fun tryOpenUsbEuiccChannel( - usbDevice: UsbDevice, - usbInterface: UsbInterface, - isdrAid: ByteArray - ): EuiccChannel? + fun tryOpenUsbEuiccChannel(usbDevice: UsbDevice, usbInterface: UsbInterface): EuiccChannel? /** * Release all resources used by this EuiccChannelFactory diff --git a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelImpl.kt b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelImpl.kt index ed8797a..a56b1cc 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelImpl.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelImpl.kt @@ -13,17 +13,21 @@ class EuiccChannelImpl( override val port: UiccPortInfoCompat, override val intrinsicChannelName: String?, override val apduInterface: ApduInterface, - isdrAid: ByteArray, verboseLoggingFlow: Flow, ignoreTLSCertificateFlow: Flow ) : EuiccChannel { + companion object { + // TODO: This needs to go somewhere else. + val ISDR_AID = "A0000005591010FFFFFFFF8900000100".decodeHex() + } + override val slotId = port.card.physicalSlotIndex override val logicalSlotId = port.logicalSlotIndex override val portId = port.portIndex override val lpa: LocalProfileAssistant = LocalProfileAssistantImpl( - isdrAid, + ISDR_AID, apduInterface, HttpInterfaceImpl(verboseLoggingFlow, ignoreTLSCertificateFlow) ) diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/IsdrAidListActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/IsdrAidListActivity.kt deleted file mode 100644 index 6553421..0000000 --- a/app-common/src/main/java/im/angry/openeuicc/ui/IsdrAidListActivity.kt +++ /dev/null @@ -1,67 +0,0 @@ -package im.angry.openeuicc.ui - -import android.os.Bundle -import android.text.Editable -import android.view.Menu -import android.view.MenuItem -import android.widget.EditText -import android.widget.Toast -import androidx.activity.enableEdgeToEdge -import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.lifecycleScope -import im.angry.openeuicc.common.R -import im.angry.openeuicc.util.preferenceRepository -import im.angry.openeuicc.util.setupToolbarInsets -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch - -class IsdrAidListActivity : AppCompatActivity() { - private lateinit var isdrAidListEditor: EditText - - override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_isdr_aid_list) - setSupportActionBar(requireViewById(R.id.toolbar)) - setupToolbarInsets() - supportActionBar!!.setDisplayHomeAsUpEnabled(true) - - isdrAidListEditor = requireViewById(R.id.isdr_aid_list_editor) - - lifecycleScope.launch { - preferenceRepository.isdrAidListFlow.onEach { - isdrAidListEditor.text = Editable.Factory.getInstance().newEditable(it) - }.collect() - } - } - - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.activity_isdr_aid_list, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean = - when (item.itemId) { - R.id.save -> { - lifecycleScope.launch { - preferenceRepository.isdrAidListFlow.updatePreference(isdrAidListEditor.text.toString()) - Toast.makeText( - this@IsdrAidListActivity, - R.string.isdr_aid_list_saved, - Toast.LENGTH_SHORT - ).show() - } - true - } - - R.id.reset -> { - lifecycleScope.launch { - preferenceRepository.isdrAidListFlow.removePreference() - } - true - } - - else -> super.onOptionsItemSelected(item) - } -} \ No newline at end of file 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 6554142..d137e90 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 @@ -83,10 +83,6 @@ open class SettingsFragment: PreferenceFragmentCompat() { requirePreference("pref_developer_euicc_memory_reset") .bindBooleanFlow(preferenceRepository.euiccMemoryResetFlow) - - requirePreference("pref_developer_isdr_aid_list").apply { - intent = Intent(requireContext(), IsdrAidListActivity::class.java) - } } protected fun requirePreference(key: CharSequence) = 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 928079f..c69c5e4 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 @@ -5,13 +5,11 @@ import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore import androidx.fragment.app.Fragment import im.angry.openeuicc.OpenEuiccApplication import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import java.util.Base64 private val Context.dataStore: DataStore by preferencesDataStore(name = "prefs") @@ -37,20 +35,6 @@ internal object PreferenceKeys { val UNFILTERED_PROFILE_LIST = booleanPreferencesKey("unfiltered_profile_list") val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate") val EUICC_MEMORY_RESET = booleanPreferencesKey("euicc_memory_reset") - val ISDR_AID_LIST = stringPreferencesKey("isdr_aid_list") -} - -const val EUICC_DEFAULT_ISDR_AID = "A0000005591010FFFFFFFF8900000100" - -internal object PreferenceConstants { - val DEFAULT_AID_LIST = """ - # One AID per line. Comment lines start with #. - # eUICC standard - $EUICC_DEFAULT_ISDR_AID - - # 5ber - A0000005591010FFFFFFFF8900050500 - """.trimIndent() } open class PreferenceRepository(private val context: Context) { @@ -70,46 +54,20 @@ open class PreferenceRepository(private val context: Context) { val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false) val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false) val euiccMemoryResetFlow = bindFlow(PreferenceKeys.EUICC_MEMORY_RESET, false) - val isdrAidListFlow = bindFlow( - PreferenceKeys.ISDR_AID_LIST, - PreferenceConstants.DEFAULT_AID_LIST, - { Base64.getEncoder().encodeToString(it.encodeToByteArray()) }, - { Base64.getDecoder().decode(it).decodeToString() }) - protected fun bindFlow( - key: Preferences.Key, - defaultValue: T, - encoder: (T) -> T = { it }, - decoder: (T) -> T = { it } - ): PreferenceFlowWrapper = - PreferenceFlowWrapper(context, key, defaultValue, encoder, decoder) + protected fun bindFlow(key: Preferences.Key, defaultValue: T): PreferenceFlowWrapper = + PreferenceFlowWrapper(context, key, defaultValue) } class PreferenceFlowWrapper private constructor( private val context: Context, private val key: Preferences.Key, inner: Flow, - private val encoder: (T) -> T, ) : Flow by inner { - internal constructor( - context: Context, - key: Preferences.Key, - defaultValue: T, - encoder: (T) -> T, - decoder: (T) -> T - ) : - this( - context, - key, - context.dataStore.data.map { it[key]?.let(decoder) ?: defaultValue }, - encoder - ) + internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : + this(context, key, context.dataStore.data.map { it[key] ?: defaultValue }) suspend fun updatePreference(value: T) { - context.dataStore.edit { it[key] = encoder(value) } - } - - suspend fun removePreference() { - context.dataStore.edit { it.remove(key) } + context.dataStore.edit { it[key] = value } } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/StringUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/StringUtils.kt index 9f993a3..8d72462 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/StringUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/StringUtils.kt @@ -1,7 +1,7 @@ package im.angry.openeuicc.util fun String.decodeHex(): ByteArray { - require(length % 2 == 0) { "Must have an even length" } + check(length % 2 == 0) { "Must have an even length" } val decodedLength = length / 2 val out = ByteArray(decodedLength) @@ -29,22 +29,6 @@ fun formatFreeSpace(size: Int): String = "$size B" } -/** - * Decode a list of potential ISDR AIDs, one per line. Lines starting with '#' are ignored. - * If none is found, at least EUICC_DEFAULT_ISDR_AID is returned - */ -fun parseIsdrAidList(s: String): List = - s.split('\n').map(String::trim).filter { !it.startsWith('#') } - .map(String::trim) - .mapNotNull { - try { - it.decodeHex() - } catch (_: IllegalArgumentException) { - null - } - } - .ifEmpty { listOf(EUICC_DEFAULT_ISDR_AID.decodeHex()) } - fun String.prettyPrintJson(): String { val ret = StringBuilder() var inQuotes = false diff --git a/app-common/src/main/res/layout/activity_isdr_aid_list.xml b/app-common/src/main/res/layout/activity_isdr_aid_list.xml deleted file mode 100644 index 06a75a1..0000000 --- a/app-common/src/main/res/layout/activity_isdr_aid_list.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app-common/src/main/res/menu/activity_isdr_aid_list.xml b/app-common/src/main/res/menu/activity_isdr_aid_list.xml deleted file mode 100644 index 32f178a..0000000 --- a/app-common/src/main/res/menu/activity_isdr_aid_list.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ 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 d51e2c7..35fd400 100644 --- a/app-common/src/main/res/values-ja/strings.xml +++ b/app-common/src/main/res/values-ja/strings.xml @@ -124,7 +124,6 @@ %s のログ 開発者になるまであと %d ステップです。 あなたは開発者になりました! - カスタム ISD-R AID リストが保存されました 設定 通知 eSIM のプロファイル操作により、通信事業者に通知が送信されます。必要に応じてこの動作を微調整できます。 @@ -149,7 +148,6 @@ 非運用のプロファイルも含めます SM-DP+ TLS 証明書を無視する RSP サーバーで使用される TLS 証明書を受け入れます - 一部のブランドの取り外し可能な eUICC では、独自の非標準 ISD-R AID が使用されている場合があり、サードパーティ アプリからアクセスできなくなります。アプリはこのリストに追加された非標準の AID の使用を試みる可能性がありますが、動作することは保証されません。 情報 アプリバージョン ソースコード @@ -166,7 +164,4 @@ eUICC の消去を可能にする この操作は、デフォルトでは非表示になっている危険な操作です。代わりに、すべての構成ファイルを手動で削除することもできます。 モデムに更新コマンドを送信 - ISD-R AID リストのカスタマイズ - リセット - ISD-R AID リスト 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 32ced90..2e069bd 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -65,7 +65,6 @@ 删除 保存日志 %s 的日志 - 自定义 ISD-R AID 列表已保存 设置 通知 操作 eSIM 配置文件会向运营商发送通知。根据需要在此处微调此行为。 @@ -82,7 +81,6 @@ 详细日志中包含敏感信息,开启此功能后请仅与你信任的人共享你的日志。 日志 查看应用程序的最新调试日志 - 某些品牌的可移除 eUICC 可能会使用自己的非标准 ISD-R AID,导致第三方应用无法访问。此 App 可以尝试使用此列表中添加的非标准 AID,但不能保证它们一定有效。 信息 App 版本 源码 @@ -166,7 +164,4 @@ 允许擦除 eUICC 此操作是默认隐藏的危险操作。作为替代方案,您可以手动删除所有配置文件。 向基带发送刷新命令 - 自定义 ISD-R AID 列表 - 重置 - ISD-R AID 列表 \ No newline at end of file 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 5136bf7..729893c 100644 --- a/app-common/src/main/res/values-zh-rTW/strings.xml +++ b/app-common/src/main/res/values-zh-rTW/strings.xml @@ -65,7 +65,6 @@ 刪除 儲存日誌 %s 的日誌 - 自訂 ISD-R AID 列表已儲存 設定 通知 變更 eSIM 設定檔會向電信業者傳送通知。根據需要在此處微調此行為。 @@ -82,7 +81,6 @@ 進階 允許 停用/刪除 已啟用的設定檔 預設情況下,此應用程式會阻止您停用可插拔 eSIM 中已啟用的設定檔。\n因為這樣做 有時 會導致無法存取。\n勾選此框以 移除 此保護措施。 - 某些品牌的可移除 eUICC 可能會使用自己的非標準 ISD-R AID,導致第三方應用程式無法存取。此 App 可以嘗試使用此清單中新增的非標準 AID,但不能保證它們一定有效。 資訊 App 版本 原始碼 @@ -166,7 +164,4 @@ 允許擦除 eUICC 此操作是預設隱藏的危險操作。作為替代方案,您可以手動刪除所有設定檔。 向基帶發送刷新命令 - 自訂 ISD-R AID 列表 - 重置 - ISD-R AID 列表 \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 5e4e4da..a366b88 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -162,11 +162,6 @@ You are %d steps away from being a developer. You are now a developer! - Reset - - ISD-R AID List - Saved custom ISD-R AID list. - Settings Notifications eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here. @@ -194,8 +189,6 @@ Accept any TLS certificate used by the RSP server Allow erasing eUICC This is a dangerous operation and hidden by default. As an alternative, you can delete all profiles manually. - Customize ISD-R AID list - Some brands of removable eUICCs may use their own non-standard ISD-R AID, rendering them inaccessible to third-party apps. We can attempt to use non-standard AIDs added in this list, but there is no guarantee that they will work. Info App Version Source Code diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index 690a120..ce700f5 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -81,12 +81,6 @@ app:summary="@string/pref_developer_euicc_memory_reset_desc" app:title="@string/pref_developer_euicc_memory_reset" /> - -