ソースを参照

feat: EuiccInfoActivity

Peter Cai 1 年間 前
コミット
c2cc8ceb2a

+ 4 - 0
app-common/src/main/AndroidManifest.xml

@@ -24,6 +24,10 @@
             android:label="@string/profile_download"
             android:theme="@style/Theme.AppCompat.Translucent" />
 
+        <activity
+            android:name="im.angry.openeuicc.ui.EuiccInfoActivity"
+            android:label="@string/euicc_info" />
+
         <activity
             android:name="im.angry.openeuicc.ui.LogsActivity"
             android:label="@string/pref_advanced_logs" />

+ 137 - 0
app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt

@@ -0,0 +1,137 @@
+package im.angry.openeuicc.ui
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.activity.enableEdgeToEdge
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import im.angry.openeuicc.common.R
+import im.angry.openeuicc.util.*
+import kotlinx.coroutines.launch
+
+class EuiccInfoActivity : BaseEuiccAccessActivity() {
+    private lateinit var swipeRefresh: SwipeRefreshLayout
+    private lateinit var infoList: RecyclerView
+
+    private val euiccInfoItems: MutableList<Pair<String, String>> = mutableListOf()
+
+    private var logicalSlotId: Int = -1
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        enableEdgeToEdge()
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_euicc_info)
+        setSupportActionBar(requireViewById(R.id.toolbar))
+        setupToolbarInsets()
+        supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+
+        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()
+
+        logicalSlotId = intent.getIntExtra("logicalSlotId", 0)
+
+        swipeRefresh.setOnRefreshListener { refresh() }
+
+        setupRootViewInsets(infoList)
+    }
+
+    override fun onInit() {
+        refresh()
+    }
+
+    @SuppressLint("NotifyDataSetChanged")
+    private fun refresh() {
+        swipeRefresh.isRefreshing = true
+
+        lifecycleScope.launch {
+            euiccInfoItems.clear()
+
+            val unknownStr = getString(R.string.unknown)
+
+            val (euiccInfo2, eID) = euiccChannelManager.withEuiccChannel(logicalSlotId) { channel ->
+                Pair(channel.lpa.euiccInfo2, channel.lpa.eID)
+            }
+
+            euiccInfoItems.add(
+                Pair(
+                    getString(R.string.euicc_info_eid),
+                    eID
+                )
+            )
+
+            euiccInfoItems.add(
+                Pair(
+                    getString(R.string.euicc_info_firmware_version),
+                    euiccInfo2?.euiccFirmwareVersion ?: unknownStr
+                )
+            )
+
+            euiccInfoItems.add(
+                Pair(
+                    getString(R.string.euicc_info_globalplatform_version),
+                    euiccInfo2?.globalPlatformVersion ?: unknownStr
+                )
+            )
+
+            euiccInfoItems.add(
+                Pair(
+                    getString(R.string.euicc_info_pp_version),
+                    euiccInfo2?.ppVersion ?: unknownStr
+                )
+            )
+
+            euiccInfoItems.add(
+                Pair(
+                    getString(R.string.euicc_info_sas_accreditation_number),
+                    euiccInfo2?.sasAccreditationNumber ?: unknownStr
+                )
+            )
+
+            euiccInfoItems.add(Pair(
+                getString(R.string.euicc_info_free_nvram),
+                euiccInfo2?.freeNvram?.let { formatFreeSpace(it) } ?: unknownStr
+            ))
+
+            infoList.adapter!!.notifyDataSetChanged()
+
+            swipeRefresh.isRefreshing = false
+        }
+    }
+
+    inner class EuiccInfoViewHolder(root: View) : ViewHolder(root) {
+        private val title: TextView = root.requireViewById(R.id.euicc_info_title)
+        private val content: TextView = root.requireViewById(R.id.euicc_info_content)
+
+        fun bind(item: Pair<String, String>) {
+            title.text = item.first
+            content.text = item.second
+        }
+    }
+
+    inner class EuiccInfoAdapter : RecyclerView.Adapter<EuiccInfoViewHolder>() {
+        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EuiccInfoViewHolder {
+            val root = LayoutInflater.from(parent.context)
+                .inflate(R.layout.euicc_info_item, parent, false)
+            return EuiccInfoViewHolder(root)
+        }
+
+        override fun getItemCount(): Int = euiccInfoItems.size
+
+        override fun onBindViewHolder(holder: EuiccInfoViewHolder, position: Int) {
+            holder.bind(euiccInfoItems[position])
+        }
+    }
+}

+ 10 - 0
app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt

@@ -136,6 +136,16 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
                 true
             }
 
+            R.id.euicc_info -> {
+                if (logicalSlotId != -1) {
+                    Intent(requireContext(), EuiccInfoActivity::class.java).apply {
+                        putExtra("logicalSlotId", logicalSlotId)
+                        startActivity(this)
+                    }
+                }
+                true
+            }
+
             else -> super.onOptionsItemSelected(item)
         }
 

+ 25 - 0
app-common/src/main/res/layout/activity_euicc_info.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <include layout="@layout/toolbar_activity" />
+
+    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_refresh"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintTop_toBottomOf="@id/toolbar"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 32 - 0
app-common/src/main/res/layout/euicc_info_item.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?android:attr/selectableItemBackground"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <TextView
+        android:id="@+id/euicc_info_title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="24dp"
+        android:layout_marginVertical="12dp"
+        android:textStyle="bold"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/euicc_info_content"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="24dp"
+        android:layout_marginVertical="12dp"
+        android:maxLines="1"
+        android:ellipsize="marquee"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/euicc_info_title"
+        app:layout_constraintBottom_toBottomOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 5 - 0
app-common/src/main/res/menu/fragment_euicc.xml

@@ -5,4 +5,9 @@
         android:id="@+id/show_notifications"
         android:title="@string/profile_notifications_show"
         app:showAsAction="never" />
+
+    <item
+        android:id="@+id/euicc_info"
+        android:title="@string/euicc_info"
+        app:showAsAction="never" />
 </menu>

+ 8 - 0
app-common/src/main/res/values/strings.xml

@@ -71,6 +71,14 @@
     <string name="profile_notification_process">Process</string>
     <string name="profile_notification_delete">Delete</string>
 
+    <string name="euicc_info">eUICC Info</string>
+    <string name="euicc_info_eid">EID</string>
+    <string name="euicc_info_firmware_version">eUICC OS Version</string>
+    <string name="euicc_info_globalplatform_version">GlobalPlatform Version</string>
+    <string name="euicc_info_sas_accreditation_number">SAS Accreditation Number</string>
+    <string name="euicc_info_pp_version">Protected Profile Version</string>
+    <string name="euicc_info_free_nvram">Free NVRAM (eSIM profile storage)</string>
+
     <string name="logs_save">Save</string>
     <string name="logs_filename_template">Logs at %s</string>