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 3c94c6c..42d9646 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 @@ -380,9 +380,9 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener, state.setText( if (profile.isEnabled) { - R.string.enabled + R.string.profile_state_enabled } else { - R.string.disabled + R.string.profile_state_disabled } ) provider.text = profile.providerName diff --git a/app-common/src/main/res/layout/euicc_profile.xml b/app-common/src/main/res/layout/euicc_profile.xml index 74c1d7a..021c53b 100644 --- a/app-common/src/main/res/layout/euicc_profile.xml +++ b/app-common/src/main/res/layout/euicc_profile.xml @@ -54,7 +54,7 @@ ヘルプ スロットを再読み込み 論理スロット %d - 有効済み - 無効済み - プロバイダー: + 有効済み + 無効済み + プロバイダー: クラス: テスト中 プロビジョニング diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml index 32ced90..6884bc4 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -6,9 +6,9 @@ 帮助 重新加载卡槽 逻辑卡槽 %d - 已启用 - 已禁用 - 提供商: + 已启用 + 已禁用 + 提供商: 类型: 启用 禁用 diff --git a/app-common/src/main/res/values-zh-rTW/strings.xml b/app-common/src/main/res/values-zh-rTW/strings.xml index 5136bf7..679491a 100644 --- a/app-common/src/main/res/values-zh-rTW/strings.xml +++ b/app-common/src/main/res/values-zh-rTW/strings.xml @@ -6,9 +6,9 @@ 幫助 重新載入卡槽 虛擬卡槽 %d - 已啟用 - 已停用 - 電信業者: + 已啟用 + 已停用 + 電信業者: 類型: 啟用 停用 diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 38bb976..abdd5f3 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -11,14 +11,15 @@ USB OpenMobile API (OMAPI) - Enabled - Disabled - Provider: + + Enabled + Disabled + Provider: Class: Testing Provisioning Operational - ICCID: + ICCID: #%d Enable diff --git a/app-unpriv/src/main/AndroidManifest.xml b/app-unpriv/src/main/AndroidManifest.xml index ce985cd..9c14163 100644 --- a/app-unpriv/src/main/AndroidManifest.xml +++ b/app-unpriv/src/main/AndroidManifest.xml @@ -24,9 +24,9 @@ + android:label="@string/quick_compatibility" /> by lazy { getCompatibilityChecks(this) } - private val adapter = CompatibilityChecksAdapter() - - override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_compatibility_check) - setSupportActionBar(requireViewById(im.angry.openeuicc.common.R.id.toolbar)) - setupToolbarInsets() - supportActionBar!!.setDisplayHomeAsUpEnabled(true) - - compatibilityCheckList = requireViewById(R.id.recycler_view).also { - it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) - it.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL)) - it.adapter = adapter - } - - setupRootViewInsets(compatibilityCheckList) - } - - @SuppressLint("NotifyDataSetChanged") - override fun onStart() { - super.onStart() - lifecycleScope.launch { - compatibilityChecks.executeAll { adapter.notifyDataSetChanged() } - } - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean = - when (item.itemId) { - android.R.id.home -> { - finish() - true - } - else -> super.onOptionsItemSelected(item) - } - - inner class ViewHolder(private val root: View): RecyclerView.ViewHolder(root) { - private val titleView: TextView = root.requireViewById(R.id.compatibility_check_title) - private val descView: TextView = root.requireViewById(R.id.compatibility_check_desc) - private val statusContainer: ViewGroup = root.requireViewById(R.id.compatibility_check_status_container) - - fun bindItem(item: CompatibilityCheck) { - titleView.text = item.title - descView.text = Html.fromHtml(item.description, Html.FROM_HTML_MODE_COMPACT) - - statusContainer.children.forEach { - it.isVisible = false - } - - val viewId = when (item.state) { - CompatibilityCheck.State.SUCCESS -> R.id.compatibility_check_checkmark - CompatibilityCheck.State.FAILURE -> R.id.compatibility_check_error - CompatibilityCheck.State.FAILURE_UNKNOWN -> R.id.compatibility_check_unknown - else -> R.id.compatibility_check_progress_bar - } - root.requireViewById(viewId).isVisible = true - } - } - - inner class CompatibilityChecksAdapter: RecyclerView.Adapter() { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = - ViewHolder(layoutInflater.inflate(R.layout.compatibility_check_item, parent, false)) - - override fun getItemCount(): Int = - compatibilityChecks.indexOfLast { it.state != CompatibilityCheck.State.NOT_STARTED } + 1 - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.bindItem(compatibilityChecks[position]) - } - } -} \ No newline at end of file diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityActivity.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityActivity.kt new file mode 100644 index 0000000..d5e599f --- /dev/null +++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityActivity.kt @@ -0,0 +1,24 @@ +package im.angry.openeuicc.ui + +import android.os.Bundle +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import im.angry.easyeuicc.R +import im.angry.openeuicc.di.UnprivilegedUiComponentFactory +import im.angry.openeuicc.util.OpenEuiccContextMarker + +class QuickCompatibilityActivity : AppCompatActivity(), OpenEuiccContextMarker { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_quick_compatibility) + + val quickCompatibilityFragment = + (appContainer.uiComponentFactory as UnprivilegedUiComponentFactory) + .createQuickCompatibilityFragment() + + supportFragmentManager.beginTransaction() + .replace(R.id.quick_compatibility_container, quickCompatibilityFragment) + .commit() + } +} diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityFragment.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityFragment.kt new file mode 100644 index 0000000..f6af78d --- /dev/null +++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/QuickCompatibilityFragment.kt @@ -0,0 +1,183 @@ +package im.angry.openeuicc.ui + +import android.content.pm.PackageManager +import android.icu.text.ListFormatter +import android.os.Build +import android.os.Bundle +import android.se.omapi.Reader +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.CheckBox +import android.widget.TextView +import androidx.core.view.isVisible +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import im.angry.easyeuicc.R +import im.angry.openeuicc.util.EUICC_DEFAULT_ISDR_AID +import im.angry.openeuicc.util.UnprivilegedEuiccContextMarker +import im.angry.openeuicc.util.connectSEService +import im.angry.openeuicc.util.decodeHex +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext + +open class QuickCompatibilityFragment : Fragment(), UnprivilegedEuiccContextMarker { + companion object { + enum class Compatibility { + COMPATIBLE, + NOT_COMPATIBLE, + } + + data class CompatibilityResult( + val compatibility: Compatibility, + val slotsOmapi: List = emptyList(), + val slotsIsdr: List = emptyList() + ) + } + + private val conclusion: TextView by lazy { + requireView().requireViewById(R.id.quick_compatibility_conclusion) + } + + private val resultSlots: TextView by lazy { + requireView().requireViewById(R.id.quick_compatibility_result_slots) + } + + private val resultSlotsIsdr: TextView by lazy { + requireView().requireViewById(R.id.quick_compatibility_result_slots_isdr) + } + + private val resultNotes: TextView by lazy { + requireView().requireViewById(R.id.quick_compatibility_result_notes) + } + + private val skipCheckBox: CheckBox by lazy { + requireView().requireViewById(R.id.quick_compatibility_skip) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View = inflater.inflate(R.layout.fragment_quick_compatibility, container, false).apply { + requireViewById(R.id.quick_compatibility_device_information) + .text = formatDeviceInformation() + requireViewById