From 0208cabfa28f2c68c518b13e7497b64fef76b31e Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Fri, 12 Jan 2024 20:38:37 -0500 Subject: [PATCH 001/511] lpac-jni: Make build more reproducible When REPRODICBLE_BUILD is set to true, disable multi-threaded compilation. --- libs/lpac-jni/build.gradle.kts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts index 62e576ab3..cbe6f1617 100644 --- a/libs/lpac-jni/build.gradle.kts +++ b/libs/lpac-jni/build.gradle.kts @@ -13,8 +13,10 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { - ndkBuild { - arguments("-j4") + if (System.getenv("REPRODUCIBLE_BUILD") != "true") { + ndkBuild { + arguments("-j4") + } } } } From 6d4d4f904190def8358fde78a4b8cc7f945c9bca Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Fri, 12 Jan 2024 20:47:00 -0500 Subject: [PATCH 002/511] lpac-jni: Hard-code a single NDK version --- libs/lpac-jni/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts index cbe6f1617..b3bef0447 100644 --- a/libs/lpac-jni/build.gradle.kts +++ b/libs/lpac-jni/build.gradle.kts @@ -6,6 +6,7 @@ plugins { android { namespace = "net.typeblog.lpac_jni" compileSdk = 33 + ndkVersion = "26.1.10909125" defaultConfig { minSdk = 27 From a923b0995c6ea9c05e5b43a62baaa758611a73c2 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Fri, 12 Jan 2024 21:01:28 -0500 Subject: [PATCH 003/511] lpac-jni: Remap __FILE__ macro usage for reproducibility --- libs/lpac-jni/src/main/jni/Application.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/lpac-jni/src/main/jni/Application.mk b/libs/lpac-jni/src/main/jni/Application.mk index f3411c99d..c949a9bb2 100644 --- a/libs/lpac-jni/src/main/jni/Application.mk +++ b/libs/lpac-jni/src/main/jni/Application.mk @@ -1,2 +1,3 @@ APP_ABI := all -APP_SHORT_COMMANDS := true \ No newline at end of file +APP_SHORT_COMMANDS := true +APP_CLFAGS := -fmacro-prefix-map="$(call my-dir)"=/fake/prefix/ \ No newline at end of file From 17ff506d88dd4eeceff699a4b1a82abb79f4110b Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Fri, 12 Jan 2024 21:06:50 -0500 Subject: [PATCH 004/511] lpac-jni: Reimplement deterministic __FILE__ prefix using gradle --- libs/lpac-jni/build.gradle.kts | 7 +++++-- libs/lpac-jni/src/main/jni/Application.mk | 3 +-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts index b3bef0447..313bf5bf3 100644 --- a/libs/lpac-jni/build.gradle.kts +++ b/libs/lpac-jni/build.gradle.kts @@ -14,9 +14,12 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { - if (System.getenv("REPRODUCIBLE_BUILD") != "true") { - ndkBuild { + ndkBuild { + if (System.getenv("REPRODUCIBLE_BUILD") != "true") { arguments("-j4") + } else { + arguments("-j1") + cFlags("-fmacro-prefix-map=${project.projectDir.toString()}=/fake/path/") } } } diff --git a/libs/lpac-jni/src/main/jni/Application.mk b/libs/lpac-jni/src/main/jni/Application.mk index c949a9bb2..f3411c99d 100644 --- a/libs/lpac-jni/src/main/jni/Application.mk +++ b/libs/lpac-jni/src/main/jni/Application.mk @@ -1,3 +1,2 @@ APP_ABI := all -APP_SHORT_COMMANDS := true -APP_CLFAGS := -fmacro-prefix-map="$(call my-dir)"=/fake/prefix/ \ No newline at end of file +APP_SHORT_COMMANDS := true \ No newline at end of file From 58227b0b79c122421544e4a60dc9a10fd75efe0b Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Fri, 12 Jan 2024 21:23:45 -0500 Subject: [PATCH 005/511] lpac-jni: Try to disable build-ids for NDK libraries --- libs/lpac-jni/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts index 313bf5bf3..dbe0ff36e 100644 --- a/libs/lpac-jni/build.gradle.kts +++ b/libs/lpac-jni/build.gradle.kts @@ -19,7 +19,7 @@ android { arguments("-j4") } else { arguments("-j1") - cFlags("-fmacro-prefix-map=${project.projectDir.toString()}=/fake/path/") + cFlags("-fmacro-prefix-map=${project.projectDir.toString()}=/fake/path/ -Wl,--build-id=none") } } } From 5eda8c63bb2bffd6747aa1cd2dbd49e4dd3c86bc Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Fri, 12 Jan 2024 21:29:35 -0500 Subject: [PATCH 006/511] lpac-jni: Use APP_LDFLAGS instead of cFlags in build.gradle --- libs/lpac-jni/build.gradle.kts | 2 +- libs/lpac-jni/src/main/jni/Application.mk | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts index dbe0ff36e..313bf5bf3 100644 --- a/libs/lpac-jni/build.gradle.kts +++ b/libs/lpac-jni/build.gradle.kts @@ -19,7 +19,7 @@ android { arguments("-j4") } else { arguments("-j1") - cFlags("-fmacro-prefix-map=${project.projectDir.toString()}=/fake/path/ -Wl,--build-id=none") + cFlags("-fmacro-prefix-map=${project.projectDir.toString()}=/fake/path/") } } } diff --git a/libs/lpac-jni/src/main/jni/Application.mk b/libs/lpac-jni/src/main/jni/Application.mk index f3411c99d..d945630e8 100644 --- a/libs/lpac-jni/src/main/jni/Application.mk +++ b/libs/lpac-jni/src/main/jni/Application.mk @@ -1,2 +1,3 @@ APP_ABI := all -APP_SHORT_COMMANDS := true \ No newline at end of file +APP_SHORT_COMMANDS := true +APP_LDFLAGS := -Wl,--build-id=none \ No newline at end of file From 2a6002d053770176caecbd1f133e936588bf7000 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 20 Jan 2024 11:16:01 -0500 Subject: [PATCH 007/511] EuiccManagementFragment: hide the "disable" option for removable eSIMs --- .../openeuicc/ui/EuiccManagementFragment.kt | 22 +++++++++---------- .../java/im/angry/openeuicc/util/Utils.kt | 6 ++++- .../src/main/res/menu/profile_options.xml | 1 + .../ui/PrivilegedEuiccManagementFragment.kt | 14 ++++++++++++ 4 files changed, 30 insertions(+), 13 deletions(-) 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 d6ffa32bf..2d0b67dd5 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 @@ -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() } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt b/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt index e5a7d2e78..6e6f16296 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt @@ -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) - } \ No newline at end of file + } + +val LocalProfileInfo.isEnabled: Boolean + get() = state == LocalProfileInfo.State.Enabled \ No newline at end of file diff --git a/app-common/src/main/res/menu/profile_options.xml b/app-common/src/main/res/menu/profile_options.xml index 4c9bede9d..6add53d5f 100644 --- a/app-common/src/main/res/menu/profile_options.xml +++ b/app-common/src/main/res/menu/profile_options.xml @@ -6,6 +6,7 @@ Date: Sat, 20 Jan 2024 11:20:56 -0500 Subject: [PATCH 008/511] PrivilegedTelephonyUtils: do not disable profiles on external eUICCs --- .../openeuicc/util/PrivilegedTelephonyUtils.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt index a544804be..4675ab9c9 100644 --- a/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt +++ b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt @@ -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 + } } } From 0b66a64fdbc529d5a153734763c98331fa7e38e8 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 20 Jan 2024 12:59:34 -0500 Subject: [PATCH 009/511] app-unpriv: Downgrade minSDK to 28 (P) This is probably the lowest version we can reasonably support with OMAPI. --- app-common/build.gradle.kts | 2 +- .../openeuicc/core/EuiccChannelManager.kt | 2 +- .../openeuicc/core/OmapiApduInterface.kt | 4 ++-- .../angry/openeuicc/util/TelephonyCompat.kt | 20 +++++++++++++++++++ app-unpriv/build.gradle.kts | 2 +- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app-common/build.gradle.kts b/app-common/build.gradle.kts index 4e3660d42..7587a0aef 100644 --- a/app-common/build.gradle.kts +++ b/app-common/build.gradle.kts @@ -8,7 +8,7 @@ android { compileSdk = 34 defaultConfig { - minSdk = 30 + minSdk = 28 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt index 94ba71c92..1c58c8ea8 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt @@ -35,7 +35,7 @@ open class EuiccChannelManager(protected val context: Context) { private val handler = Handler(HandlerThread("BaseEuiccChannelManager").also { it.start() }.looper) protected open val uiccCards: Collection - get() = (0.. handler.post { diff --git a/app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt b/app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt index fb5a2640f..1349f3c8a 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt @@ -3,7 +3,7 @@ package im.angry.openeuicc.core import android.se.omapi.Channel import android.se.omapi.SEService import android.se.omapi.Session -import im.angry.openeuicc.util.UiccPortInfoCompat +import im.angry.openeuicc.util.* import net.typeblog.lpac_jni.ApduInterface import net.typeblog.lpac_jni.LocalProfileAssistant import net.typeblog.lpac_jni.impl.HttpInterfaceImpl @@ -17,7 +17,7 @@ class OmapiApduInterface( private lateinit var lastChannel: Channel override fun connect() { - session = service.getUiccReader(port.logicalSlotIndex + 1).openSession() + session = service.getUiccReaderCompat(port.logicalSlotIndex + 1).openSession() } override fun disconnect() { diff --git a/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt index f01bd6f3c..614efdfa4 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyCompat.kt @@ -1,5 +1,25 @@ package im.angry.openeuicc.util +import android.os.Build +import android.se.omapi.Reader +import android.se.omapi.SEService +import android.telephony.TelephonyManager + +val TelephonyManager.activeModemCountCompat: Int + get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + activeModemCount + } else { + phoneCount + } + +fun SEService.getUiccReaderCompat(slotNumber: Int): Reader { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + return getUiccReader(slotNumber) + } else { + return readers.first { it.name == "SIM${slotNumber}" || (slotNumber == 1 && it.name == "SIM") } + } +} + /* * In the privileged version, the EuiccChannelManager should work * based on real Uicc{Card,Port}Info reported by TelephonyManager. diff --git a/app-unpriv/build.gradle.kts b/app-unpriv/build.gradle.kts index 776590d5e..7f49bb654 100644 --- a/app-unpriv/build.gradle.kts +++ b/app-unpriv/build.gradle.kts @@ -21,7 +21,7 @@ android { defaultConfig { applicationId = "im.angry.easyeuicc" - minSdk = 30 + minSdk = 28 targetSdk = 34 } From 70c29c195b5638a97d9c122d6e0d901a149f0411 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 20 Jan 2024 15:28:27 -0500 Subject: [PATCH 010/511] convert settings.gradle to kts --- .idea/deploymentTargetDropDown.xml | 17 +++++++++++++++++ settings.gradle => settings.gradle.kts | 12 ++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml rename settings.gradle => settings.gradle.kts (66%) diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 000000000..159f0187b --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle.kts similarity index 66% rename from settings.gradle rename to settings.gradle.kts index a1647d1c4..324247d99 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -13,9 +13,9 @@ dependencyResolutionManagement { } } rootProject.name = "OpenEUICC" -include ':app' -include ':libs:hidden-apis-stub' -include ':libs:hidden-apis-shim' -include ':libs:lpac-jni' -include ':app-common' -include ':app-unpriv' +include(":app") +include(":libs:hidden-apis-stub") +include(":libs:hidden-apis-shim") +include(":libs:lpac-jni") +include(":app-common") +include(":app-unpriv") From b580193624ea1c836b5e8c7642da23d11028c7d7 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 20 Jan 2024 16:36:23 -0500 Subject: [PATCH 011/511] Generate Android.bp and dependencies with LineageOS's GenerateBp plugin ...extract all common dependencies to a new module, app-deps, and then run LineageOS's GenerateBp plugin based on that. The resulting Android.bp file is a java_defaults that can be used from the main Android.bp. Note that the prebuilt binaries are placed in app-deps/libs by GenerateBp. This directory is explicitly excluded by .gitignore. These binaries should be copied to another repository (android_prebuilts_openeuicc-deps) manually. --- .gitignore | 3 +- .idea/compiler.xml | 1 + .idea/gradle.xml | 1 + app-common/build.gradle.kts | 14 +--- app-deps/.gitignore | 1 + app-deps/Android.bp | 16 +++++ app-deps/build.gradle.kts | 70 +++++++++++++++++++ app-deps/consumer-rules.pro | 0 app-deps/proguard-rules.pro | 21 ++++++ .../openeuicc_deps/ExampleInstrumentedTest.kt | 24 +++++++ app-deps/src/main/AndroidManifest.xml | 4 ++ .../angry/openeuicc_deps/ExampleUnitTest.kt | 17 +++++ app-unpriv/build.gradle.kts | 3 - app/build.gradle.kts | 7 +- settings.gradle.kts | 12 ++++ 15 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 app-deps/.gitignore create mode 100644 app-deps/Android.bp create mode 100644 app-deps/build.gradle.kts create mode 100644 app-deps/consumer-rules.pro create mode 100644 app-deps/proguard-rules.pro create mode 100644 app-deps/src/androidTest/java/im/angry/openeuicc_deps/ExampleInstrumentedTest.kt create mode 100644 app-deps/src/main/AndroidManifest.xml create mode 100644 app-deps/src/test/java/im/angry/openeuicc_deps/ExampleUnitTest.kt diff --git a/.gitignore b/.gitignore index f19884d61..b4a728f28 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ .cxx local.properties /libs/**/build -/buildSrc/build \ No newline at end of file +/buildSrc/build +/app-deps/libs \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 82920a5b3..61f4db454 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -4,6 +4,7 @@ + diff --git a/.idea/gradle.xml b/.idea/gradle.xml index cb7a67737..163d6b486 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -14,6 +14,7 @@