| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- package im.angry.openeuicc.ui
- import android.annotation.SuppressLint
- import android.content.BroadcastReceiver
- import android.content.Context
- import android.content.Intent
- import android.content.IntentFilter
- import android.hardware.usb.UsbManager
- import android.os.Bundle
- import android.telephony.TelephonyManager
- import android.util.Log
- import android.view.Menu
- import android.view.MenuItem
- import android.view.View
- import android.widget.ProgressBar
- import androidx.fragment.app.Fragment
- import androidx.lifecycle.lifecycleScope
- import androidx.viewpager2.adapter.FragmentStateAdapter
- import androidx.viewpager2.widget.ViewPager2
- import com.google.android.material.tabs.TabLayout
- import com.google.android.material.tabs.TabLayoutMediator
- import im.angry.openeuicc.common.R
- import im.angry.openeuicc.util.*
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.launch
- import kotlinx.coroutines.withContext
- @SuppressLint("NotifyDataSetChanged")
- open class MainActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
- companion object {
- const val TAG = "MainActivity"
- }
- private lateinit var loadingProgress: ProgressBar
- private lateinit var tabs: TabLayout
- private lateinit var viewPager: ViewPager2
- private data class Page(
- val title: String,
- val createFragment: () -> Fragment
- )
- private val pages: MutableList<Page> = mutableListOf()
- private val pagerAdapter by lazy {
- object : FragmentStateAdapter(this) {
- override fun getItemCount() = pages.size
- override fun createFragment(position: Int): Fragment = pages[position].createFragment()
- }
- }
- var loading: Boolean
- get() = loadingProgress.visibility == View.VISIBLE
- set(value) {
- loadingProgress.visibility = if (value) {
- View.VISIBLE
- } else {
- View.GONE
- }
- }
- protected lateinit var tm: TelephonyManager
- private val usbReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
- if (intent?.action == UsbManager.ACTION_USB_DEVICE_ATTACHED || intent?.action == UsbManager.ACTION_USB_DEVICE_DETACHED) {
- refresh()
- }
- }
- }
- @SuppressLint("WrongConstant", "UnspecifiedRegisterReceiverFlag")
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- setSupportActionBar(requireViewById(R.id.toolbar))
- loadingProgress = requireViewById(R.id.loading)
- tabs = requireViewById(R.id.main_tabs)
- viewPager = requireViewById(R.id.view_pager)
- viewPager.adapter = pagerAdapter
- TabLayoutMediator(tabs, viewPager) { tab, pos ->
- tab.text = pages[pos].title
- }.attach()
- tm = telephonyManager
- registerReceiver(usbReceiver, IntentFilter().apply {
- addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
- addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
- })
- }
- override fun onDestroy() {
- super.onDestroy()
- unregisterReceiver(usbReceiver)
- }
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.activity_main, menu)
- return true
- }
- override fun onOptionsItemSelected(item: MenuItem): Boolean =
- when (item.itemId) {
- R.id.settings -> {
- startActivity(Intent(this, SettingsActivity::class.java));
- true
- }
- R.id.reload -> {
- refresh()
- true
- }
- else -> super.onOptionsItemSelected(item)
- }
- override fun onInit() {
- lifecycleScope.launch {
- init()
- }
- }
- private suspend fun init() {
- loading = true
- viewPager.visibility = View.GONE
- tabs.visibility = View.GONE
- val knownChannels = withContext(Dispatchers.IO) {
- euiccChannelManager.enumerateEuiccChannels().onEach {
- Log.d(TAG, "slot ${it.slotId} port ${it.portId}")
- Log.d(TAG, it.lpa.eID)
- // Request the system to refresh the list of profiles every time we start
- // Note that this is currently supposed to be no-op when unprivileged,
- // but it could change in the future
- euiccChannelManager.notifyEuiccProfilesChanged(it.logicalSlotId)
- }
- }
- val (usbDevice, _) = withContext(Dispatchers.IO) {
- euiccChannelManager.enumerateUsbEuiccChannel()
- }
- withContext(Dispatchers.Main) {
- loading = false
- knownChannels.sortedBy { it.logicalSlotId }.forEach { channel ->
- pages.add(Page(
- getString(R.string.channel_name_format, channel.logicalSlotId)
- ) { appContainer.uiComponentFactory.createEuiccManagementFragment(channel) })
- }
- // If USB readers exist, add them at the very last
- // We use a wrapper fragment to handle logic specific to USB readers
- usbDevice?.let {
- //spinnerAdapter.add(it.productName)
- pages.add(Page(it.productName ?: "USB") { UsbCcidReaderFragment() })
- }
- pagerAdapter.notifyDataSetChanged()
- viewPager.visibility = View.VISIBLE
- if (pages.size > 1) {
- tabs.visibility = View.VISIBLE
- } else if (pages.isEmpty()) {
- pages.add(Page("") { appContainer.uiComponentFactory.createNoEuiccPlaceholderFragment() })
- pagerAdapter.notifyDataSetChanged()
- }
- }
- }
- private fun refresh() {
- lifecycleScope.launch {
- loading = true
- viewPager.visibility = View.GONE
- tabs.visibility = View.GONE
- pages.clear()
- pagerAdapter.notifyDataSetChanged()
- init()
- }
- }
- }
|