Compare commits

...

7 commits

Author SHA1 Message Date
ee40a5ec57
chore: add preference item 2025-08-11 10:26:02 +08:00
cbf9d3ea41
feat: global es10x mss settings 2025-08-11 10:26:02 +08:00
4c4fa058ae
feat: es10x mss as preference 2025-08-11 10:26:02 +08:00
a8b7482afb feat: version name suffix (#215)
All checks were successful
/ build-debug (push) Successful in 5m32s
see https://developer.android.com/build/build-variants

Reviewed-on: #215
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
2025-08-10 22:08:31 +02:00
3fed4b2bd6 fix: aid list (#217)
Some checks failed
/ build-debug (push) Has been cancelled
Reviewed-on: #217
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
2025-08-10 22:07:25 +02:00
deb0a372b1 feat: allow copy app version and source code url (#216)
Some checks failed
/ build-debug (push) Has been cancelled
Reviewed-on: #216
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
2025-08-10 22:07:10 +02:00
72ec20f824 feat: 16k page sizes (#211)
Some checks failed
/ build-debug (push) Has been cancelled
see https://developer.android.com/guide/practices/page-sizes

Reviewed-on: #211
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
2025-08-10 22:03:25 +02:00
11 changed files with 67 additions and 15 deletions

View file

@ -35,8 +35,8 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
DefaultEuiccChannelManager.TAG, DefaultEuiccChannelManager.TAG,
"Trying OMAPI for physical slot ${port.card.physicalSlotIndex}" "Trying OMAPI for physical slot ${port.card.physicalSlotIndex}"
) )
try { return try {
return EuiccChannelImpl( EuiccChannelImpl(
context.getString(R.string.channel_type_omapi), context.getString(R.string.channel_type_omapi),
port, port,
intrinsicChannelName = null, intrinsicChannelName = null,
@ -48,19 +48,15 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
isdrAid, isdrAid,
context.preferenceRepository.verboseLoggingFlow, context.preferenceRepository.verboseLoggingFlow,
context.preferenceRepository.ignoreTLSCertificateFlow, context.preferenceRepository.ignoreTLSCertificateFlow,
).also { )
Log.i(DefaultEuiccChannelManager.TAG, "Is OMAPI channel, setting MSS to 60")
it.lpa.setEs10xMss(60)
}
} catch (_: IllegalArgumentException) { } catch (_: IllegalArgumentException) {
// Failed // Failed
Log.w( Log.w(
DefaultEuiccChannelManager.TAG, DefaultEuiccChannelManager.TAG,
"OMAPI APDU interface unavailable for physical slot ${port.card.physicalSlotIndex} with ISD-R AID: ${isdrAid.encodeHex()}." "OMAPI APDU interface unavailable for physical slot ${port.card.physicalSlotIndex} with ISD-R AID: ${isdrAid.encodeHex()}."
) )
null
} }
return null
} }
override fun tryOpenUsbEuiccChannel( override fun tryOpenUsbEuiccChannel(

View file

@ -99,6 +99,12 @@ open class DefaultEuiccChannelManager(
val channel = val channel =
tryOpenChannelFirstValidAid { euiccChannelFactory.tryOpenEuiccChannel(port, it) } tryOpenChannelFirstValidAid { euiccChannelFactory.tryOpenEuiccChannel(port, it) }
if (channel != null) {
val mss = context.preferenceRepository.es10xMssFlow.first()
Log.i(TAG, "Set ${channel.type} channel, ES10x MSS to $mss")
channel.lpa.setEs10xMss(mss.toByte())
}
if (channel != null) { if (channel != null) {
channelCache.add(channel) channelCache.add(channel)
return channel return channel

View file

@ -8,6 +8,7 @@ import android.provider.Settings
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.CheckBoxPreference import androidx.preference.CheckBoxPreference
import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
@ -16,7 +17,6 @@ import im.angry.openeuicc.util.*
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
open class SettingsFragment: PreferenceFragmentCompat() { open class SettingsFragment: PreferenceFragmentCompat() {
private lateinit var developerPref: PreferenceCategory private lateinit var developerPref: PreferenceCategory
@ -84,6 +84,9 @@ open class SettingsFragment: PreferenceFragmentCompat() {
requirePreference<CheckBoxPreference>("pref_developer_euicc_memory_reset") requirePreference<CheckBoxPreference>("pref_developer_euicc_memory_reset")
.bindBooleanFlow(preferenceRepository.euiccMemoryResetFlow) .bindBooleanFlow(preferenceRepository.euiccMemoryResetFlow)
requirePreference<ListPreference>("pref_developer_es10x_mss")
.bindIntFlow(preferenceRepository.es10xMssFlow, 63)
requirePreference<Preference>("pref_developer_isdr_aid_list").apply { requirePreference<Preference>("pref_developer_isdr_aid_list").apply {
intent = Intent(requireContext(), IsdrAidListActivity::class.java) intent = Intent(requireContext(), IsdrAidListActivity::class.java)
} }
@ -138,13 +141,26 @@ open class SettingsFragment: PreferenceFragmentCompat() {
} }
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
runBlocking { lifecycleScope.launch {
flow.updatePreference(newValue as Boolean) flow.updatePreference(newValue as Boolean)
} }
true true
} }
} }
private fun ListPreference.bindIntFlow(flow: PreferenceFlowWrapper<Int>, defaultValue: Int) {
lifecycleScope.launch {
flow.collect { value = it.toString() }
}
setOnPreferenceChangeListener { _, newValue ->
lifecycleScope.launch {
flow.updatePreference((newValue as String).toIntOrNull() ?: defaultValue)
}
true
}
}
protected fun mergePreferenceOverlay(overlayKey: String, targetKey: String) { protected fun mergePreferenceOverlay(overlayKey: String, targetKey: String) {
val overlayCat = requirePreference<PreferenceCategory>(overlayKey) val overlayCat = requirePreference<PreferenceCategory>(overlayKey)
val targetCat = requirePreference<PreferenceCategory>(targetKey) val targetCat = requirePreference<PreferenceCategory>(targetKey)

View file

@ -5,6 +5,7 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore import androidx.datastore.preferences.preferencesDataStore
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@ -38,6 +39,7 @@ internal object PreferenceKeys {
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate") val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
val EUICC_MEMORY_RESET = booleanPreferencesKey("euicc_memory_reset") val EUICC_MEMORY_RESET = booleanPreferencesKey("euicc_memory_reset")
val ISDR_AID_LIST = stringPreferencesKey("isdr_aid_list") val ISDR_AID_LIST = stringPreferencesKey("isdr_aid_list")
val ES10X_MSS = intPreferencesKey("es10x_mss")
} }
const val EUICC_DEFAULT_ISDR_AID = "A0000005591010FFFFFFFF8900000100" const val EUICC_DEFAULT_ISDR_AID = "A0000005591010FFFFFFFF8900000100"
@ -50,9 +52,12 @@ internal object PreferenceConstants {
# eUICC standard # eUICC standard
$EUICC_DEFAULT_ISDR_AID $EUICC_DEFAULT_ISDR_AID
# eSTK.me # ESTKme AUX (deprecated, use SE0 instead)
A06573746B6D65FFFFFFFF4953442D52 A06573746B6D65FFFFFFFF4953442D52
# ESTKme SE0
A06573746B6D65FFFF4953442D522030
# eSIM.me # eSIM.me
A0000005591010000000008900000300 A0000005591010000000008900000300
@ -86,6 +91,7 @@ open class PreferenceRepository(private val context: Context) {
PreferenceConstants.DEFAULT_AID_LIST, PreferenceConstants.DEFAULT_AID_LIST,
{ Base64.getEncoder().encodeToString(it.encodeToByteArray()) }, { Base64.getEncoder().encodeToString(it.encodeToByteArray()) },
{ Base64.getDecoder().decode(it).decodeToString() }) { Base64.getDecoder().decode(it).decodeToString() })
val es10xMssFlow = bindFlow(PreferenceKeys.ES10X_MSS, 63)
protected fun <T> bindFlow( protected fun <T> bindFlow(
key: Preferences.Key<T>, key: Preferences.Key<T>,

View file

@ -200,6 +200,16 @@
<string name="pref_developer_ignore_tls_certificate_desc">Accept any TLS certificate used by the RSP server</string> <string name="pref_developer_ignore_tls_certificate_desc">Accept any TLS certificate used by the RSP server</string>
<string name="pref_developer_euicc_memory_reset">Allow erasing eUICC</string> <string name="pref_developer_euicc_memory_reset">Allow erasing eUICC</string>
<string name="pref_developer_euicc_memory_reset_desc">This is a dangerous operation and hidden by default. As an alternative, you can delete all profiles manually.</string> <string name="pref_developer_euicc_memory_reset_desc">This is a dangerous operation and hidden by default. As an alternative, you can delete all profiles manually.</string>
<string name="pref_developer_es10x_mss">ES10x MSS</string>
<string name="pref_developer_es10x_mss_desc">Global ES10x MSS</string>
<string-array name="pref_developer_es10x_entry_keys">
<item>High Speed</item>
<item>Compatibility Mode</item>
</string-array>
<string-array name="pref_developer_es10x_entry_values" translatable="false">
<item>255</item>
<item>63</item>
</string-array>
<string name="pref_developer_isdr_aid_list">Customize ISD-R AID list</string> <string name="pref_developer_isdr_aid_list">Customize ISD-R AID list</string>
<string name="pref_developer_isdr_aid_list_desc">Some brands of removable eUICCs may use their own non-standard ISD-R AID, rendering them inaccessible to third-party apps. We can attempt to use non-standard AIDs added in this list, but there is no guarantee that they will work.</string> <string name="pref_developer_isdr_aid_list_desc">Some brands of removable eUICCs may use their own non-standard ISD-R AID, rendering them inaccessible to third-party apps. We can attempt to use non-standard AIDs added in this list, but there is no guarantee that they will work.</string>
<string name="pref_info">Info</string> <string name="pref_info">Info</string>

View file

@ -81,6 +81,14 @@
app:summary="@string/pref_developer_euicc_memory_reset_desc" app:summary="@string/pref_developer_euicc_memory_reset_desc"
app:title="@string/pref_developer_euicc_memory_reset" /> app:title="@string/pref_developer_euicc_memory_reset" />
<ListPreference
app:iconSpaceReserved="false"
app:key="pref_developer_es10x_mss"
app:summary="@string/pref_developer_es10x_mss_desc"
app:title="@string/pref_developer_es10x_mss"
app:entries="@array/pref_developer_es10x_entry_keys"
app:entryValues="@array/pref_developer_es10x_entry_values" />
<Preference <Preference
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:key="pref_developer_isdr_aid_list" app:key="pref_developer_isdr_aid_list"
@ -96,12 +104,14 @@
<Preference <Preference
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:title="@string/pref_info_app_version" app:title="@string/pref_info_app_version"
app:enableCopying="true"
app:key="pref_info_app_version" /> app:key="pref_info_app_version" />
<Preference <Preference
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:title="@string/pref_info_source_code" app:title="@string/pref_info_source_code"
app:summary="@string/pref_info_source_code_url" app:summary="@string/pref_info_source_code_url"
app:enableCopying="true"
app:key="pref_info_source_code"> app:key="pref_info_source_code">
<intent <intent
android:action="android.intent.action.VIEW" android:action="android.intent.action.VIEW"

View file

@ -27,6 +27,9 @@ android {
} }
buildTypes { buildTypes {
defaultConfig {
versionNameSuffix = "-unpriv"
}
release { release {
isMinifyEnabled = false isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")

View file

@ -23,6 +23,9 @@ android {
} }
buildTypes { buildTypes {
defaultConfig {
versionNameSuffix = "-priv"
}
release { release {
isMinifyEnabled = false isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")

View file

@ -16,7 +16,7 @@ val Project.gitVersionCode: Int
standardOutput = stdout standardOutput = stdout
} }
stdout.toString("utf-8").trim('\n').toInt() stdout.toString("utf-8").trim('\n').toInt()
} catch (e: Exception) { } catch (_: Exception) {
0 0
} }
@ -29,7 +29,7 @@ val Project.gitVersionName: String
standardOutput = stdout standardOutput = stdout
} }
stdout.toString("utf-8").trim('\n') stdout.toString("utf-8").trim('\n')
} catch (e: Exception) { } catch (_: Exception) {
"Unknown" "Unknown"
} }
@ -38,7 +38,7 @@ class MyVersioningPlugin: Plugin<Project> {
target.configure<BaseAppModuleExtension> { target.configure<BaseAppModuleExtension> {
defaultConfig { defaultConfig {
versionCode = target.gitVersionCode versionCode = target.gitVersionCode
versionName = target.gitVersionName versionName = target.gitVersionName.removePrefix("unpriv-")
} }
applicationVariants.all { applicationVariants.all {

View file

@ -1,4 +1,5 @@
APP_ABI := all APP_ABI := all
APP_SHORT_COMMANDS := true APP_SHORT_COMMANDS := true
APP_CFLAGS := -Wno-compound-token-split-by-macro APP_CFLAGS := -Wno-compound-token-split-by-macro
APP_LDFLAGS := -Wl,--build-id=none -z muldefs APP_LDFLAGS := -Wl,--build-id=none -z muldefs
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

View file

@ -1,4 +1,5 @@
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"
# function to find all *.c files under a directory # function to find all *.c files under a directory
define all-c-files-under define all-c-files-under