Compare commits

..

No commits in common. "d7bfd84de925735957b780e3f53f6510c95c8303" and "dc6b3a4810bd05b25bd5433993cece12a79c5945" have entirely different histories.

18 changed files with 33 additions and 284 deletions

View file

@ -28,10 +28,6 @@
android:name="im.angry.openeuicc.ui.LogsActivity"
android:label="@string/pref_advanced_logs" />
<activity
android:name="im.angry.openeuicc.ui.IsdrAidListActivity"
android:label="@string/isdr_aid_list" />
<activity
android:exported="true"
android:name="im.angry.openeuicc.ui.wizard.DownloadWizardActivity"

View file

@ -26,23 +26,14 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
}
}
override suspend fun tryOpenEuiccChannel(
port: UiccPortInfoCompat,
isdrAid: ByteArray
): EuiccChannel? {
override suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? {
if (port.portIndex != 0) {
Log.w(
DefaultEuiccChannelManager.TAG,
"OMAPI channel attempted on non-zero portId, this may or may not work."
)
Log.w(DefaultEuiccChannelManager.TAG, "OMAPI channel attempted on non-zero portId, this may or may not work.")
}
ensureSEService()
Log.i(
DefaultEuiccChannelManager.TAG,
"Trying OMAPI for physical slot ${port.card.physicalSlotIndex}"
)
Log.i(DefaultEuiccChannelManager.TAG, "Trying OMAPI for physical slot ${port.card.physicalSlotIndex}")
try {
return EuiccChannelImpl(
context.getString(R.string.omapi),
@ -53,7 +44,6 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
port,
context.preferenceRepository.verboseLoggingFlow
),
isdrAid,
context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow,
).also {
@ -71,11 +61,7 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
return null
}
override fun tryOpenUsbEuiccChannel(
usbDevice: UsbDevice,
usbInterface: UsbInterface,
isdrAid: ByteArray
): EuiccChannel? {
override fun tryOpenUsbEuiccChannel(usbDevice: UsbDevice, usbInterface: UsbInterface): EuiccChannel? {
val (bulkIn, bulkOut) = usbInterface.endpoints.bulkPair
if (bulkIn == null || bulkOut == null) return null
val conn = usbManager.openDevice(usbDevice) ?: return null
@ -90,7 +76,6 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
bulkOut,
context.preferenceRepository.verboseLoggingFlow
),
isdrAid,
context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow,
)

View file

@ -12,7 +12,6 @@ import im.angry.openeuicc.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.merge
@ -50,24 +49,6 @@ open class DefaultEuiccChannelManager(
protected open val uiccCards: Collection<UiccCardInfoCompat>
get() = (0..<tm.activeModemCountCompat).map { FakeUiccCardInfoCompat(it) }
private suspend inline fun tryOpenChannelFirstValidAid(openFn: (ByteArray) -> 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)
}

View file

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

View file

@ -13,17 +13,21 @@ class EuiccChannelImpl(
override val port: UiccPortInfoCompat,
override val intrinsicChannelName: String?,
override val apduInterface: ApduInterface,
isdrAid: ByteArray,
verboseLoggingFlow: Flow<Boolean>,
ignoreTLSCertificateFlow: Flow<Boolean>
) : 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)
)

View file

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

View file

@ -83,10 +83,6 @@ open class SettingsFragment: PreferenceFragmentCompat() {
requirePreference<CheckBoxPreference>("pref_developer_euicc_memory_reset")
.bindBooleanFlow(preferenceRepository.euiccMemoryResetFlow)
requirePreference<Preference>("pref_developer_isdr_aid_list").apply {
intent = Intent(requireContext(), IsdrAidListActivity::class.java)
}
}
protected fun <T : Preference> requirePreference(key: CharSequence) =

View file

@ -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<Preferences> 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 <T> bindFlow(
key: Preferences.Key<T>,
defaultValue: T,
encoder: (T) -> T = { it },
decoder: (T) -> T = { it }
): PreferenceFlowWrapper<T> =
PreferenceFlowWrapper(context, key, defaultValue, encoder, decoder)
protected fun <T> bindFlow(key: Preferences.Key<T>, defaultValue: T): PreferenceFlowWrapper<T> =
PreferenceFlowWrapper(context, key, defaultValue)
}
class PreferenceFlowWrapper<T> private constructor(
private val context: Context,
private val key: Preferences.Key<T>,
inner: Flow<T>,
private val encoder: (T) -> T,
) : Flow<T> by inner {
internal constructor(
context: Context,
key: Preferences.Key<T>,
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<T>, 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 }
}
}

View file

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

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/toolbar_activity" />
<EditText
android:id="@+id/isdr_aid_list_editor"
android:layout_width="0dp"
android:layout_height="0dp"
android:importantForAutofill="no"
android:inputType="textMultiLine"
android:gravity="top|start"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="LabelFor" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/save"
android:icon="@drawable/ic_save_as_black"
android:title="@string/logs_save"
app:showAsAction="always" />
<item
android:id="@+id/reset"
android:title="@string/reset"
android:icon="@drawable/ic_refresh_black"
app:showAsAction="ifRoom" />
</menu>

