Compare commits

...

2 commits

5 changed files with 72 additions and 5 deletions

View file

@ -10,7 +10,7 @@ abstract class EuiccChannel(
val logicalSlotId = port.logicalSlotIndex
val portId = port.portIndex
val cardId = port.card.cardId
val name = "SLOT ${port.card.physicalSlotIndex}:${port.portIndex}"
val name = "SLOT $logicalSlotId"
val removable = port.card.isRemovable
abstract val lpa: LocalProfileAssistant

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.os.Handler
import android.os.HandlerThread
import android.se.omapi.SEService
import android.telephony.SubscriptionManager
import android.util.Log
import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.util.*
@ -77,7 +78,7 @@ open class EuiccChannelManager(protected val context: Context) {
ensureSEService()
val existing = channels.find { it.slotId == port.card.physicalSlotIndex && it.portId == port.portIndex }
if (existing != null) {
if (existing.valid) {
if (existing.valid && port.logicalSlotIndex == existing.logicalSlotId) {
return existing
} else {
existing.close()
@ -85,6 +86,11 @@ open class EuiccChannelManager(protected val context: Context) {
}
}
if (port.logicalSlotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
// We can only open channels on ports that are actually enabled
return null
}
var euiccChannel: EuiccChannel? = tryOpenEuiccChannelPrivileged(port)
if (euiccChannel == null) {

View file

@ -13,6 +13,7 @@ import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import androidx.appcompat.widget.Toolbar.OnMenuItemClickListener
import androidx.fragment.app.DialogFragment
@ -46,6 +47,7 @@ class SlotMappingFragment: DialogFragment(), OnMenuItemClickListener {
private lateinit var toolbar: Toolbar
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: SlotMappingAdapter
private lateinit var helpTextView: TextView
override fun onCreateView(
inflater: LayoutInflater,
@ -58,6 +60,7 @@ class SlotMappingFragment: DialogFragment(), OnMenuItemClickListener {
recyclerView = view.findViewById(R.id.mapping_list)
recyclerView.layoutManager =
LinearLayoutManager(view.context, LinearLayoutManager.VERTICAL, false)
helpTextView = view.findViewById(R.id.mapping_help)
return view
}
@ -87,19 +90,56 @@ class SlotMappingFragment: DialogFragment(), OnMenuItemClickListener {
recyclerView.adapter = adapter
adapter.notifyDataSetChanged()
helpTextView.text = buildHelpText()
}
}
private fun commit() {
lifecycleScope.launch(Dispatchers.Main) {
try {
withContext(Dispatchers.IO) {
tm.simSlotMapping = adapter.mappings
}
} catch (e: Exception) {
Toast.makeText(requireContext(), R.string.slot_mapping_failure, Toast.LENGTH_LONG).show()
return@launch
}
Toast.makeText(requireContext(), R.string.slot_mapping_completed, Toast.LENGTH_LONG).show()
openEuiccApplication.euiccChannelManager.invalidate()
requireActivity().finish()
}
}
private suspend fun buildHelpText() = withContext(Dispatchers.IO) {
var nLogicalSlots = adapter.mappings.size
val cards = openEuiccApplication.telephonyManager.uiccCardsInfoCompat
var nPhysicalSlots = cards.size
var idxMepCard = -1
var nMepPorts = 0
for (card in cards) {
if (card.isMultipleEnabledProfilesSupported) {
idxMepCard = card.physicalSlotIndex
nMepPorts = card.ports.size
}
}
val mayEnableDSDS =
openEuiccApplication.telephonyManager.supportsDSDS && !openEuiccApplication.telephonyManager.dsdsEnabled
val extraText =
if (nLogicalSlots == 1 && mayEnableDSDS) {
getString(R.string.slot_mapping_help_dsds)
} else if (idxMepCard != -1) {
getString(R.string.slot_mapping_help_mep, idxMepCard, nMepPorts)
} else {
""
}
getString(R.string.slot_mapping_help, nLogicalSlots, nPhysicalSlots, extraText)
}
override fun onMenuItemClick(item: MenuItem?): Boolean =
when (item!!.itemId) {
R.id.ok -> {

View file

@ -22,6 +22,22 @@
android:layout_height="wrap_content"
android:paddingTop="6dp"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintBottom_toTopOf="@id/mapping_help"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/mapping_help"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="10dp"
android:layout_marginHorizontal="24dp"
android:gravity="center"
android:textSize="12sp"
android:textColor="?attr/colorSecondary"
android:textStyle="italic"
app:layout_constraintTop_toBottomOf="@id/mapping_list"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

View file

@ -9,4 +9,9 @@
<string name="slot_mapping">Slot Mapping</string>
<string name="slot_mapping_logical_slot">Logical slot %d:</string>
<string name="slot_mapping_port">Slot %d Port %d</string>
<string name="slot_mapping_help">Your phone has %d logical and %d physical SIM slots.%s\n\nSelect which physical slot and/or "port" you want each logical slot to correspond to. Note that not all mapping modes may be supported by hardware.</string>
<string name="slot_mapping_help_mep">\n\nPhysical slot %d supports Multiple Enabled Profiles (MEP). To use this feature, associate its %d virtual "ports" to different logical slots shown above.</string>
<string name="slot_mapping_help_dsds">\nDual SIM mode is supported but disabled.</string>
<string name="slot_mapping_completed">Your new slot mapping has been set. Please wait until modem refreshes the slots.</string>
<string name="slot_mapping_failure">The specified mapping might be invalid or unsupported by hardware.</string>
</resources>