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