refactor: [3/n] Extract privileged menu / logic from MainActivity as well

This commit is contained in:
Peter Cai 2023-11-28 21:33:28 -05:00
parent 5ed4c84bf2
commit af66bc440e
13 changed files with 94 additions and 58 deletions

View file

@ -16,7 +16,7 @@ import java.lang.IllegalArgumentException
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
abstract class BaseEuiccChannelManager(private val context: Context) { abstract class BaseEuiccChannelManager(protected val context: Context) {
companion object { companion object {
const val TAG = "BaseEuiccChannelManager" const val TAG = "BaseEuiccChannelManager"
} }
@ -125,4 +125,8 @@ abstract class BaseEuiccChannelManager(private val context: Context) {
seService?.shutdown() seService?.shutdown()
seService = null seService = null
} }
open fun notifyEuiccProfilesChanged(slotId: Int) {
// No-op for unprivileged
}
} }

View file

@ -82,7 +82,7 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh
lifecycleScope.launch { lifecycleScope.launch {
val profiles = withContext(Dispatchers.IO) { val profiles = withContext(Dispatchers.IO) {
openEuiccApplication.subscriptionManager.tryRefreshCachedEuiccInfo(channel.cardId) euiccChannelManager.notifyEuiccProfilesChanged(slotId)
channel.lpa.profiles channel.lpa.profiles
} }

View file

@ -4,12 +4,10 @@ import android.os.Bundle
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Spinner import android.widget.Spinner
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R import im.angry.openeuicc.common.R
@ -19,12 +17,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class MainActivity : AppCompatActivity() { open class MainActivity : AppCompatActivity() {
companion object { companion object {
const val TAG = "MainActivity" const val TAG = "MainActivity"
} }
private lateinit var manager: BaseEuiccChannelManager protected lateinit var manager: BaseEuiccChannelManager
private lateinit var spinnerAdapter: ArrayAdapter<String> private lateinit var spinnerAdapter: ArrayAdapter<String>
private lateinit var spinner: Spinner private lateinit var spinner: Spinner
@ -33,7 +31,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var noEuiccPlaceholder: View private lateinit var noEuiccPlaceholder: View
private lateinit var tm: TelephonyManager protected lateinit var tm: TelephonyManager
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) 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 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() { private suspend fun init() {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
manager.enumerateEuiccChannels() manager.enumerateEuiccChannels()
manager.knownChannels.forEach { manager.knownChannels.forEach {
Log.d(TAG, it.name) Log.d(TAG, it.name)
Log.d(TAG, it.lpa.eID) 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)
} }
} }

View file

@ -1,28 +1,6 @@
package im.angry.openeuicc.util package im.angry.openeuicc.util
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import net.typeblog.lpac_jni.LocalProfileInfo 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 val LocalProfileInfo.displayName: String
get() = nickName.ifEmpty { name } get() = nickName.ifEmpty { name }

View file

@ -7,11 +7,4 @@
app:actionViewClass="android.widget.Spinner" app:actionViewClass="android.widget.Spinner"
android:background="?android:attr/colorPrimary" android:background="?android:attr/colorPrimary"
app:showAsAction="always" /> app:showAsAction="always" />
<item
android:id="@+id/dsds"
android:title="@string/dsds"
android:checkable="true"
android:visible="false"
app:showAsAction="never" />
</menu> </menu>

View file

@ -2,8 +2,6 @@
<resources> <resources>
<string name="no_euicc">No eUICC found on this device.\nOn some devices, you may need to enable dual SIM first in the menu of this app.</string> <string name="no_euicc">No eUICC found on this device.\nOn some devices, you may need to enable dual SIM first in the menu of this app.</string>
<string name="dsds">Dual SIM</string>
<string name="enabled">Enabled</string> <string name="enabled">Enabled</string>
<string name="disabled">Disabled</string> <string name="disabled">Disabled</string>
<string name="provider">Provider:</string> <string name="provider">Provider:</string>
@ -17,7 +15,6 @@
<string name="toast_profile_enabled">eSIM profile switched. Please wait for a while when the card is restarting.</string> <string name="toast_profile_enabled">eSIM profile switched. Please wait for a while when the card is restarting.</string>
<string name="toast_profile_enable_failed">Cannot switch to new eSIM profile.</string> <string name="toast_profile_enable_failed">Cannot switch to new eSIM profile.</string>
<string name="toast_profile_name_too_long">Nickname cannot be longer than 64 characters</string> <string name="toast_profile_name_too_long">Nickname cannot be longer than 64 characters</string>
<string name="toast_dsds_switched">DSDS state switched. Please wait until the modem restarts.</string>
<string name="profile_download">New eSIM</string> <string name="profile_download">New eSIM</string>
<string name="profile_download_server">Server (RSP / SM-DP+)</string> <string name="profile_download_server">Server (RSP / SM-DP+)</string>

View file

@ -13,7 +13,7 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.OpenEUICC"> android:theme="@style/Theme.OpenEUICC">
<activity <activity
android:name=".ui.MainActivity" android:name=".ui.PrivilegedMainActivity"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View file

@ -3,6 +3,7 @@ package im.angry.openeuicc.core
import android.content.Context import android.content.Context
import android.telephony.UiccCardInfo import android.telephony.UiccCardInfo
import android.util.Log import android.util.Log
import im.angry.openeuicc.BaseOpenEuiccApplication
import im.angry.openeuicc.util.* import im.angry.openeuicc.util.*
import java.lang.Exception import java.lang.Exception
import java.lang.IllegalArgumentException 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)
}
}
}
} }

View file

@ -6,7 +6,7 @@ import androidx.appcompat.app.AppCompatActivity
class LuiActivity : AppCompatActivity() { class LuiActivity : AppCompatActivity() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
startActivity(Intent(this, MainActivity::class.java)) startActivity(Intent(this, PrivilegedMainActivity::class.java))
finish() finish()
} }
} }

View file

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

View file

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

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/dsds"
android:title="@string/dsds"
android:checkable="true"
android:visible="false"
app:showAsAction="never" />
</menu>

View file

@ -1,3 +1,7 @@
<resources> <resources>
<string name="app_name">OpenEUICC</string> <string name="app_name">OpenEUICC</string>
<string name="dsds">Dual SIM</string>
<string name="toast_dsds_switched">DSDS state switched. Please wait until the modem restarts.</string>
</resources> </resources>