Compare commits

...

2 commits

10 changed files with 106 additions and 0 deletions

View file

@ -6,6 +6,8 @@ A fully free and open-source Local Profile Assistant implementation for Android
There are two variants of this project: There are two variants of this project:
- OpenEUICC: The full-fledged privileged variant. Intended to be run as a privileged system app (inside `/system/priv-app`) and serve as the system LPA. This can be used to manage all kinds of eSIM chips, embedded or removable. - OpenEUICC: The full-fledged privileged variant. Intended to be run as a privileged system app (inside `/system/priv-app`) and serve as the system LPA. This can be used to manage all kinds of eSIM chips, embedded or removable.
- The privileged variant can be imported to build along with AOSP by simply placing this repository and its [dependencies](https://gitea.angry.im/PeterCxy/android_prebuilts_openeuicc-deps) inside the AOSP tree.
- Note that **only the latest AOSP release** is supported. Older versions are still compatible with the app itself, but it may not compile within the old AOSP trees. For older versions, consider building the app with `gradle` or a newer AOSP source tree and simply import as a prebuilt apk.
- EasyEUICC: Unprivileged version that can run as a user app. An eSIM chip must include the certificate of EasyEUICC in its ARA-M field in order to grant access without system privileges. This is intended for removable eSIM chips such as those provided by eSTK. - EasyEUICC: Unprivileged version that can run as a user app. An eSIM chip must include the certificate of EasyEUICC in its ARA-M field in order to grant access without system privileges. This is intended for removable eSIM chips such as those provided by eSTK.
- Prebuilt EasyEUICC apks can be downloaded [here](https://gitea.angry.im/PeterCxy/OpenEUICC/releases) - Prebuilt EasyEUICC apks can be downloaded [here](https://gitea.angry.im/PeterCxy/OpenEUICC/releases)
- For removable eSIM chip vendors: to have your chip supported by official builds of EasyEUICC, include the ARA-M hash `2A2FA878BC7C3354C2CF82935A5945A3EDAE4AFA` - For removable eSIM chip vendors: to have your chip supported by official builds of EasyEUICC, include the ARA-M hash `2A2FA878BC7C3354C2CF82935A5945A3EDAE4AFA`

View file

@ -35,6 +35,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.10.0' implementation 'com.google.android.material:material:1.10.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.preference:preference-ktx:1.2.1"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.cardview:cardview:1.0.0"

View file

@ -8,6 +8,10 @@
<application <application
android:networkSecurityConfig="@xml/network_security_config"> android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name="im.angry.openeuicc.ui.SettingsActivity"
android:label="@string/pref_settings" />
<activity <activity
android:name="com.journeyapps.barcodescanner.CaptureActivity" android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="fullSensor" android:screenOrientation="fullSensor"

View file

@ -1,9 +1,11 @@
package im.angry.openeuicc.ui package im.angry.openeuicc.ui
import android.content.Intent
import android.os.Bundle 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
@ -73,6 +75,16 @@ open class MainActivity : AppCompatActivity() {
return true return true
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean =
when (item.itemId) {
R.id.settings -> {
startActivity(Intent(this, SettingsActivity::class.java));
true
}
else -> super.onOptionsItemSelected(item)
}
protected open fun createEuiccManagementFragment(channel: EuiccChannel): EuiccManagementFragment = protected open fun createEuiccManagementFragment(channel: EuiccChannel): EuiccManagementFragment =
EuiccManagementFragment.newInstance(channel.slotId, channel.portId) EuiccManagementFragment.newInstance(channel.slotId, channel.portId)

View file

@ -0,0 +1,24 @@
package im.angry.openeuicc.ui
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
class SettingsActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportFragmentManager.beginTransaction()
.replace(android.R.id.content, SettingsFragment())
.commit()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean =
when (item.itemId) {
android.R.id.home -> {
finish()
true
}
else -> super.onOptionsItemSelected(item)
}
}

View file

@ -0,0 +1,24 @@
package im.angry.openeuicc.ui
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
class SettingsFragment: PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.pref_settings, rootKey)
findPreference<Preference>("pref_info_app_version")
?.summary = requireContext().selfAppVersion
findPreference<Preference>("pref_info_source_code")
?.setOnPreferenceClickListener {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(it.summary.toString())))
true
}
}
}

View file

@ -0,0 +1,14 @@
package im.angry.openeuicc.util
import android.content.Context
import android.content.pm.PackageManager
import java.lang.RuntimeException
val Context.selfAppVersion: String
get() =
try {
val pInfo = packageManager.getPackageInfo(packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
throw RuntimeException(e)
}

View file

@ -7,4 +7,9 @@
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/settings"
android:title="@string/pref_settings"
app:showAsAction="never" />
</menu> </menu>

View file

@ -32,4 +32,10 @@
<string name="profile_rename_new_name">New nickname</string> <string name="profile_rename_new_name">New nickname</string>
<string name="profile_delete_confirm">Are you sure you want to delete the profile %s? This operation is irreversible.</string> <string name="profile_delete_confirm">Are you sure you want to delete the profile %s? This operation is irreversible.</string>
<string name="pref_settings">Settings</string>
<string name="pref_info">Info</string>
<string name="pref_info_app_version">App Version</string>
<string name="pref_info_source_code">Source Code</string>
<string name="pref_info_source_code_url" translatable="false">https://gitea.angry.im/PeterCxy/OpenEUICC</string>
</resources> </resources>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory
app:title="@string/pref_info">
<Preference
app:title="@string/pref_info_app_version"
app:key="pref_info_app_version" />
<Preference
app:title="@string/pref_info_source_code"
app:summary="@string/pref_info_source_code_url"
app:key="pref_info_source_code"/>
</PreferenceCategory>
</PreferenceScreen>