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 index 95eb8b4..22e3933 100644 --- a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedEuiccManagementFragment.kt +++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedEuiccManagementFragment.kt @@ -24,10 +24,8 @@ class UnprivilegedEuiccManagementFragment : EuiccManagementFragment() { super.onCreateOptionsMenu(menu, inflater) inflater.inflate(R.menu.fragment_sim_toolkit, menu) menu.findItem(R.id.open_sim_toolkit).apply { - val slot = stk[slotId] - if (slot == null) return@apply - isVisible = true - setOnMenuItemClickListener { slot.launch() } + isVisible = stk.isAvailable(slotId) + setOnMenuItemClickListener { stk.launch(slotId) } } } } \ 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 index ca3c0ad..fe65023 100644 --- a/app-unpriv/src/main/java/im/angry/openeuicc/util/SIMToolkit.kt +++ b/app-unpriv/src/main/java/im/angry/openeuicc/util/SIMToolkit.kt @@ -3,6 +3,7 @@ package im.angry.openeuicc.util import android.content.ComponentName import android.content.Context import android.content.Intent +import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.net.Uri import android.provider.Settings @@ -20,37 +21,36 @@ class SIMToolkit(private val context: Context) { put(1, getComponentNames(R.array.sim_toolkit_slot_2)) } - operator fun get(slotId: Int): Slot? = when (slotId) { - -1, EuiccChannelManager.USB_CHANNEL_ID -> null - else -> Slot(context, buildSet { - addAll(slots.getOrDefault(slotId, emptySet())) - addAll(slots.getOrDefault(-1, emptySet())) - }) + private val packageNames: Iterable + get() = slots.values.flatten().map { it.packageName }.toSet() + + private val activities: Iterable + get() = packageNames.flatMap(context.packageManager::getActivities) + .filter { it.exported } + .map { ComponentName(it.packageName, it.name) } + + private val launchIntent: Intent? + get() = packageNames.firstNotNullOfOrNull(context.packageManager::getLaunchIntent) + + private fun getComponentsBySlotId(slotId: Int) = buildSet { + addAll(slots.getOrDefault(slotId, emptySet())) + addAll(slots.getOrDefault(-1, emptySet())) } - data class Slot(private val context: Context, private val components: Set) { - private val packageNames: Iterable - get() = components.map { it.packageName }.toSet() - - private val launchIntent: Intent? - get() = packageNames.firstNotNullOfOrNull(context.packageManager::getLaunchIntent) - - private val activities: Iterable - get() = packageNames.flatMap(context.packageManager::getActivities) - .filter { it.exported }.map { ComponentName(it.packageName, it.name) } - - private fun getIntent(): Intent? { - try { - val component = components.find(activities::contains) ?: return launchIntent - if (isDisabledState(context.packageManager.getComponentEnabledSetting(component))) - return null - return Intent.makeMainActivity(component) - } catch (e: IllegalArgumentException) { - return null - } + private fun intentActivity(slotId: Int): Intent? { + val component = getComponentsBySlotId(slotId).find(activities::contains) + ?: return launchIntent + val disabled = try { + isDisabledState(context.packageManager.getComponentEnabledSetting(component)) + } catch (e: IllegalArgumentException) { + true } + if (disabled) return null + return Intent.makeMainActivity(component) + } - private fun getDisabledPackageName() = packageNames.find { + private fun getDisabledPackageName(slotId: Int) = + getComponentsBySlotId(slotId).map { it.packageName }.toSet().find { try { isDisabledState(context.packageManager.getApplicationEnabledSetting(it)) } catch (e: IllegalArgumentException) { @@ -58,23 +58,28 @@ class SIMToolkit(private val context: Context) { } } - fun launch(): Boolean { - var intent = getIntent() - if (intent == null) { - val pkgName = getDisabledPackageName() ?: return false - val message = context.getString( - R.string.toast_prompt_to_enable_sim_toolkit, - context.packageManager.getApplicationLabel(pkgName) - ) - intent = Intent( - Settings.ACTION_APPLICATION_DETAILS_SETTINGS, - Uri.fromParts("package", pkgName, null) - ) - Toast.makeText(context, message, Toast.LENGTH_LONG).show() - } - context.startActivity(intent) - return true + fun isAvailable(slotId: Int) = when (slotId) { + -1 -> false + EuiccChannelManager.USB_CHANNEL_ID -> false + else -> intentActivity(slotId) != null || getDisabledPackageName(slotId) != null + } + + fun launch(slotId: Int): Boolean { + var intent = intentActivity(slotId) + if (intent == null) { + val pkgName = getDisabledPackageName(slotId) ?: return false + val message = context.getString( + R.string.toast_prompt_to_enable_sim_toolkit, + context.packageManager.getApplicationLabel(pkgName) + ) + intent = Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.fromParts("package", pkgName, null) + ) + Toast.makeText(context, message, Toast.LENGTH_LONG).show() } + context.startActivity(intent) + return true } } @@ -97,5 +102,5 @@ private fun PackageManager.getActivities(packageName: String) = try { getPackageInfo(packageName, PackageManager.GET_ACTIVITIES) .activities?.toList() ?: emptyList() } catch (_: PackageManager.NameNotFoundException) { - emptyList() + emptyList() }