EuiccManagementFragment.kt 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package im.angry.openeuicc.ui
  2. import android.annotation.SuppressLint
  3. import android.os.Bundle
  4. import android.text.method.PasswordTransformationMethod
  5. import android.view.LayoutInflater
  6. import android.view.View
  7. import android.view.ViewGroup
  8. import androidx.fragment.app.Fragment
  9. import androidx.lifecycle.lifecycleScope
  10. import androidx.recyclerview.widget.LinearLayoutManager
  11. import androidx.recyclerview.widget.RecyclerView
  12. import im.angry.openeuicc.R
  13. import im.angry.openeuicc.databinding.EuiccProfileBinding
  14. import im.angry.openeuicc.databinding.FragmentEuiccBinding
  15. import kotlinx.coroutines.Dispatchers
  16. import kotlinx.coroutines.launch
  17. import kotlinx.coroutines.withContext
  18. class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesChangedListener {
  19. companion object {
  20. fun newInstance(slotId: Int): EuiccManagementFragment =
  21. newInstanceEuicc(EuiccManagementFragment::class.java, slotId)
  22. }
  23. private var _binding: FragmentEuiccBinding? = null
  24. private val binding get() = _binding!!
  25. private val adapter = EuiccProfileAdapter(listOf())
  26. override fun onCreateView(
  27. inflater: LayoutInflater,
  28. container: ViewGroup?,
  29. savedInstanceState: Bundle?
  30. ): View {
  31. _binding = FragmentEuiccBinding.inflate(inflater, container, false)
  32. return binding.root
  33. }
  34. override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  35. super.onViewCreated(view, savedInstanceState)
  36. binding.swipeRefresh.setOnRefreshListener { refresh() }
  37. binding.profileList.adapter = adapter
  38. binding.profileList.layoutManager =
  39. LinearLayoutManager(view.context, LinearLayoutManager.VERTICAL, false)
  40. binding.fab.setOnClickListener {
  41. ProfileDownloadFragment.newInstance(slotId)
  42. .show(childFragmentManager, ProfileDownloadFragment.TAG)
  43. }
  44. }
  45. override fun onStart() {
  46. super.onStart()
  47. refresh()
  48. }
  49. override fun onEuiccProfilesChanged() {
  50. refresh()
  51. }
  52. @SuppressLint("NotifyDataSetChanged")
  53. private fun refresh() {
  54. binding.swipeRefresh.isRefreshing = true
  55. lifecycleScope.launch {
  56. val profiles = withContext(Dispatchers.IO) {
  57. channel.lpa.profiles
  58. }
  59. withContext(Dispatchers.Main) {
  60. adapter.profiles = profiles
  61. adapter.notifyDataSetChanged()
  62. binding.swipeRefresh.isRefreshing = false
  63. }
  64. }
  65. }
  66. }
  67. class EuiccProfileAdapter(var profiles: List<Map<String, String>>) :
  68. RecyclerView.Adapter<EuiccProfileAdapter.ViewHolder>() {
  69. data class ViewHolder(val binding: EuiccProfileBinding) : RecyclerView.ViewHolder(binding.root) {
  70. init {
  71. binding.iccid.setOnClickListener {
  72. if (binding.iccid.transformationMethod == null) {
  73. binding.iccid.transformationMethod = PasswordTransformationMethod.getInstance()
  74. } else {
  75. binding.iccid.transformationMethod = null
  76. }
  77. }
  78. }
  79. }
  80. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
  81. val binding =
  82. EuiccProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
  83. return ViewHolder(binding)
  84. }
  85. override fun onBindViewHolder(holder: ViewHolder, position: Int) {
  86. // TODO: The library is not exposing the nicknames. Expose them so that we can do something here.
  87. holder.binding.name.text = profiles[position]["NAME"]
  88. holder.binding.state.setText(
  89. if (profiles[position]["STATE"]?.lowercase() == "enabled") {
  90. R.string.enabled
  91. } else {
  92. R.string.disabled
  93. }
  94. )
  95. holder.binding.provider.text = profiles[position]["PROVIDER_NAME"]
  96. holder.binding.iccid.text = profiles[position]["ICCID"]
  97. holder.binding.iccid.transformationMethod = PasswordTransformationMethod.getInstance()
  98. }
  99. override fun getItemCount(): Int = profiles.size
  100. }