|
@@ -1,13 +1,18 @@
|
|
|
package im.angry.openeuicc.ui
|
|
package im.angry.openeuicc.ui
|
|
|
|
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.annotation.SuppressLint
|
|
|
|
|
+import android.content.ClipData
|
|
|
|
|
+import android.content.ClipboardManager
|
|
|
|
|
+import android.os.Build
|
|
|
import android.os.Bundle
|
|
import android.os.Bundle
|
|
|
import android.view.LayoutInflater
|
|
import android.view.LayoutInflater
|
|
|
import android.view.MenuItem
|
|
import android.view.MenuItem
|
|
|
import android.view.View
|
|
import android.view.View
|
|
|
import android.view.ViewGroup
|
|
import android.view.ViewGroup
|
|
|
import android.widget.TextView
|
|
import android.widget.TextView
|
|
|
|
|
+import android.widget.Toast
|
|
|
import androidx.activity.enableEdgeToEdge
|
|
import androidx.activity.enableEdgeToEdge
|
|
|
|
|
+import androidx.annotation.StringRes
|
|
|
import androidx.lifecycle.lifecycleScope
|
|
import androidx.lifecycle.lifecycleScope
|
|
|
import androidx.recyclerview.widget.DividerItemDecoration
|
|
import androidx.recyclerview.widget.DividerItemDecoration
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
@@ -32,6 +37,13 @@ class EuiccInfoActivity : BaseEuiccAccessActivity() {
|
|
|
|
|
|
|
|
private var logicalSlotId: Int = -1
|
|
private var logicalSlotId: Int = -1
|
|
|
|
|
|
|
|
|
|
+ data class Item(
|
|
|
|
|
+ @StringRes
|
|
|
|
|
+ val titleResId: Int,
|
|
|
|
|
+ val content: String?,
|
|
|
|
|
+ val copiedToastResId: Int? = null
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
enableEdgeToEdge()
|
|
enableEdgeToEdge()
|
|
|
super.onCreate(savedInstanceState)
|
|
super.onCreate(savedInstanceState)
|
|
@@ -41,12 +53,11 @@ class EuiccInfoActivity : BaseEuiccAccessActivity() {
|
|
|
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
|
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
|
|
|
|
|
|
|
swipeRefresh = requireViewById(R.id.swipe_refresh)
|
|
swipeRefresh = requireViewById(R.id.swipe_refresh)
|
|
|
- infoList = requireViewById(R.id.recycler_view)
|
|
|
|
|
-
|
|
|
|
|
- infoList.layoutManager =
|
|
|
|
|
- LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
|
|
|
|
- infoList.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
|
|
|
|
|
- infoList.adapter = EuiccInfoAdapter()
|
|
|
|
|
|
|
+ infoList = requireViewById<RecyclerView>(R.id.recycler_view).also {
|
|
|
|
|
+ it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
|
|
|
|
+ it.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
|
|
|
|
|
+ it.adapter = EuiccInfoAdapter()
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
logicalSlotId = intent.getIntExtra("logicalSlotId", 0)
|
|
logicalSlotId = intent.getIntExtra("logicalSlotId", 0)
|
|
|
|
|
|
|
@@ -81,29 +92,33 @@ class EuiccInfoActivity : BaseEuiccAccessActivity() {
|
|
|
|
|
|
|
|
lifecycleScope.launch {
|
|
lifecycleScope.launch {
|
|
|
(infoList.adapter!! as EuiccInfoAdapter).euiccInfoItems =
|
|
(infoList.adapter!! as EuiccInfoAdapter).euiccInfoItems =
|
|
|
- euiccChannelManager.withEuiccChannel(logicalSlotId, ::buildPairs).map {
|
|
|
|
|
- Pair(getString(it.first), it.second ?: getString(R.string.unknown))
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ euiccChannelManager.withEuiccChannel(logicalSlotId, ::buildEuiccInfoItems)
|
|
|
|
|
|
|
|
swipeRefresh.isRefreshing = false
|
|
swipeRefresh.isRefreshing = false
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private fun buildPairs(channel: EuiccChannel) = buildList {
|
|
|
|
|
- add(Pair(R.string.euicc_info_access_mode, channel.type))
|
|
|
|
|
|
|
+ private fun buildEuiccInfoItems(channel: EuiccChannel) = buildList {
|
|
|
|
|
+ add(Item(R.string.euicc_info_access_mode, channel.type))
|
|
|
add(
|
|
add(
|
|
|
- Pair(
|
|
|
|
|
|
|
+ Item(
|
|
|
R.string.euicc_info_removable,
|
|
R.string.euicc_info_removable,
|
|
|
formatByBoolean(channel.port.card.isRemovable, YES_NO)
|
|
formatByBoolean(channel.port.card.isRemovable, YES_NO)
|
|
|
)
|
|
)
|
|
|
)
|
|
)
|
|
|
- add(Pair(R.string.euicc_info_eid, channel.lpa.eID))
|
|
|
|
|
|
|
+ add(
|
|
|
|
|
+ Item(
|
|
|
|
|
+ R.string.euicc_info_eid,
|
|
|
|
|
+ channel.lpa.eID,
|
|
|
|
|
+ copiedToastResId = R.string.toast_eid_copied
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
channel.lpa.euiccInfo2.let { info ->
|
|
channel.lpa.euiccInfo2.let { info ->
|
|
|
- add(Pair(R.string.euicc_info_firmware_version, info?.euiccFirmwareVersion))
|
|
|
|
|
- add(Pair(R.string.euicc_info_globalplatform_version, info?.globalPlatformVersion))
|
|
|
|
|
- add(Pair(R.string.euicc_info_pp_version, info?.ppVersion))
|
|
|
|
|
- add(Pair(R.string.euicc_info_sas_accreditation_number, info?.sasAccreditationNumber))
|
|
|
|
|
- add(Pair(R.string.euicc_info_free_nvram, info?.freeNvram?.let(::formatFreeSpace)))
|
|
|
|
|
|
|
+ add(Item(R.string.euicc_info_firmware_version, info?.euiccFirmwareVersion))
|
|
|
|
|
+ add(Item(R.string.euicc_info_globalplatform_version, info?.globalPlatformVersion))
|
|
|
|
|
+ add(Item(R.string.euicc_info_pp_version, info?.ppVersion))
|
|
|
|
|
+ add(Item(R.string.euicc_info_sas_accreditation_number, info?.sasAccreditationNumber))
|
|
|
|
|
+ add(Item(R.string.euicc_info_free_nvram, info?.freeNvram?.let(::formatFreeSpace)))
|
|
|
}
|
|
}
|
|
|
channel.lpa.euiccInfo2?.euiccCiPKIdListForSigning.orEmpty().let { signers ->
|
|
channel.lpa.euiccInfo2?.euiccCiPKIdListForSigning.orEmpty().let { signers ->
|
|
|
// SGP.28 v1.0, eSIM CI Registration Criteria (Page 5 of 9, 2019-10-24)
|
|
// SGP.28 v1.0, eSIM CI Registration Criteria (Page 5 of 9, 2019-10-24)
|
|
@@ -116,7 +131,7 @@ class EuiccInfoActivity : BaseEuiccAccessActivity() {
|
|
|
PKID_GSMA_TEST_CI.any(signers::contains) -> R.string.euicc_info_ci_gsma_test
|
|
PKID_GSMA_TEST_CI.any(signers::contains) -> R.string.euicc_info_ci_gsma_test
|
|
|
else -> R.string.euicc_info_ci_unknown
|
|
else -> R.string.euicc_info_ci_unknown
|
|
|
}
|
|
}
|
|
|
- add(Pair(R.string.euicc_info_ci_type, getString(resId)))
|
|
|
|
|
|
|
+ add(Item(R.string.euicc_info_ci_type, getString(resId)))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -132,15 +147,34 @@ class EuiccInfoActivity : BaseEuiccAccessActivity() {
|
|
|
inner class EuiccInfoViewHolder(root: View) : ViewHolder(root) {
|
|
inner class EuiccInfoViewHolder(root: View) : ViewHolder(root) {
|
|
|
private val title: TextView = root.requireViewById(R.id.euicc_info_title)
|
|
private val title: TextView = root.requireViewById(R.id.euicc_info_title)
|
|
|
private val content: TextView = root.requireViewById(R.id.euicc_info_content)
|
|
private val content: TextView = root.requireViewById(R.id.euicc_info_content)
|
|
|
|
|
+ private var copiedToastResId: Int? = null
|
|
|
|
|
+
|
|
|
|
|
+ init {
|
|
|
|
|
+ root.setOnClickListener {
|
|
|
|
|
+ if (copiedToastResId != null) {
|
|
|
|
|
+ val label = title.text.toString()
|
|
|
|
|
+ getSystemService(ClipboardManager::class.java)!!
|
|
|
|
|
+ .setPrimaryClip(ClipData.newPlainText(label, content.text))
|
|
|
|
|
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
|
|
|
|
+ Toast.makeText(
|
|
|
|
|
+ this@EuiccInfoActivity,
|
|
|
|
|
+ copiedToastResId!!,
|
|
|
|
|
+ Toast.LENGTH_SHORT
|
|
|
|
|
+ ).show()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- fun bind(item: Pair<String, String>) {
|
|
|
|
|
- title.text = item.first
|
|
|
|
|
- content.text = item.second
|
|
|
|
|
|
|
+ fun bind(item: Item) {
|
|
|
|
|
+ copiedToastResId = item.copiedToastResId
|
|
|
|
|
+ title.setText(item.titleResId)
|
|
|
|
|
+ content.text = item.content ?: getString(R.string.unknown)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
inner class EuiccInfoAdapter : RecyclerView.Adapter<EuiccInfoViewHolder>() {
|
|
inner class EuiccInfoAdapter : RecyclerView.Adapter<EuiccInfoViewHolder>() {
|
|
|
- var euiccInfoItems: List<Pair<String, String>> = listOf()
|
|
|
|
|
|
|
+ var euiccInfoItems: List<Item> = listOf()
|
|
|
@SuppressLint("NotifyDataSetChanged")
|
|
@SuppressLint("NotifyDataSetChanged")
|
|
|
set(newVal) {
|
|
set(newVal) {
|
|
|
field = newVal
|
|
field = newVal
|