Compare commits

...

2 commits

5 changed files with 41 additions and 16 deletions

View file

@ -29,7 +29,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.typeblog.lpac_jni.LocalProfileNotification
import java.lang.Exception
open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesChangedListener {
@ -159,6 +158,14 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi
preferenceRepository.notificationDisableFlow.first()
}
protected open fun populatePopupWithProfileActions(popup: PopupMenu, profile: LocalProfileInfo) {
popup.inflate(R.menu.profile_options)
if (profile.isEnabled) {
popup.menu.findItem(R.id.enable).isVisible = false
popup.menu.findItem(R.id.delete).isVisible = false
}
}
sealed class ViewHolder(root: View) : RecyclerView.ViewHolder(root) {
enum class Type(val value: Int) {
PROFILE(0),
@ -208,7 +215,7 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi
name.text = profile.displayName
state.setText(
if (isEnabled()) {
if (profile.isEnabled) {
R.string.enabled
} else {
R.string.disabled
@ -219,19 +226,10 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi
iccid.transformationMethod = PasswordTransformationMethod.getInstance()
}
private fun isEnabled(): Boolean =
profile.state == LocalProfileInfo.State.Enabled
private fun showOptionsMenu() {
PopupMenu(root.context, profileMenu).apply {
setOnMenuItemClickListener(::onMenuItemClicked)
inflate(R.menu.profile_options)
if (isEnabled()) {
menu.findItem(R.id.enable).isVisible = false
menu.findItem(R.id.delete).isVisible = false
} else {
menu.findItem(R.id.disable).isVisible = false
}
populatePopupWithProfileActions(this, profile)
show()
}
}

View file

@ -2,6 +2,7 @@ package im.angry.openeuicc.util
import android.content.Context
import android.content.pm.PackageManager
import net.typeblog.lpac_jni.LocalProfileInfo
import java.lang.RuntimeException
val Context.selfAppVersion: String
@ -11,4 +12,7 @@ val Context.selfAppVersion: String
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
throw RuntimeException(e)
}
}
val LocalProfileInfo.isEnabled: Boolean
get() = state == LocalProfileInfo.State.Enabled

View file

@ -6,6 +6,7 @@
<item
android:id="@+id/disable"
android:visible="false"
android:title="@string/disable"/>
<item

View file

@ -3,8 +3,10 @@ package im.angry.openeuicc.ui
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.PopupMenu
import im.angry.openeuicc.R
import im.angry.openeuicc.util.*
import net.typeblog.lpac_jni.LocalProfileInfo
class PrivilegedEuiccManagementFragment: EuiccManagementFragment() {
companion object {
@ -22,4 +24,16 @@ class PrivilegedEuiccManagementFragment: EuiccManagementFragment() {
} else {
listOf()
}
override fun populatePopupWithProfileActions(popup: PopupMenu, profile: LocalProfileInfo) {
super.populatePopupWithProfileActions(popup, profile)
if (profile.isEnabled && !channel.removable) {
// Only show the disable option for non-removable eUICCs
// Some devices without internal eUICCs have the "optimization" of ignoring SIM
// slots without a valid profile. This can lead to "bricking" of external eUICCs
// at least for that specific device.
// TODO: Maybe we can still make this option available in some sort of "advanced" mode.
popup.menu.findItem(im.angry.openeuicc.common.R.id.disable).isVisible = true
}
}
}

View file

@ -19,9 +19,11 @@ fun TelephonyManager.setDsdsEnabled(euiccManager: EuiccChannelManager, enabled:
euiccManager.enumerateEuiccChannels()
}
// Disable all eSIM profiles before performing a DSDS switch
// Disable all eSIM profiles before performing a DSDS switch (only for internal eSIMs)
euiccManager.knownChannels.forEach {
it.lpa.disableActiveProfileWithUndo()
if (!it.removable) {
it.lpa.disableActiveProfileWithUndo()
}
}
switchMultiSimConfig(if (enabled) { 2 } else { 1 })
@ -42,7 +44,13 @@ fun TelephonyManager.updateSimSlotMapping(
val undo = unmapped.mapNotNull { mapping ->
euiccManager.findEuiccChannelByPortBlocking(mapping.physicalSlotIndex, mapping.portIndex)?.let { channel ->
return@mapNotNull channel.lpa.disableActiveProfileWithUndo()
if (!channel.removable) {
return@mapNotNull channel.lpa.disableActiveProfileWithUndo()
} else {
// Do not do anything for external eUICCs -- we can't really trust them to work properly
// with no profile enabled.
return@mapNotNull null
}
}
}