TelephonyCompat.kt 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package im.angry.openeuicc.util
  2. import android.content.Context
  3. import android.os.Build
  4. import android.se.omapi.Reader
  5. import android.se.omapi.SEService
  6. import android.telephony.TelephonyManager
  7. import kotlinx.coroutines.runBlocking
  8. import kotlinx.coroutines.sync.Mutex
  9. import kotlinx.coroutines.sync.withLock
  10. import kotlin.coroutines.resume
  11. import kotlin.coroutines.resumeWithException
  12. import kotlin.coroutines.suspendCoroutine
  13. val TelephonyManager.activeModemCountCompat: Int
  14. get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  15. activeModemCount
  16. } else {
  17. phoneCount
  18. }
  19. fun SEService.getUiccReaderCompat(slotNumber: Int): Reader {
  20. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  21. return getUiccReader(slotNumber)
  22. } else {
  23. return readers.first { it.name == "SIM${slotNumber}" || (slotNumber == 1 && it.name == "SIM") }
  24. }
  25. }
  26. /*
  27. * In the privileged version, the EuiccChannelManager should work
  28. * based on real Uicc{Card,Port}Info reported by TelephonyManager.
  29. * However, when unprivileged, we cannot depend on the fact that
  30. * we can access TelephonyManager. ARA-M only grants access to
  31. * OMAPI, but not TelephonyManager APIs that are associated with
  32. * carrier privileges.
  33. *
  34. * To maximally share code between the two variants, we define
  35. * an interface of whatever information will be used in the shared
  36. * portion of EuiccChannelManager etc. When unprivileged, we
  37. * generate "fake" versions based solely on how many slots the phone
  38. * has, while the privileged version can populate the fields with
  39. * real information, extending whenever needed.
  40. */
  41. interface UiccCardInfoCompat {
  42. val physicalSlotIndex: Int
  43. val ports: Collection<UiccPortInfoCompat>
  44. val isRemovable: Boolean
  45. get() = true // This defaults to removable unless overridden
  46. }
  47. interface UiccPortInfoCompat {
  48. val card: UiccCardInfoCompat
  49. val portIndex: Int
  50. val logicalSlotIndex: Int
  51. }
  52. data class FakeUiccCardInfoCompat(
  53. override val physicalSlotIndex: Int,
  54. ): UiccCardInfoCompat {
  55. override val ports: Collection<UiccPortInfoCompat> =
  56. listOf(FakeUiccPortInfoCompat(this))
  57. }
  58. data class FakeUiccPortInfoCompat(
  59. override val card: UiccCardInfoCompat
  60. ): UiccPortInfoCompat {
  61. override val portIndex: Int = 0
  62. override val logicalSlotIndex: Int = card.physicalSlotIndex
  63. }