View file

@ -124,7 +124,6 @@
<string name="logs_filename_template">%s のログ</string>
<string name="developer_options_steps">開発者になるまであと %d ステップです。</string>
<string name="developer_options_enabled">あなたは開発者になりました!</string>
<string name="isdr_aid_list_saved">カスタム ISD-R AID リストが保存されました</string>
<string name="pref_settings">設定</string>
<string name="pref_notifications">通知</string>
<string name="pref_notifications_desc">eSIM のプロファイル操作により、通信事業者に通知が送信されます。必要に応じてこの動作を微調整できます。</string>
@ -149,7 +148,6 @@
<string name="pref_developer_unfiltered_profile_list_desc">非運用のプロファイルも含めます</string>
<string name="pref_developer_ignore_tls_certificate">SM-DP+ TLS 証明書を無視する</string>
<string name="pref_developer_ignore_tls_certificate_desc">RSP サーバーで使用される TLS 証明書を受け入れます</string>
<string name="pref_developer_isdr_aid_list_desc">一部のブランドの取り外し可能な eUICC では、独自の非標準 ISD-R AID が使用されている場合があり、サードパーティ アプリからアクセスできなくなります。アプリはこのリストに追加された非標準の AID の使用を試みる可能性がありますが、動作することは保証されません。</string>
<string name="pref_info">情報</string>
<string name="pref_info_app_version">アプリバージョン</string>
<string name="pref_info_source_code">ソースコード</string>
@ -166,7 +164,4 @@
<string name="pref_developer_euicc_memory_reset">eUICC の消去を可能にする</string>
<string name="pref_developer_euicc_memory_reset_desc">この操作は、デフォルトでは非表示になっている危険な操作です。代わりに、すべての構成ファイルを手動で削除することもできます。</string>
<string name="pref_developer_refresh_after_switch">モデムに更新コマンドを送信</string>
<string name="pref_developer_isdr_aid_list">ISD-R AID リストのカスタマイズ</string>
<string name="reset">リセット</string>
<string name="isdr_aid_list">ISD-R AID リスト</string>
</resources>

View file

@ -65,7 +65,6 @@
<string name="profile_notification_delete">删除</string>
<string name="logs_save">保存日志</string>
<string name="logs_filename_template">%s 的日志</string>
<string name="isdr_aid_list_saved">自定义 ISD-R AID 列表已保存</string>
<string name="pref_settings">设置</string>
<string name="pref_notifications">通知</string>
<string name="pref_notifications_desc">操作 eSIM 配置文件会向运营商发送通知。根据需要在此处微调此行为。</string>
@ -82,7 +81,6 @@
<string name="pref_advanced_verbose_logging_desc">详细日志中包含敏感信息,开启此功能后请仅与你信任的人共享你的日志。</string>
<string name="pref_advanced_logs">日志</string>
<string name="pref_advanced_logs_desc">查看应用程序的最新调试日志</string>
<string name="pref_developer_isdr_aid_list_desc">某些品牌的可移除 eUICC 可能会使用自己的非标准 ISD-R AID导致第三方应用无法访问。此 App 可以尝试使用此列表中添加的非标准 AID但不能保证它们一定有效。</string>
<string name="pref_info">信息</string>
<string name="pref_info_app_version">App 版本</string>
<string name="pref_info_source_code">源码</string>
@ -166,7 +164,4 @@
<string name="pref_developer_euicc_memory_reset">允许擦除 eUICC</string>
<string name="pref_developer_euicc_memory_reset_desc">此操作是默认隐藏的危险操作。作为替代方案,您可以手动删除所有配置文件。</string>
<string name="pref_developer_refresh_after_switch">向基带发送刷新命令</string>
<string name="pref_developer_isdr_aid_list">自定义 ISD-R AID 列表</string>
<string name="reset">重置</string>
<string name="isdr_aid_list">ISD-R AID 列表</string>
</resources>

View file

