feat: Allow forcing the use of TelephonyManager everywhere
All checks were successful
/ build-debug (push) Successful in 4m39s

Manual merge of #139, but removed all reference to "TMAPI" because such
a term does not exist.

Also reworked PreferenceRepository to allow extensibility from the
privileged app.
This commit is contained in:
septs 2025-03-08 17:25:26 -05:00 committed by Peter Cai
parent ece231f17b
commit 17102be7cb
12 changed files with 59 additions and 6 deletions

View file

@ -122,7 +122,7 @@ open class SettingsFragment: PreferenceFragmentCompat() {
return true
}
private fun CheckBoxPreference.bindBooleanFlow(flow: PreferenceFlowWrapper<Boolean>) {
protected fun CheckBoxPreference.bindBooleanFlow(flow: PreferenceFlowWrapper<Boolean>) {
lifecycleScope.launch {
flow.collect { isChecked = it }
}

View file

@ -35,7 +35,7 @@ internal object PreferenceKeys {
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
}
class PreferenceRepository(private val context: Context) {
open class PreferenceRepository(private val context: Context) {
// Expose flows so that we can also handle default values
// ---- Profile Notifications ----
val notificationDownloadFlow = bindFlow(PreferenceKeys.NOTIFICATION_DOWNLOAD, true)
@ -51,7 +51,7 @@ class PreferenceRepository(private val context: Context) {
val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false)
val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false)
private fun <T> bindFlow(key: Preferences.Key<T>, defaultValue: T): PreferenceFlowWrapper<T> =
protected fun <T> bindFlow(key: Preferences.Key<T>, defaultValue: T): PreferenceFlowWrapper<T> =
PreferenceFlowWrapper(context, key, defaultValue)
}

View file

@ -52,7 +52,7 @@
</PreferenceCategory>
<PreferenceCategory
<im.angry.openeuicc.ui.preference.LongSummaryPreferenceCategory
app:key="pref_developer"
app:title="@string/pref_developer"
app:iconSpaceReserved="false">
@ -69,7 +69,7 @@
app:summary="@string/pref_developer_ignore_tls_certificate_desc"
app:title="@string/pref_developer_ignore_tls_certificate" />
</PreferenceCategory>
</im.angry.openeuicc.ui.preference.LongSummaryPreferenceCategory>
<PreferenceCategory
app:key="pref_info"

View file

@ -5,6 +5,7 @@ import android.util.Log
import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.R
import im.angry.openeuicc.util.*
import kotlinx.coroutines.flow.first
import java.lang.IllegalArgumentException
class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFactory(context) {
@ -21,7 +22,7 @@ class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFacto
super.tryOpenEuiccChannel(port)?.let { return it }
}
if (port.card.isEuicc) {
if (port.card.isEuicc || (context.preferenceRepository as PrivilegedPreferenceRepository).removableTelephonyManagerFlow.first()) {
Log.i(
DefaultEuiccChannelManager.TAG,
"Trying TelephonyManager for slot ${port.card.physicalSlotIndex} port ${port.portIndex}"

View file

@ -6,6 +6,7 @@ import im.angry.openeuicc.core.EuiccChannelManagerFactory
import im.angry.openeuicc.core.PrivilegedEuiccChannelFactory
import im.angry.openeuicc.core.PrivilegedEuiccChannelManager
import im.angry.openeuicc.core.PrivilegedEuiccChannelManagerFactory
import im.angry.openeuicc.util.*
class PrivilegedAppContainer(context: Context) : DefaultAppContainer(context) {
override val euiccChannelManager: EuiccChannelManager by lazy {
@ -27,4 +28,8 @@ class PrivilegedAppContainer(context: Context) : DefaultAppContainer(context) {
override val customizableTextProvider by lazy {
PrivilegedCustomizableTextProvider(context)
}
override val preferenceRepository by lazy {
PrivilegedPreferenceRepository(context)
}
}

View file

@ -1,11 +1,17 @@
package im.angry.openeuicc.ui
import android.os.Bundle
import androidx.preference.CheckBoxPreference
import androidx.preference.Preference
import im.angry.openeuicc.R
import im.angry.openeuicc.util.*
class PrivilegedSettingsFragment : SettingsFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
super.onCreatePreferences(savedInstanceState, rootKey)
addPreferencesFromResource(R.xml.pref_privileged_settings)
mergePreferenceOverlay("pref_developer_overlay", "pref_developer")
// It's stupid to _disable_ things for privileged, but for now, the per-app locale picker
// is not usable for apps signed with the platform key.
// ref: <https://android.googlesource.com/platform/packages/apps/Settings/+/refs/tags/android-15.0.0_r6/src/com/android/settings/applications/AppLocaleUtil.java#60>
@ -13,5 +19,9 @@ class PrivilegedSettingsFragment : SettingsFragment() {
// eventually work for platform-signed apps. Or, at some point we might introduce our own
// locale picker, which hopefully works whether privileged or not.
requirePreference<Preference>("pref_advanced_language").isVisible = false
// Force use TelephonyManager API
requirePreference<CheckBoxPreference>("pref_developer_tmapi_removable")
.bindBooleanFlow((preferenceRepository as PrivilegedPreferenceRepository).removableTelephonyManagerFlow)
}
}

View file

@ -0,0 +1,15 @@
package im.angry.openeuicc.util
import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
internal object PrivilegedPreferenceKeys {
// ---- Developer Options ----
val REMOVABLE_TELEPHONY_MANAGER = booleanPreferencesKey("removable_telephony_manager")
}
class PrivilegedPreferenceRepository(context: Context) : PreferenceRepository(context) {
// ---- Developer Options ----
val removableTelephonyManagerFlow =
bindFlow(PrivilegedPreferenceKeys.REMOVABLE_TELEPHONY_MANAGER, false)
}

View file

@ -17,4 +17,6 @@
<string name="lui_desc">使用しているデバイスは eSIM をサポートしています。モバイルネットワークに接続するには通信事業者が発行した eSIM をダウンロードするか、物理 SIM を挿入してください。</string>
<string name="lui_skip">スキップ</string>
<string name="lui_download">eSIM をダウンロード</string>
<string name="pref_developer_telephony_manager_removable">TelephonyManagerをどこでも使用</string>
<string name="pref_developer_telephony_manager_removable_desc">デフォルトでは、非特権モード (EasyEUICC) と一致するように、取り外し可能な eUICC に対して OMAPI のみが試行されます。これは、一部のデバイスではうまく機能しない可能性があります。このオプションを選択する場合、取り外し可能な eUICC でも TelephonyManager を使用することになります。</string>
</resources>

View file

@ -17,4 +17,6 @@
<string name="lui_skip">跳过</string>
<string name="lui_download">下载 eSIM</string>
<string name="telephony_manager">TelephonyManager (特权)</string>
<string name="pref_developer_telephony_manager_removable">全局使用 TelephonyManager</string>
<string name="pref_developer_telephony_manager_removable_desc">在默认情况下,可移除 eUICC 将仅使用 OMAPI。这与非特权模式 (EasyEUICC) 一致。在某些设备上 OMAPI 可能存在问题 -- 选择此选项以强制使用 TelephonyManager。</string>
</resources>

View file

@ -17,4 +17,6 @@
<string name="lui_skip">跳過</string>
<string name="lui_download">下載 eSIM</string>
<string name="telephony_manager">TelephonyManager (特權)</string>
<string name="pref_developer_telephony_manager_removable">全域使用 TelephonyManager</string>
<string name="pref_developer_telephony_manager_removable_desc">在預設情況下,可移除 eUICC 將僅使用 OMAPI。這與非特權模式 (EasyEUICC) 一致。在某些裝置上 OMAPI 可能有問題 -- 選擇此選項以強制使用 TelephonyManager。</string>
</resources>

View file

@ -22,4 +22,8 @@
<string name="lui_desc">Your device supports eSIMs. To connect to mobile network, download your eSIM issued by a carrier, or insert a physical SIM.</string>
<string name="lui_skip">Skip</string>
<string name="lui_download">Download eSIM</string>
<!-- Preference -->
<string name="pref_developer_telephony_manager_removable">Use TelephonyManager everywhere</string>
<string name="pref_developer_telephony_manager_removable_desc">By default, only OMAPI is attempted for removable eUICCs to match what is done in unprivileged mode (i.e. EasyEUICC). This may not work well on some devices. Select this option to force the use of TelephonyManager even for removable eUICCs.</string>
</resources>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory
app:isPreferenceVisible="false"
app:key="pref_developer_overlay">
<CheckBoxPreference
app:iconSpaceReserved="false"
app:key="pref_developer_tmapi_removable"
app:summary="@string/pref_developer_telephony_manager_removable_desc"
app:title="@string/pref_developer_telephony_manager_removable" />
</PreferenceCategory>
</PreferenceScreen>