refactor: Create OpenEuiccUIContextMarker to facilitate easy access to application-global singletons
yes yes yes we should be using dependency injection but let's keep it simple with AOSP building...
This commit is contained in:
parent
7c0be54fd7
commit
632b6b4931
13 changed files with 166 additions and 39 deletions
117
.idea/codeStyles/Project.xml
Normal file
117
.idea/codeStyles/Project.xml
Normal file
|
@ -0,0 +1,117 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
|
@ -8,27 +8,27 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DirectProfileDownloadActivity : AppCompatActivity(), SlotSelectFragment.SlotSelectedListener {
|
||||
class DirectProfileDownloadActivity : AppCompatActivity(), SlotSelectFragment.SlotSelectedListener, OpenEuiccUIContextMarker {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
openEuiccApplication.euiccChannelManager.enumerateEuiccChannels()
|
||||
euiccChannelManager.enumerateEuiccChannels()
|
||||
}
|
||||
|
||||
val knownChannels = openEuiccApplication.euiccChannelManager.knownChannels
|
||||
when {
|
||||
knownChannels.isEmpty() -> {
|
||||
euiccChannelManager.knownChannels.isEmpty() -> {
|
||||
finish()
|
||||
}
|
||||
knownChannels.hasMultipleChips -> {
|
||||
euiccChannelManager.knownChannels.hasMultipleChips -> {
|
||||
SlotSelectFragment.newInstance()
|
||||
.show(supportFragmentManager, SlotSelectFragment.TAG)
|
||||
}
|
||||
else -> {
|
||||
// If the device has only one eSIM "chip" (but may be mapped to multiple slots),
|
||||
// we can skip the slot selection dialog since there is only one chip to save to.
|
||||
onSlotSelected(knownChannels[0].slotId, knownChannels[0].portId)
|
||||
onSlotSelected(euiccChannelManager.knownChannels[0].slotId,
|
||||
euiccChannelManager.knownChannels[0].portId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@ package im.angry.openeuicc.ui
|
|||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import im.angry.openeuicc.core.EuiccChannelManager
|
||||
import im.angry.openeuicc.core.EuiccChannel
|
||||
import im.angry.openeuicc.util.openEuiccApplication
|
||||
import im.angry.openeuicc.util.*
|
||||
|
||||
interface EuiccFragmentMarker
|
||||
interface EuiccFragmentMarker: OpenEuiccUIContextMarker
|
||||
|
||||
fun <T> newInstanceEuicc(clazz: Class<T>, slotId: Int, portId: Int, addArguments: Bundle.() -> Unit = {}): T where T: Fragment, T: EuiccFragmentMarker {
|
||||
val instance = clazz.newInstance()
|
||||
|
@ -23,9 +22,6 @@ val <T> T.slotId: Int where T: Fragment, T: EuiccFragmentMarker
|
|||
val <T> T.portId: Int where T: Fragment, T: EuiccFragmentMarker
|
||||
get() = requireArguments().getInt("portId")
|
||||
|
||||
val <T> T.euiccChannelManager: EuiccChannelManager where T: Fragment, T: EuiccFragmentMarker
|
||||
get() = openEuiccApplication.euiccChannelManager
|
||||
|
||||
val <T> T.channel: EuiccChannel where T: Fragment, T: EuiccFragmentMarker
|
||||
get() =
|
||||
euiccChannelManager.findEuiccChannelByPortBlocking(slotId, portId)!!
|
||||
|
|
|
@ -31,7 +31,7 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
import java.lang.Exception
|
||||
|
||||
open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesChangedListener {
|
||||
open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener, EuiccFragmentMarker {
|
||||
companion object {
|
||||
const val TAG = "EuiccManagementFragment"
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
open class MainActivity : AppCompatActivity() {
|
||||
open class MainActivity : AppCompatActivity(), OpenEuiccUIContextMarker {
|
||||
companion object {
|
||||
const val TAG = "MainActivity"
|
||||
}
|
||||
|
@ -43,9 +43,9 @@ open class MainActivity : AppCompatActivity() {
|
|||
|
||||
noEuiccPlaceholder = findViewById(R.id.no_euicc_placeholder)
|
||||
|
||||
tm = openEuiccApplication.telephonyManager
|
||||
tm = telephonyManager
|
||||
|
||||
manager = openEuiccApplication.euiccChannelManager
|
||||
manager = euiccChannelManager
|
||||
|
||||
spinnerAdapter = ArrayAdapter<String>(this, R.layout.spinner_item)
|
||||
|
||||
|
|
|
@ -19,16 +19,15 @@ import androidx.recyclerview.widget.DividerItemDecoration
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import im.angry.openeuicc.OpenEuiccApplication
|
||||
import im.angry.openeuicc.common.R
|
||||
import im.angry.openeuicc.core.EuiccChannel
|
||||
import im.angry.openeuicc.util.displayName
|
||||
import im.angry.openeuicc.util.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.typeblog.lpac_jni.LocalProfileNotification
|
||||
|
||||
class NotificationsActivity: AppCompatActivity() {
|
||||
class NotificationsActivity: AppCompatActivity(), OpenEuiccUIContextMarker {
|
||||
private lateinit var swipeRefresh: SwipeRefreshLayout
|
||||
private lateinit var notificationList: RecyclerView
|
||||
private val notificationAdapter = NotificationAdapter()
|
||||
|
@ -41,7 +40,7 @@ class NotificationsActivity: AppCompatActivity() {
|
|||
setSupportActionBar(findViewById(R.id.toolbar))
|
||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
euiccChannel = (application as OpenEuiccApplication).euiccChannelManager
|
||||
euiccChannel = euiccChannelManager
|
||||
.findEuiccChannelBySlotBlocking(intent.getIntExtra("logicalSlotId", 0))!!
|
||||
|
||||
swipeRefresh = findViewById(R.id.swipe_refresh)
|
||||
|
|
|
@ -7,12 +7,9 @@ import androidx.appcompat.app.AlertDialog
|
|||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import im.angry.openeuicc.common.R
|
||||
import im.angry.openeuicc.util.preferenceRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import im.angry.openeuicc.util.*
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.typeblog.lpac_jni.LocalProfileNotification
|
||||
import java.lang.Exception
|
||||
|
||||
class ProfileDeleteFragment : DialogFragment(), EuiccFragmentMarker {
|
||||
|
|
|
@ -17,9 +17,7 @@ import com.google.android.material.textfield.TextInputLayout
|
|||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import im.angry.openeuicc.common.R
|
||||
import im.angry.openeuicc.util.openEuiccApplication
|
||||
import im.angry.openeuicc.util.preferenceRepository
|
||||
import im.angry.openeuicc.util.setWidthPercent
|
||||
import im.angry.openeuicc.util.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -27,7 +25,8 @@ import kotlinx.coroutines.withContext
|
|||
import net.typeblog.lpac_jni.ProfileDownloadCallback
|
||||
import kotlin.Exception
|
||||
|
||||
class ProfileDownloadFragment : BaseMaterialDialogFragment(), EuiccFragmentMarker, Toolbar.OnMenuItemClickListener {
|
||||
class ProfileDownloadFragment : BaseMaterialDialogFragment(),
|
||||
Toolbar.OnMenuItemClickListener, EuiccFragmentMarker {
|
||||
companion object {
|
||||
const val TAG = "ProfileDownloadFragment"
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import androidx.appcompat.widget.Toolbar
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import im.angry.openeuicc.common.R
|
||||
import im.angry.openeuicc.util.setWidthPercent
|
||||
import im.angry.openeuicc.util.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
|
@ -10,10 +10,9 @@ import android.widget.Spinner
|
|||
import androidx.appcompat.widget.Toolbar
|
||||
import im.angry.openeuicc.common.R
|
||||
import im.angry.openeuicc.core.EuiccChannel
|
||||
import im.angry.openeuicc.util.openEuiccApplication
|
||||
import im.angry.openeuicc.util.setWidthPercent
|
||||
import im.angry.openeuicc.util.*
|
||||
|
||||
class SlotSelectFragment : BaseMaterialDialogFragment() {
|
||||
class SlotSelectFragment : BaseMaterialDialogFragment(), OpenEuiccUIContextMarker {
|
||||
companion object {
|
||||
const val TAG = "SlotSelectFragment"
|
||||
|
||||
|
@ -30,7 +29,7 @@ class SlotSelectFragment : BaseMaterialDialogFragment() {
|
|||
private lateinit var toolbar: Toolbar
|
||||
private lateinit var spinner: Spinner
|
||||
private val channels: List<EuiccChannel> by lazy {
|
||||
openEuiccApplication.euiccChannelManager.knownChannels.sortedBy { it.logicalSlotId }
|
||||
euiccChannelManager.knownChannels.sortedBy { it.logicalSlotId }
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
|
|
|
@ -1,18 +1,32 @@
|
|||
package im.angry.openeuicc.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Rect
|
||||
import android.telephony.TelephonyManager
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import im.angry.openeuicc.OpenEuiccApplication
|
||||
import im.angry.openeuicc.core.EuiccChannelManager
|
||||
|
||||
val Activity.openEuiccApplication: OpenEuiccApplication
|
||||
get() = application as OpenEuiccApplication
|
||||
interface OpenEuiccUIContextMarker
|
||||
|
||||
val Fragment.openEuiccApplication: OpenEuiccApplication
|
||||
get() = requireActivity().openEuiccApplication
|
||||
val OpenEuiccUIContextMarker.context: Context
|
||||
get() = when (this) {
|
||||
is Context -> this
|
||||
is Fragment -> requireContext()
|
||||
else -> throw RuntimeException("OpenEuiccUIContextMarker shall only be used on Fragments or UI types that derive from Context")
|
||||
}
|
||||
|
||||
val OpenEuiccUIContextMarker.openEuiccApplication: OpenEuiccApplication
|
||||
get() = context.applicationContext as OpenEuiccApplication
|
||||
|
||||
val OpenEuiccUIContextMarker.euiccChannelManager: EuiccChannelManager
|
||||
get() = openEuiccApplication.euiccChannelManager
|
||||
|
||||
val OpenEuiccUIContextMarker.telephonyManager: TelephonyManager
|
||||
get() = openEuiccApplication.telephonyManager
|
||||
|
||||
// Source: <https://stackoverflow.com/questions/12478520/how-to-set-dialogfragments-width-and-height>
|
||||
/**
|
||||
|
|
|
@ -26,7 +26,8 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class SlotMappingFragment: BaseMaterialDialogFragment(), OnMenuItemClickListener {
|
||||
class SlotMappingFragment: BaseMaterialDialogFragment(),
|
||||
OnMenuItemClickListener, OpenEuiccUIContextMarker {
|
||||
companion object {
|
||||
const val TAG = "SlotMappingFragment"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue