diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 69fd9ef..8eb4222 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -3,11 +3,9 @@
+
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 749c0ae..61fb4b6 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -13,6 +13,7 @@
+
diff --git a/app-common/.gitignore b/app-common/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app-common/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app-common/build.gradle b/app-common/build.gradle
new file mode 100644
index 0000000..bb33349
--- /dev/null
+++ b/app-common/build.gradle
@@ -0,0 +1,47 @@
+plugins {
+ id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'im.angry.openeuicc.common'
+ compileSdk 34
+
+ defaultConfig {
+ minSdk 30
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+}
+
+dependencies {
+ compileOnly project(':libs:hidden-apis-stub')
+ implementation project(':libs:hidden-apis-shim')
+ implementation project(":libs:lpac-jni")
+ implementation 'androidx.core:core-ktx:1.12.0'
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'com.google.android.material:material:1.10.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
+ implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
+ implementation "androidx.cardview:cardview:1.0.0"
+ implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+}
\ No newline at end of file
diff --git a/app-common/consumer-rules.pro b/app-common/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/app-common/proguard-rules.pro b/app-common/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app-common/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app-common/src/androidTest/java/im/angry/openeuicc/common/ExampleInstrumentedTest.kt b/app-common/src/androidTest/java/im/angry/openeuicc/common/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..b027bbe
--- /dev/null
+++ b/app-common/src/androidTest/java/im/angry/openeuicc/common/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package im.angry.openeuicc.common
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("im.angry.openeuicc.common.test", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/app-common/src/main/AndroidManifest.xml b/app-common/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f833c4d
--- /dev/null
+++ b/app-common/src/main/AndroidManifest.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/im/angry/openeuicc/OpenEuiccApplication.kt b/app-common/src/main/java/im/angry/openeuicc/BaseOpenEuiccApplication.kt
similarity index 55%
rename from app/src/main/java/im/angry/openeuicc/OpenEuiccApplication.kt
rename to app-common/src/main/java/im/angry/openeuicc/BaseOpenEuiccApplication.kt
index 131b099..1a2fcb7 100644
--- a/app/src/main/java/im/angry/openeuicc/OpenEuiccApplication.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/BaseOpenEuiccApplication.kt
@@ -3,23 +3,16 @@ package im.angry.openeuicc
import android.app.Application
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
-import im.angry.openeuicc.core.EuiccChannelManager
+import im.angry.openeuicc.core.BaseEuiccChannelManager
-class OpenEuiccApplication : Application() {
+abstract class BaseOpenEuiccApplication : Application() {
val telephonyManager by lazy {
getSystemService(TelephonyManager::class.java)!!
}
- val euiccChannelManager by lazy {
- EuiccChannelManager(this)
- }
+ abstract val euiccChannelManager: BaseEuiccChannelManager
val subscriptionManager by lazy {
getSystemService(SubscriptionManager::class.java)!!
}
-
- override fun onCreate() {
- super.onCreate()
- euiccChannelManager.closeAllStaleChannels()
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt b/app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt
similarity index 69%
rename from app/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt
rename to app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt
index 27ff301..2b89b4c 100644
--- a/app/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt
@@ -6,21 +6,19 @@ import android.os.HandlerThread
import android.se.omapi.SEService
import android.telephony.UiccCardInfo
import android.util.Log
-import im.angry.openeuicc.OpenEuiccApplication
-import im.angry.openeuicc.util.*
+import im.angry.openeuicc.BaseOpenEuiccApplication
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
-import java.lang.Exception
import java.lang.IllegalArgumentException
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
-class EuiccChannelManager(private val context: Context) {
+abstract class BaseEuiccChannelManager(private val context: Context) {
companion object {
- const val TAG = "EuiccChannelManager"
+ const val TAG = "BaseEuiccChannelManager"
}
private val channels = mutableListOf()
@@ -29,11 +27,11 @@ class EuiccChannelManager(private val context: Context) {
private val lock = Mutex()
- private val tm by lazy {
- (context.applicationContext as OpenEuiccApplication).telephonyManager
+ protected val tm by lazy {
+ (context.applicationContext as BaseOpenEuiccApplication).telephonyManager
}
- private val handler = Handler(HandlerThread("EuiccChannelManager").also { it.start() }.looper)
+ private val handler = Handler(HandlerThread("BaseEuiccChannelManager").also { it.start() }.looper)
private suspend fun connectSEService(): SEService = suspendCoroutine { cont ->
handler.post {
@@ -50,6 +48,8 @@ class EuiccChannelManager(private val context: Context) {
}
}
+ abstract fun tryOpenEuiccChannelPrivileged(uiccInfo: UiccCardInfo, channelInfo: EuiccChannelInfo): EuiccChannel?
+
private suspend fun tryOpenEuiccChannel(uiccInfo: UiccCardInfo): EuiccChannel? {
lock.withLock {
ensureSEService()
@@ -71,17 +71,7 @@ class EuiccChannelManager(private val context: Context) {
uiccInfo.isRemovable
)
- var euiccChannel: EuiccChannel? = null
-
- if (uiccInfo.isEuicc && !uiccInfo.isRemovable) {
- Log.d(TAG, "Using TelephonyManager for slot ${uiccInfo.slotIndex}")
- // TODO: On Tiramisu, we should also connect all available "ports" for MEP support
- try {
- euiccChannel = TelephonyManagerChannel(channelInfo, tm)
- } catch (e: IllegalArgumentException) {
- // Failed
- }
- }
+ var euiccChannel: EuiccChannel? = tryOpenEuiccChannelPrivileged(uiccInfo, channelInfo)
if (euiccChannel == null) {
try {
@@ -135,19 +125,4 @@ class EuiccChannelManager(private val context: Context) {
seService?.shutdown()
seService = null
}
-
- // Clean up channels left open in TelephonyManager
- // due to a (potentially) forced restart
- // This should be called every time the application is restarted
- fun closeAllStaleChannels() {
- for (card in tm.uiccCardsInfo) {
- for (channel in 0 until 10) {
- try {
- tm.iccCloseLogicalChannelBySlot(card.slotIndex, channel)
- } catch (_: Exception) {
- // We do not care
- }
- }
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/im/angry/openeuicc/core/EuiccChannel.kt b/app-common/src/main/java/im/angry/openeuicc/core/EuiccChannel.kt
similarity index 100%
rename from app/src/main/java/im/angry/openeuicc/core/EuiccChannel.kt
rename to app-common/src/main/java/im/angry/openeuicc/core/EuiccChannel.kt
diff --git a/app/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt b/app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt
similarity index 100%
rename from app/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt
rename to app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt
diff --git a/app/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt
similarity index 85%
rename from app/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt
rename to app-common/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt
index 1201d60..2d8d687 100644
--- a/app/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt
@@ -2,8 +2,8 @@ package im.angry.openeuicc.ui
import android.os.Bundle
import androidx.fragment.app.Fragment
+import im.angry.openeuicc.core.BaseEuiccChannelManager
import im.angry.openeuicc.core.EuiccChannel
-import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.openEuiccApplication
interface EuiccFragmentMarker
@@ -19,7 +19,7 @@ fun newInstanceEuicc(clazz: Class, slotId: Int): T where T: Fragment, T:
val T.slotId: Int where T: Fragment, T: EuiccFragmentMarker
get() = requireArguments().getInt("slotId")
-val T.euiccChannelManager: EuiccChannelManager where T: Fragment, T: EuiccFragmentMarker
+val T.euiccChannelManager: BaseEuiccChannelManager where T: Fragment, T: EuiccFragmentMarker
get() = openEuiccApplication.euiccChannelManager
val T.channel: EuiccChannel where T: Fragment, T: EuiccFragmentMarker
diff --git a/app/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
similarity index 99%
rename from app/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
rename to app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
index 959588e..0b24114 100644
--- a/app/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt
@@ -19,7 +19,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import net.typeblog.lpac_jni.LocalProfileInfo
-import im.angry.openeuicc.R
+import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
diff --git a/app/src/main/java/im/angry/openeuicc/ui/MainActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt
similarity index 95%
rename from app/src/main/java/im/angry/openeuicc/ui/MainActivity.kt
rename to app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt
index 7a86790..6ea0a15 100644
--- a/app/src/main/java/im/angry/openeuicc/ui/MainActivity.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt
@@ -12,8 +12,8 @@ import android.widget.Spinner
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
-import im.angry.openeuicc.R
-import im.angry.openeuicc.core.EuiccChannelManager
+import im.angry.openeuicc.common.R
+import im.angry.openeuicc.core.BaseEuiccChannelManager
import im.angry.openeuicc.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -24,7 +24,7 @@ class MainActivity : AppCompatActivity() {
const val TAG = "MainActivity"
}
- private lateinit var manager: EuiccChannelManager
+ private lateinit var manager: BaseEuiccChannelManager
private lateinit var spinnerAdapter: ArrayAdapter
private lateinit var spinner: Spinner
diff --git a/app/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt
similarity index 98%
rename from app/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt
rename to app-common/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt
index 55a0457..92571ad 100644
--- a/app/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt
@@ -6,7 +6,7 @@ import android.util.Log
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
-import im.angry.openeuicc.R
+import im.angry.openeuicc.common.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
diff --git a/app/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt
similarity index 97%
rename from app/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt
rename to app-common/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt
index 61e4f55..18cdb0b 100644
--- a/app/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt
@@ -13,7 +13,7 @@ import androidx.lifecycle.lifecycleScope
import com.google.android.material.textfield.TextInputLayout
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
-import im.angry.openeuicc.R
+import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.setWidthPercent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -132,6 +132,8 @@ class ProfileDownloadFragment : DialogFragment(), EuiccFragmentMarker, Toolbar.O
profileDownloadServer.editText!!.isEnabled = false
profileDownloadCode.editText!!.isEnabled = false
+ profileDownloadConfirmationCode.editText!!.isEnabled = false
+ profileDownloadIMEI.editText!!.isEnabled = false
progress.isIndeterminate = true
progress.visibility = View.VISIBLE
diff --git a/app/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
similarity index 99%
rename from app/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
rename to app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
index e151498..d940036 100644
--- a/app/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt
@@ -13,7 +13,7 @@ import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.google.android.material.textfield.TextInputLayout
-import im.angry.openeuicc.R
+import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.setWidthPercent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
diff --git a/app/src/main/java/im/angry/openeuicc/util/StringUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/StringUtils.kt
similarity index 100%
rename from app/src/main/java/im/angry/openeuicc/util/StringUtils.kt
rename to app-common/src/main/java/im/angry/openeuicc/util/StringUtils.kt
diff --git a/app/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt
similarity index 100%
rename from app/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt
rename to app-common/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt
diff --git a/app/src/main/java/im/angry/openeuicc/util/UiUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt
similarity index 83%
rename from app/src/main/java/im/angry/openeuicc/util/UiUtils.kt
rename to app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt
index 477837f..b39b78f 100644
--- a/app/src/main/java/im/angry/openeuicc/util/UiUtils.kt
+++ b/app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt
@@ -6,12 +6,12 @@ import android.graphics.Rect
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
-import im.angry.openeuicc.OpenEuiccApplication
+import im.angry.openeuicc.BaseOpenEuiccApplication
-val Activity.openEuiccApplication: OpenEuiccApplication
- get() = application as OpenEuiccApplication
+val Activity.openEuiccApplication: BaseOpenEuiccApplication
+ get() = application as BaseOpenEuiccApplication
-val Fragment.openEuiccApplication: OpenEuiccApplication
+val Fragment.openEuiccApplication: BaseOpenEuiccApplication
get() = requireActivity().openEuiccApplication
// Source:
diff --git a/app/src/main/res/drawable/ic_add.xml b/app-common/src/main/res/drawable/ic_add.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_add.xml
rename to app-common/src/main/res/drawable/ic_add.xml
diff --git a/app/src/main/res/drawable/ic_check_black.xml b/app-common/src/main/res/drawable/ic_check_black.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_check_black.xml
rename to app-common/src/main/res/drawable/ic_check_black.xml
diff --git a/app/src/main/res/drawable/ic_menu_black.xml b/app-common/src/main/res/drawable/ic_menu_black.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_menu_black.xml
rename to app-common/src/main/res/drawable/ic_menu_black.xml
diff --git a/app/src/main/res/drawable/ic_scan_black.xml b/app-common/src/main/res/drawable/ic_scan_black.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_scan_black.xml
rename to app-common/src/main/res/drawable/ic_scan_black.xml
diff --git a/app/src/main/res/layout/activity_main.xml b/app-common/src/main/res/layout/activity_main.xml
similarity index 100%
rename from app/src/main/res/layout/activity_main.xml
rename to app-common/src/main/res/layout/activity_main.xml
diff --git a/app/src/main/res/layout/euicc_profile.xml b/app-common/src/main/res/layout/euicc_profile.xml
similarity index 100%
rename from app/src/main/res/layout/euicc_profile.xml
rename to app-common/src/main/res/layout/euicc_profile.xml
diff --git a/app/src/main/res/layout/fragment_euicc.xml b/app-common/src/main/res/layout/fragment_euicc.xml
similarity index 100%
rename from app/src/main/res/layout/fragment_euicc.xml
rename to app-common/src/main/res/layout/fragment_euicc.xml
diff --git a/app/src/main/res/layout/fragment_profile_download.xml b/app-common/src/main/res/layout/fragment_profile_download.xml
similarity index 100%
rename from app/src/main/res/layout/fragment_profile_download.xml
rename to app-common/src/main/res/layout/fragment_profile_download.xml
diff --git a/app/src/main/res/layout/fragment_profile_rename.xml b/app-common/src/main/res/layout/fragment_profile_rename.xml
similarity index 100%
rename from app/src/main/res/layout/fragment_profile_rename.xml
rename to app-common/src/main/res/layout/fragment_profile_rename.xml
diff --git a/app/src/main/res/layout/spinner_item.xml b/app-common/src/main/res/layout/spinner_item.xml
similarity index 100%
rename from app/src/main/res/layout/spinner_item.xml
rename to app-common/src/main/res/layout/spinner_item.xml
diff --git a/app/src/main/res/menu/activity_main.xml b/app-common/src/main/res/menu/activity_main.xml
similarity index 100%
rename from app/src/main/res/menu/activity_main.xml
rename to app-common/src/main/res/menu/activity_main.xml
diff --git a/app/src/main/res/menu/fragment_profile_download.xml b/app-common/src/main/res/menu/fragment_profile_download.xml
similarity index 100%
rename from app/src/main/res/menu/fragment_profile_download.xml
rename to app-common/src/main/res/menu/fragment_profile_download.xml
diff --git a/app/src/main/res/menu/fragment_profile_rename.xml b/app-common/src/main/res/menu/fragment_profile_rename.xml
similarity index 100%
rename from app/src/main/res/menu/fragment_profile_rename.xml
rename to app-common/src/main/res/menu/fragment_profile_rename.xml
diff --git a/app/src/main/res/menu/profile_options.xml b/app-common/src/main/res/menu/profile_options.xml
similarity index 100%
rename from app/src/main/res/menu/profile_options.xml
rename to app-common/src/main/res/menu/profile_options.xml
diff --git a/app/src/main/res/raw/symantec_gsma_rspv2_root_ci1 b/app-common/src/main/res/raw/symantec_gsma_rspv2_root_ci1
similarity index 100%
rename from app/src/main/res/raw/symantec_gsma_rspv2_root_ci1
rename to app-common/src/main/res/raw/symantec_gsma_rspv2_root_ci1
diff --git a/app/src/main/res/values/colors.xml b/app-common/src/main/res/values/colors.xml
similarity index 100%
rename from app/src/main/res/values/colors.xml
rename to app-common/src/main/res/values/colors.xml
diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml
new file mode 100644
index 0000000..38b1972
--- /dev/null
+++ b/app-common/src/main/res/values/strings.xml
@@ -0,0 +1,34 @@
+
+
+ No eUICC found on this device.\nOn some devices, you may need to enable dual SIM first in the menu of this app.
+
+ Dual SIM
+
+ Enabled
+ Disabled
+ Provider:
+ ICCID:
+
+ Enable
+ Disable
+ Delete
+ Rename
+
+ eSIM profile switched. Please wait for a while when the card is restarting.
+ Cannot switch to new eSIM profile.
+ Nickname cannot be longer than 64 characters
+ DSDS state switched. Please wait until the modem restarts.
+
+ New eSIM
+ Server (RSP / SM-DP+)
+ Activation Code
+ Confirmation Code (Optional)
+ IMEI (Optional)
+ Scan QR Code
+ Download
+ Failed to download eSIM. Check your activation / QR code.
+
+ New nickname
+
+ Are you sure you want to delete the profile %s? This operation is irreversible.
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app-common/src/main/res/values/themes.xml
similarity index 90%
rename from app/src/main/res/values/themes.xml
rename to app-common/src/main/res/values/themes.xml
index c07d0ec..8836304 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app-common/src/main/res/values/themes.xml
@@ -11,9 +11,11 @@
- @color/white
- ?attr/colorSecondary
- - ?attr/colorPrimaryVariant
+ - ?attr/colorPrimary
+ - true
- @style/AlertDialogTheme
+ - ?attr/colorSecondary