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 65d7918..e635d21 100644 --- a/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt +++ b/app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt @@ -16,6 +16,21 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { const val TAG = "OpenEuiccService" } + private val hasInternalEuicc by lazy { + telephonyManager.uiccCardsInfoCompat.any { it.isEuicc && !it.isRemovable } + } + + // TODO: Should this be configurable? + private fun shouldIgnoreSlot(physicalSlotId: Int) = + if (hasInternalEuicc) { + // For devices with an internal eUICC slot, ignore any removable UICC + telephonyManager.uiccCardsInfoCompat.find { it.physicalSlotIndex == physicalSlotId }!!.isRemovable + } else { + // Otherwise, we can report at least one removable eUICC to the system without confusing + // it too much. + telephonyManager.uiccCardsInfoCompat.firstOrNull { it.isEuicc }?.physicalSlotIndex == physicalSlotId + } + private fun findChannel(physicalSlotId: Int): EuiccChannel? = euiccChannelManager.findEuiccChannelByPhysicalSlotBlocking(physicalSlotId) @@ -111,6 +126,11 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { override fun onGetEuiccProfileInfoList(slotId: Int): GetEuiccProfileInfoListResult { Log.i(TAG, "onGetEuiccProfileInfoList slotId=$slotId") + if (shouldIgnoreSlot(slotId)) { + Log.i(TAG, "ignoring slot $slotId") + return GetEuiccProfileInfoListResult(RESULT_FIRST_USER, arrayOf(), true) + } + val channel = findChannel(slotId)!! val profiles = channel.lpa.profiles.operational.map { EuiccProfileInfo.Builder(it.iccid).apply { @@ -142,6 +162,8 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { override fun onDeleteSubscription(slotId: Int, iccid: String): Int { Log.i(TAG, "onDeleteSubscription slotId=$slotId iccid=$iccid") + if (shouldIgnoreSlot(slotId)) return RESULT_FIRST_USER + try { val channels = findAllChannels(slotId) ?: return RESULT_FIRST_USER @@ -187,6 +209,8 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { forceDeactivateSim: Boolean ): Int { Log.i(TAG,"onSwitchToSubscriptionWithPort slotId=$slotId portIndex=$portIndex iccid=$iccid forceDeactivateSim=$forceDeactivateSim") + if (shouldIgnoreSlot(slotId)) return RESULT_FIRST_USER + try { // retryWithTimeout is needed here because this function may be called just after // AOSP has switched slot mappings, in which case the slots may not be ready yet. @@ -237,6 +261,7 @@ class OpenEuiccService : EuiccService(), OpenEuiccContextMarker { override fun onUpdateSubscriptionNickname(slotId: Int, iccid: String, nickname: String?): Int { Log.i(TAG, "onUpdateSubscriptionNickname slotId=$slotId iccid=$iccid nickname=$nickname") + if (shouldIgnoreSlot(slotId)) return RESULT_FIRST_USER val channel = findChannel(slotId) ?: return RESULT_FIRST_USER if (!channel.profileExists(iccid)) { return RESULT_FIRST_USER