diff --git a/app-unpriv/src/main/AndroidManifest.xml b/app-unpriv/src/main/AndroidManifest.xml
index e72b112..cb1ef5f 100644
--- a/app-unpriv/src/main/AndroidManifest.xml
+++ b/app-unpriv/src/main/AndroidManifest.xml
@@ -22,9 +22,12 @@
+ android:exported="false"
+ android:label="@string/compatibility_check" />
+
+
+
\ No newline at end of file
diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/di/UnprivilegedUiComponentFactory.kt b/app-unpriv/src/main/java/im/angry/openeuicc/di/UnprivilegedUiComponentFactory.kt
index f117038..2531676 100644
--- a/app-unpriv/src/main/java/im/angry/openeuicc/di/UnprivilegedUiComponentFactory.kt
+++ b/app-unpriv/src/main/java/im/angry/openeuicc/di/UnprivilegedUiComponentFactory.kt
@@ -1,9 +1,15 @@
package im.angry.openeuicc.di
import androidx.fragment.app.Fragment
+import im.angry.openeuicc.core.EuiccChannel
+import im.angry.openeuicc.ui.EuiccManagementFragment
+import im.angry.openeuicc.ui.UnprivilegedEuiccManagementFragment
import im.angry.openeuicc.ui.UnprivilegedNoEuiccPlaceholderFragment
class UnprivilegedUiComponentFactory : DefaultUiComponentFactory() {
+ override fun createEuiccManagementFragment(channel: EuiccChannel): EuiccManagementFragment =
+ UnprivilegedEuiccManagementFragment.newInstance(channel.slotId, channel.portId)
+
override fun createNoEuiccPlaceholderFragment(): Fragment =
UnprivilegedNoEuiccPlaceholderFragment()
}
\ No newline at end of file
diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedEuiccManagementFragment.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedEuiccManagementFragment.kt
new file mode 100644
index 0000000..91c4804
--- /dev/null
+++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedEuiccManagementFragment.kt
@@ -0,0 +1,40 @@
+package im.angry.openeuicc.ui
+
+import android.util.Log
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import im.angry.easyeuicc.R
+import im.angry.openeuicc.util.SIMToolkit
+import im.angry.openeuicc.util.isUsb
+import im.angry.openeuicc.util.newInstanceEuicc
+import im.angry.openeuicc.util.slotId
+
+
+class UnprivilegedEuiccManagementFragment : EuiccManagementFragment() {
+ companion object {
+ const val TAG = "UnprivilegedEuiccManagementFragment"
+
+ fun newInstance(slotId: Int, portId: Int): EuiccManagementFragment =
+ newInstanceEuicc(UnprivilegedEuiccManagementFragment::class.java, slotId, portId)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ inflater.inflate(R.menu.fragment_sim_toolkit, menu)
+ menu.findItem(R.id.open_sim_toolkit).isVisible =
+ SIMToolkit.getComponentName(requireContext(), slotId) != null
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean =
+ when (item.itemId) {
+ R.id.open_sim_toolkit -> {
+ val intent = SIMToolkit.intent(requireContext(), slotId)
+ Log.d(TAG, "Opening SIM Toolkit for $slotId slot, intent: $intent")
+ startActivity(intent)
+ true
+ }
+
+ else -> super.onOptionsItemSelected(item)
+ }
+}
\ No newline at end of file
diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/util/SIMToolkit.kt b/app-unpriv/src/main/java/im/angry/openeuicc/util/SIMToolkit.kt
new file mode 100644
index 0000000..b6aed0f
--- /dev/null
+++ b/app-unpriv/src/main/java/im/angry/openeuicc/util/SIMToolkit.kt
@@ -0,0 +1,38 @@
+package im.angry.openeuicc.util
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager.NameNotFoundException
+
+object SIMToolkit {
+ private val slot1activities = arrayOf(
+ ComponentName("com.android.stk", "com.android.stk.StkMain1"),
+ )
+
+ private val slot2activities = arrayOf(
+ ComponentName("com.android.stk", "com.android.stk.StkMain2"),
+ )
+
+ fun getComponentName(context: Context, slotId: Int): ComponentName? {
+ val components = when (slotId) {
+ 0 -> slot1activities
+ 1 -> slot2activities
+ else -> return null
+ }
+ return components.find {
+ try {
+ context.packageManager.getActivityIcon(it)
+ true
+ } catch (_: NameNotFoundException) {
+ false
+ }
+ }
+ }
+
+ fun intent(context: Context, slotId: Int) = Intent(Intent.ACTION_MAIN, null).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ component = getComponentName(context, slotId)
+ addCategory(Intent.CATEGORY_LAUNCHER)
+ }
+}
diff --git a/app-unpriv/src/main/res/menu/fragment_sim_toolkit.xml b/app-unpriv/src/main/res/menu/fragment_sim_toolkit.xml
new file mode 100644
index 0000000..610b3a1
--- /dev/null
+++ b/app-unpriv/src/main/res/menu/fragment_sim_toolkit.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app-unpriv/src/main/res/values/strings.xml b/app-unpriv/src/main/res/values/strings.xml
index 124bedf..5abc4bf 100644
--- a/app-unpriv/src/main/res/values/strings.xml
+++ b/app-unpriv/src/main/res/values/strings.xml
@@ -2,6 +2,7 @@
EasyEUICC
SIM %d
Compatibility Check
+ Open SIM Toolkit
System Features