@ -65,7 +65,6 @@
<string name="profile_notification_delete">刪除</string>
<string name="logs_save">儲存日誌</string>
<string name="logs_filename_template">%s 的日誌</string>
<string name="isdr_aid_list_saved">自訂 ISD-R AID 列表已儲存</string>
<string name="pref_settings">設定</string>
<string name="pref_notifications">通知</string>
<string name="pref_notifications_desc">變更 eSIM 設定檔會向電信業者傳送通知。根據需要在此處微調此行為。</string>
@ -82,7 +81,6 @@
<string name="pref_advanced">進階</string>
<string name="pref_advanced_disable_safeguard_removable_esim">允許 停用/刪除 已啟用的設定檔</string>
<string name="pref_advanced_disable_safeguard_removable_esim_desc">預設情況下,此應用程式會阻止您停用可插拔 eSIM 中已啟用的設定檔。\n因為這樣做 <i>有時</i> 會導致無法存取。\n勾選此框以 <i>移除</i> 此保護措施。</string>
<string name="pref_developer_isdr_aid_list_desc">某些品牌的可移除 eUICC 可能會使用自己的非標準 ISD-R AID導致第三方應用程式無法存取。此 App 可以嘗試使用此清單中新增的非標準 AID但不能保證它們一定有效。</string>
<string name="pref_info">資訊</string>
<string name="pref_info_app_version">App 版本</string>
<string name="pref_info_source_code">原始碼</string>
@ -166,7 +164,4 @@
<string name="pref_developer_euicc_memory_reset">允許擦除 eUICC</string>
<string name="pref_developer_euicc_memory_reset_desc">此操作是預設隱藏的危險操作。作為替代方案,您可以手動刪除所有設定檔。</string>
<string name="pref_developer_refresh_after_switch">向基帶發送刷新命令</string>
<string name="pref_developer_isdr_aid_list">自訂 ISD-R AID 列表</string>
<string name="reset">重置</string>
<string name="isdr_aid_list">ISD-R AID 列表</string>
</resources>

View file

@ -162,11 +162,6 @@
<string name="developer_options_steps">You are %d steps away from being a developer.</string>
<string name="developer_options_enabled">You are now a developer!</string>
<string name="reset">Reset</string>
<string name="isdr_aid_list">ISD-R AID List</string>
<string name="isdr_aid_list_saved">Saved custom ISD-R AID list.</string>
<string name="pref_settings">Settings</string>
<string name="pref_notifications">Notifications</string>
<string name="pref_notifications_desc">eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.</string>
@ -194,8 +189,6 @@
<string name="pref_developer_ignore_tls_certificate_desc">Accept any TLS certificate used by the RSP server</string>
<string name="pref_developer_euicc_memory_reset">Allow erasing eUICC</string>
<string name="pref_developer_euicc_memory_reset_desc">This is a dangerous operation and hidden by default. As an alternative, you can delete all profiles manually.</string>
<string name="pref_developer_isdr_aid_list">Customize ISD-R AID list</string>
<string name="pref_developer_isdr_aid_list_desc">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.</string>
<string name="pref_info">Info</string>
<string name="pref_info_app_version">App Version</string>
<string name="pref_info_source_code">Source Code</string>

View file

@ -81,12 +81,6 @@
app:summary="@string/pref_developer_euicc_memory_reset_desc"
app:title="@string/pref_developer_euicc_memory_reset" />
<Preference
app:iconSpaceReserved="false"
app:key="pref_developer_isdr_aid_list"
app:title="@string/pref_developer_isdr_aid_list"
app:summary="@string/pref_developer_isdr_aid_list_desc" />
</im.angry.openeuicc.ui.preference.LongSummaryPreferenceCategory>
<PreferenceCategory

View file

@ -128,6 +128,10 @@ internal class OmapiConnCheck(private val context: Context): CompatibilityCheck(
}
internal class IsdrChannelAccessCheck(private val context: Context): CompatibilityCheck(context) {
companion object {
val ISDR_AID = "A0000005591010FFFFFFFF8900000100".decodeHex()
}
override val title: String
get() = context.getString(R.string.compatibility_check_isdr_channel)
override val defaultDescription: String
@ -143,10 +147,7 @@ internal class IsdrChannelAccessCheck(private val context: Context): Compatibili
val (validSlotIds, result) = readers.map {
try {
// Note: we ONLY check the default ISD-R AID, because this test is for the _device_,
// NOT the eUICC. We don't care what AID a potential eUICC might use, all we need to
// check is we can open _some_ AID.
it.openSession().openLogicalChannel(EUICC_DEFAULT_ISDR_AID.decodeHex())?.close()
it.openSession().openLogicalChannel(ISDR_AID)?.close()
Pair(it.slotIndex, State.SUCCESS)
} catch (_: SecurityException) {
// Ignore; this is expected when everything works

View file

@ -14,15 +14,12 @@ class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFacto
get() = context
@Suppress("NAME_SHADOWING")
override suspend fun tryOpenEuiccChannel(
port: UiccPortInfoCompat,
isdrAid: ByteArray
): EuiccChannel? {
override suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? {
val port = port as RealUiccPortInfoCompat
if (port.card.isRemovable) {
// Attempt unprivileged (OMAPI) before TelephonyManager
// but still try TelephonyManager in case OMAPI is broken
super.tryOpenEuiccChannel(port, isdrAid)?.let { return it }
super.tryOpenEuiccChannel(port)?.let { return it }
}
if (port.card.isEuicc || preferenceRepository.removableTelephonyManagerFlow.first()) {
@ -40,7 +37,6 @@ class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFacto
telephonyManager,
context.preferenceRepository.verboseLoggingFlow
),
isdrAid,
context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow,
)
@ -53,6 +49,6 @@ class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFacto
}
}
return super.tryOpenEuiccChannel(port, isdrAid)
return super.tryOpenEuiccChannel(port)
}
}