瀏覽代碼

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...
Peter Cai 2 年之前
父節點
當前提交
632b6b4931

+ 117 - 0
.idea/codeStyles/Project.xml

@@ -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 - 0
.idea/codeStyles/codeStyleConfig.xml

@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
+  </state>
+</component>

+ 6 - 6
app-common/src/main/java/im/angry/openeuicc/ui/DirectProfileDownloadActivity.kt

@@ -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 - 6
app-common/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt

@@ -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)!!

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

@@ -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"
 

+ 3 - 3
app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt

@@ -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)
 

+ 3 - 4
app-common/src/main/java/im/angry/openeuicc/ui/NotificationsActivity.kt

@@ -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)

+ 1 - 4
app-common/src/main/java/im/angry/openeuicc/ui/ProfileDeleteFragment.kt

@@ -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 {

+ 3 - 4
app-common/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt

@@ -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"
 

+ 1 - 1
app-common/src/main/java/im/angry/openeuicc/ui/ProfileRenameFragment.kt

@@ -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

+ 3 - 4
app-common/src/main/java/im/angry/openeuicc/ui/SlotSelectFragment.kt

@@ -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(

+ 19 - 5
app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt

@@ -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>
 /**

+ 2 - 1
app/src/main/java/im/angry/openeuicc/ui/SlotMappingFragment.kt

@@ -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"
     }