diff --git a/app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt b/app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt index 2b89b4c..1d7bd58 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt @@ -16,7 +16,7 @@ import java.lang.IllegalArgumentException import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine -abstract class BaseEuiccChannelManager(private val context: Context) { +abstract class BaseEuiccChannelManager(protected val context: Context) { companion object { const val TAG = "BaseEuiccChannelManager" } @@ -125,4 +125,8 @@ abstract class BaseEuiccChannelManager(private val context: Context) { seService?.shutdown() seService = null } + + open fun notifyEuiccProfilesChanged(slotId: Int) { + // No-op for unprivileged + } } \ No newline at end of file diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt index 0b24114..8966dbb 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt @@ -82,7 +82,7 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh lifecycleScope.launch { val profiles = withContext(Dispatchers.IO) { - openEuiccApplication.subscriptionManager.tryRefreshCachedEuiccInfo(channel.cardId) + euiccChannelManager.notifyEuiccProfilesChanged(slotId) channel.lpa.profiles } diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt index 6ea0a15..d15ab56 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt @@ -4,12 +4,10 @@ import android.os.Bundle import android.telephony.TelephonyManager import android.util.Log import android.view.Menu -import android.view.MenuItem import android.view.View import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.Spinner -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import im.angry.openeuicc.common.R @@ -19,12 +17,12 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -class MainActivity : AppCompatActivity() { +open class MainActivity : AppCompatActivity() { companion object { const val TAG = "MainActivity" } - private lateinit var manager: BaseEuiccChannelManager + protected lateinit var manager: BaseEuiccChannelManager private lateinit var spinnerAdapter: ArrayAdapter private lateinit var spinner: Spinner @@ -33,7 +31,7 @@ class MainActivity : AppCompatActivity() { private lateinit var noEuiccPlaceholder: View - private lateinit var tm: TelephonyManager + protected lateinit var tm: TelephonyManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -71,32 +69,19 @@ class MainActivity : AppCompatActivity() { } - if (tm.supportsDSDS) { - val dsds = menu.findItem(R.id.dsds) - dsds.isVisible = true - dsds.isChecked = tm.dsdsEnabled - } - return true } - override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { - R.id.dsds -> { - tm.dsdsEnabled = !item.isChecked - Toast.makeText(this, R.string.toast_dsds_switched, Toast.LENGTH_LONG).show() - finish() - true - } - else -> false - } - private suspend fun init() { withContext(Dispatchers.IO) { manager.enumerateEuiccChannels() manager.knownChannels.forEach { Log.d(TAG, it.name) Log.d(TAG, it.lpa.eID) - openEuiccApplication.subscriptionManager.tryRefreshCachedEuiccInfo(it.cardId) + // Request the system to refresh the list of profiles every time we start + // Note that this is currently supposed to be no-op when unprivileged, + // but it could change in the future + manager.notifyEuiccProfilesChanged(it.slotId) } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt index 700db77..e07a113 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt @@ -1,28 +1,6 @@ package im.angry.openeuicc.util -import android.telephony.SubscriptionManager -import android.telephony.TelephonyManager import net.typeblog.lpac_jni.LocalProfileInfo -import java.lang.Exception - -val TelephonyManager.supportsDSDS: Boolean - get() = supportedModemCount == 2 - -var TelephonyManager.dsdsEnabled: Boolean - get() = activeModemCount >= 2 - set(value) { - switchMultiSimConfig(if (value) { 2 } else {1}) - } - -fun SubscriptionManager.tryRefreshCachedEuiccInfo(cardId: Int) { - if (cardId != 0) { - try { - requestEmbeddedSubscriptionInfoListRefresh(cardId) - } catch (e: Exception) { - // Ignore - } - } -} val LocalProfileInfo.displayName: String get() = nickName.ifEmpty { name } diff --git a/app-common/src/main/res/menu/activity_main.xml b/app-common/src/main/res/menu/activity_main.xml index 7386e70..9d1f42c 100644 --- a/app-common/src/main/res/menu/activity_main.xml +++ b/app-common/src/main/res/menu/activity_main.xml @@ -7,11 +7,4 @@ app:actionViewClass="android.widget.Spinner" android:background="?android:attr/colorPrimary" app:showAsAction="always" /> - - \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 38b1972..5ea8508 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -2,8 +2,6 @@ No eUICC found on this device.\nOn some devices, you may need to enable dual SIM first in the menu of this app. - Dual SIM - Enabled Disabled Provider: @@ -17,7 +15,6 @@ eSIM profile switched. Please wait for a while when the card is restarting. Cannot switch to new eSIM profile. Nickname cannot be longer than 64 characters - DSDS state switched. Please wait until the modem restarts. New eSIM Server (RSP / SM-DP+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cdbb508..640955e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ android:supportsRtl="true" android:theme="@style/Theme.OpenEUICC"> diff --git a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt index d40d151..fc2c07a 100644 --- a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt +++ b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt @@ -3,6 +3,7 @@ package im.angry.openeuicc.core import android.content.Context import android.telephony.UiccCardInfo import android.util.Log +import im.angry.openeuicc.BaseOpenEuiccApplication import im.angry.openeuicc.util.* import java.lang.Exception import java.lang.IllegalArgumentException @@ -35,4 +36,12 @@ class PrivilegedEuiccChannelManager(context: Context): BaseEuiccChannelManager(c } } } + + override fun notifyEuiccProfilesChanged(slotId: Int) { + (context.applicationContext as BaseOpenEuiccApplication).subscriptionManager.apply { + findEuiccChannelBySlotBlocking(slotId)?.let { + tryRefreshCachedEuiccInfo(it.cardId) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/im/angry/openeuicc/ui/LuiActivity.kt b/app/src/main/java/im/angry/openeuicc/ui/LuiActivity.kt index af35f1c..8cd2150 100644 --- a/app/src/main/java/im/angry/openeuicc/ui/LuiActivity.kt +++ b/app/src/main/java/im/angry/openeuicc/ui/LuiActivity.kt @@ -6,7 +6,7 @@ import androidx.appcompat.app.AppCompatActivity class LuiActivity : AppCompatActivity() { override fun onStart() { super.onStart() - startActivity(Intent(this, MainActivity::class.java)) + startActivity(Intent(this, PrivilegedMainActivity::class.java)) finish() } } \ No newline at end of file diff --git a/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt b/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt new file mode 100644 index 0000000..880d43b --- /dev/null +++ b/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt @@ -0,0 +1,32 @@ +package im.angry.openeuicc.ui + +import android.view.Menu +import android.view.MenuItem +import android.widget.Toast +import im.angry.openeuicc.R +import im.angry.openeuicc.util.* + +class PrivilegedMainActivity : MainActivity() { + override fun onCreateOptionsMenu(menu: Menu): Boolean { + super.onCreateOptionsMenu(menu) + menuInflater.inflate(R.menu.activity_main_privileged, menu) + + if (tm.supportsDSDS) { + val dsds = menu.findItem(R.id.dsds) + dsds.isVisible = true + dsds.isChecked = tm.dsdsEnabled + } + + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { + R.id.dsds -> { + tm.dsdsEnabled = !item.isChecked + Toast.makeText(this, R.string.toast_dsds_switched, Toast.LENGTH_LONG).show() + finish() + true + } + else -> super.onOptionsItemSelected(item) + } +} \ No newline at end of file diff --git a/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt new file mode 100644 index 0000000..28b9623 --- /dev/null +++ b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt @@ -0,0 +1,24 @@ +package im.angry.openeuicc.util + +import android.telephony.SubscriptionManager +import android.telephony.TelephonyManager +import java.lang.Exception + +val TelephonyManager.supportsDSDS: Boolean + get() = supportedModemCount == 2 + +var TelephonyManager.dsdsEnabled: Boolean + get() = activeModemCount >= 2 + set(value) { + switchMultiSimConfig(if (value) { 2 } else {1}) + } + +fun SubscriptionManager.tryRefreshCachedEuiccInfo(cardId: Int) { + if (cardId != 0) { + try { + requestEmbeddedSubscriptionInfoListRefresh(cardId) + } catch (e: Exception) { + // Ignore + } + } +} \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_privileged.xml b/app/src/main/res/menu/activity_main_privileged.xml new file mode 100644 index 0000000..2bbe20f --- /dev/null +++ b/app/src/main/res/menu/activity_main_privileged.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 60ef1da..1879a05 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,7 @@ OpenEUICC + + Dual SIM + + DSDS state switched. Please wait until the modem restarts. \ No newline at end of file