Compare commits
No commits in common. "d4b875c808cc2ae96299dadc544202681422bcdc" and "100d2e2866ebf2fbc7a2360fad4785a5550703ec" have entirely different histories.
d4b875c808
...
100d2e2866
|
@ -135,16 +135,6 @@ open class EuiccChannelManager(protected val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>? = runBlocking {
|
|
||||||
if (!checkPrivileges()) return@runBlocking null
|
|
||||||
for (card in tm.uiccCardsInfoCompat) {
|
|
||||||
if (card.physicalSlotIndex != physicalSlotId) continue
|
|
||||||
return@runBlocking card.ports.mapNotNull { tryOpenEuiccChannel(it) }
|
|
||||||
.ifEmpty { null }
|
|
||||||
}
|
|
||||||
return@runBlocking null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel? = runBlocking {
|
fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel? = runBlocking {
|
||||||
if (!checkPrivileges()) return@runBlocking null
|
if (!checkPrivileges()) return@runBlocking null
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
|
|
|
@ -27,10 +27,6 @@ class OpenEuiccService : EuiccService() {
|
||||||
openEuiccApplication.euiccChannelManager
|
openEuiccApplication.euiccChannelManager
|
||||||
.findEuiccChannelByPortBlocking(slotId, portId)
|
.findEuiccChannelByPortBlocking(slotId, portId)
|
||||||
|
|
||||||
private fun findAllChannels(physicalSlotId: Int): List<EuiccChannel>? =
|
|
||||||
openEuiccApplication.euiccChannelManager
|
|
||||||
.findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId)
|
|
||||||
|
|
||||||
override fun onGetEid(slotId: Int): String? =
|
override fun onGetEid(slotId: Int): String? =
|
||||||
findChannel(slotId)?.lpa?.eID
|
findChannel(slotId)?.lpa?.eID
|
||||||
|
|
||||||
|
@ -145,25 +141,23 @@ class OpenEuiccService : EuiccService() {
|
||||||
override fun onDeleteSubscription(slotId: Int, iccid: String): Int {
|
override fun onDeleteSubscription(slotId: Int, iccid: String): Int {
|
||||||
Log.i(TAG, "onDeleteSubscription slotId=$slotId iccid=$iccid")
|
Log.i(TAG, "onDeleteSubscription slotId=$slotId iccid=$iccid")
|
||||||
try {
|
try {
|
||||||
val channels = findAllChannels(slotId) ?: return RESULT_FIRST_USER
|
val channel = findChannel(slotId) ?: return RESULT_FIRST_USER
|
||||||
|
|
||||||
if (!channels[0].profileExists(iccid)) {
|
if (!channel.profileExists(iccid)) {
|
||||||
return RESULT_FIRST_USER
|
return RESULT_FIRST_USER
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the profile is enabled by ANY channel (port), we cannot delete it
|
|
||||||
channels.forEach { channel ->
|
|
||||||
val profile = channel.lpa.profiles.find {
|
val profile = channel.lpa.profiles.find {
|
||||||
it.iccid == iccid
|
it.iccid == iccid
|
||||||
} ?: return RESULT_FIRST_USER
|
} ?: return RESULT_FIRST_USER
|
||||||
|
|
||||||
if (profile.state == LocalProfileInfo.State.Enabled) {
|
if (profile.state == LocalProfileInfo.State.Enabled) {
|
||||||
// Must disable the profile first
|
// Must disable the profile first
|
||||||
|
// TODO: Need to check "other port" as well for MEP
|
||||||
return RESULT_FIRST_USER
|
return RESULT_FIRST_USER
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return if (channels[0].lpa.deleteProfile(iccid)) {
|
return if (channel.lpa.deleteProfile(iccid)) {
|
||||||
RESULT_OK
|
RESULT_OK
|
||||||
} else {
|
} else {
|
||||||
RESULT_FIRST_USER
|
RESULT_FIRST_USER
|
||||||
|
|
|
@ -98,9 +98,7 @@ class SlotMappingFragment: DialogFragment(), OnMenuItemClickListener {
|
||||||
lifecycleScope.launch(Dispatchers.Main) {
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
try {
|
try {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
// Use the utility method from PrivilegedTelephonyUtils to ensure
|
tm.simSlotMapping = adapter.mappings
|
||||||
// unmapped ports have all profiles disabled
|
|
||||||
tm.updateSimSlotMapping(openEuiccApplication.euiccChannelManager, adapter.mappings)
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Toast.makeText(requireContext(), R.string.slot_mapping_failure, Toast.LENGTH_LONG).show()
|
Toast.makeText(requireContext(), R.string.slot_mapping_failure, Toast.LENGTH_LONG).show()
|
||||||
|
|
|
@ -2,9 +2,6 @@ package im.angry.openeuicc.util
|
||||||
|
|
||||||
import android.telephony.SubscriptionManager
|
import android.telephony.SubscriptionManager
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
import android.telephony.UiccSlotMapping
|
|
||||||
import im.angry.openeuicc.core.EuiccChannelManager
|
|
||||||
import net.typeblog.lpac_jni.LocalProfileInfo
|
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
val TelephonyManager.supportsDSDS: Boolean
|
val TelephonyManager.supportsDSDS: Boolean
|
||||||
|
@ -16,34 +13,6 @@ var TelephonyManager.dsdsEnabled: Boolean
|
||||||
switchMultiSimConfig(if (value) { 2 } else {1})
|
switchMultiSimConfig(if (value) { 2 } else {1})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable eSIM profiles before switching the slot mapping
|
|
||||||
// This ensures that unmapped eSIM ports never have "ghost" profiles enabled
|
|
||||||
fun TelephonyManager.updateSimSlotMapping(euiccManager: EuiccChannelManager, newMapping: Collection<UiccSlotMapping>) {
|
|
||||||
val unmapped = simSlotMapping.filterNot { mapping ->
|
|
||||||
// If the same physical slot + port pair is not found in the new mapping, it is unmapped
|
|
||||||
newMapping.any {
|
|
||||||
it.physicalSlotIndex == mapping.physicalSlotIndex && it.portIndex == mapping.portIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val undo = unmapped.mapNotNull { mapping ->
|
|
||||||
euiccManager.findEuiccChannelByPortBlocking(mapping.physicalSlotIndex, mapping.portIndex)?.let { channel ->
|
|
||||||
channel.lpa.profiles.find { it.state == LocalProfileInfo.State.Enabled }?.let { profile ->
|
|
||||||
channel.lpa.disableProfile(profile.iccid)
|
|
||||||
return@mapNotNull { channel.lpa.enableProfile(profile.iccid) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
simSlotMapping = newMapping
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
undo.forEach { it() } // Undo what we just did
|
|
||||||
throw e // Rethrow for caller to handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SubscriptionManager.tryRefreshCachedEuiccInfo(cardId: Int) {
|
fun SubscriptionManager.tryRefreshCachedEuiccInfo(cardId: Int) {
|
||||||
if (cardId != 0) {
|
if (cardId != 0) {
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in a new issue