bugfix: camConfig shouldn't be a static field of the MainActivity

When another instance of MainActivity (or its subclass) starts, it overwrites
this field, which breaks all other instances of MainActivity (or its subclass).

Make camConfig an instance field to resolve this issue.

Note that passing camConfig to MoreSettings is a bit hacky, but a proper fix
would be a lot more work for little upside.
diff --git a/app/src/main/java/app/grapheneos/camera/CamConfig.kt b/app/src/main/java/app/grapheneos/camera/CamConfig.kt
index 53c6f6c..89aa1ef 100644
--- a/app/src/main/java/app/grapheneos/camera/CamConfig.kt
+++ b/app/src/main/java/app/grapheneos/camera/CamConfig.kt
@@ -41,6 +41,7 @@
 import app.grapheneos.camera.analyzer.QRAnalyzer
 import app.grapheneos.camera.ui.activities.CaptureActivity
 import app.grapheneos.camera.ui.activities.MainActivity
+import app.grapheneos.camera.ui.activities.MoreSettings
 import app.grapheneos.camera.ui.activities.SecureActivity
 import app.grapheneos.camera.ui.activities.SecureMainActivity
 import app.grapheneos.camera.ui.activities.VideoCaptureActivity
@@ -198,7 +199,7 @@
 
     var iAnalyzer: ImageAnalysis? = null
 
-    val mPlayer: TunePlayer by lazy { TunePlayer(mActivity.applicationContext) }
+    val mPlayer: TunePlayer by lazy { TunePlayer(mActivity) }
 
     // note that Activities which implement SecureActivity interface (meaning they are accessible
     // from the lock screen) are forced to override getSharedPreferences()
@@ -1413,7 +1414,7 @@
         builder.setMessage(R.string.reverting_to_default_folder)
         builder.setPositiveButton(R.string.ok, null)
         builder.setNeutralButton(R.string.more_settings) { _, _ ->
-            mActivity.settingsDialog.openMoreSettings()
+            MoreSettings.start(mActivity)
         }
         val alertDialog: AlertDialog = builder.create()
         alertDialog.setCancelable(false)
diff --git a/app/src/main/java/app/grapheneos/camera/NumInputFilter.kt b/app/src/main/java/app/grapheneos/camera/NumInputFilter.kt
index c75de74..a40a559 100644
--- a/app/src/main/java/app/grapheneos/camera/NumInputFilter.kt
+++ b/app/src/main/java/app/grapheneos/camera/NumInputFilter.kt
@@ -4,7 +4,7 @@
 import android.text.Spanned
 import app.grapheneos.camera.ui.activities.MoreSettings
 
-class NumInputFilter(private val mActivity: MoreSettings) : InputFilter {
+class NumInputFilter(private val settings: MoreSettings) : InputFilter {
 
     override fun filter(
         source: CharSequence,
@@ -22,9 +22,7 @@
             if (isInRange(input)) {
                 return null
             } else {
-                mActivity.showMessage(
-                    "Photo quality can only be between $min and $max"
-                )
+                settings.showMessage("Photo quality can only be between $min and $max")
             }
         } catch (e: NumberFormatException) {
             e.printStackTrace()
@@ -40,4 +38,4 @@
         const val min = 1
         const val max = 100
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/app/grapheneos/camera/TunePlayer.kt b/app/src/main/java/app/grapheneos/camera/TunePlayer.kt
index b373f78..a961156 100644
--- a/app/src/main/java/app/grapheneos/camera/TunePlayer.kt
+++ b/app/src/main/java/app/grapheneos/camera/TunePlayer.kt
@@ -1,10 +1,9 @@
 package app.grapheneos.camera
 
-import android.content.Context
 import android.media.MediaPlayer
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
+import app.grapheneos.camera.ui.activities.MainActivity
 
-class TunePlayer(context: Context) {
+class TunePlayer(val context: MainActivity) {
 
     private val shutterPlayer: MediaPlayer = MediaPlayer.create(context, R.raw.image_shot)
 
@@ -17,7 +16,7 @@
     private val vStopPlayer: MediaPlayer = MediaPlayer.create(context, R.raw.video_stop)
 
     private fun shouldNotPlayTune(): Boolean {
-        return !camConfig.enableCameraSounds
+        return !context.camConfig.enableCameraSounds
     }
 
     fun playShutterSound() {
@@ -60,4 +59,4 @@
         fSPlayer.seekTo(0)
         fSPlayer.start()
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/app/grapheneos/camera/analyzer/QRAnalyzer.kt b/app/src/main/java/app/grapheneos/camera/analyzer/QRAnalyzer.kt
index c261386..06820cf 100644
--- a/app/src/main/java/app/grapheneos/camera/analyzer/QRAnalyzer.kt
+++ b/app/src/main/java/app/grapheneos/camera/analyzer/QRAnalyzer.kt
@@ -4,7 +4,6 @@
 import androidx.camera.core.ImageAnalysis.Analyzer
 import androidx.camera.core.ImageProxy
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import com.google.zxing.BarcodeFormat
 import com.google.zxing.BinaryBitmap
 import com.google.zxing.DecodeHintType
@@ -31,6 +30,8 @@
     }
 
     fun refreshHints() {
+        val camConfig = mActivity.camConfig
+
         val supportedHints: MutableMap<DecodeHintType, Any> = EnumMap(
             DecodeHintType::class.java
         )
diff --git a/app/src/main/java/app/grapheneos/camera/capturer/ImageCapturer.kt b/app/src/main/java/app/grapheneos/camera/capturer/ImageCapturer.kt
index ea59378..99c3b75 100644
--- a/app/src/main/java/app/grapheneos/camera/capturer/ImageCapturer.kt
+++ b/app/src/main/java/app/grapheneos/camera/capturer/ImageCapturer.kt
@@ -21,13 +21,13 @@
 import app.grapheneos.camera.CapturedItem
 import app.grapheneos.camera.R
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import app.grapheneos.camera.ui.activities.SecureMainActivity
 
 private const val imageFileFormat = ".jpg"
 var isTakingPicture: Boolean = false
 
 class ImageCapturer(val mActivity: MainActivity) {
+    val camConfig = mActivity.camConfig
 
     @SuppressLint("RestrictedApi")
     fun takePicture() {
diff --git a/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt b/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt
index ba82faf..35f9052 100644
--- a/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt
+++ b/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt
@@ -27,7 +27,6 @@
 import app.grapheneos.camera.R
 import app.grapheneos.camera.VIDEO_NAME_PREFIX
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import app.grapheneos.camera.ui.activities.SecureMainActivity
 import app.grapheneos.camera.ui.activities.VideoCaptureActivity
 import app.grapheneos.camera.util.getTreeDocumentUri
@@ -37,6 +36,7 @@
 import java.util.Locale
 
 class VideoCapturer(private val mActivity: MainActivity) {
+    val camConfig = mActivity.camConfig
 
     var isRecording = false
         private set
diff --git a/app/src/main/java/app/grapheneos/camera/notifier/SensorOrientationChangeNotifier.kt b/app/src/main/java/app/grapheneos/camera/notifier/SensorOrientationChangeNotifier.kt
index a21f228..b676965 100644
--- a/app/src/main/java/app/grapheneos/camera/notifier/SensorOrientationChangeNotifier.kt
+++ b/app/src/main/java/app/grapheneos/camera/notifier/SensorOrientationChangeNotifier.kt
@@ -7,7 +7,6 @@
 import android.hardware.SensorManager
 import android.view.View
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import java.lang.ref.WeakReference
 import kotlin.math.abs
 import kotlin.math.atan
@@ -103,7 +102,7 @@
                 notifyListeners()
             }
 
-            if (!camConfig.shouldShowGyroscope()) return
+            if (!mainActivity.camConfig.shouldShowGyroscope()) return
 
             val dAngle = if (mainActivity.gCircleFrame.rotation == 270f) {
                 90f
diff --git a/app/src/main/java/app/grapheneos/camera/ui/CountDownTimerUI.kt b/app/src/main/java/app/grapheneos/camera/ui/CountDownTimerUI.kt
index e9b7b85..7289ee7 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/CountDownTimerUI.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/CountDownTimerUI.kt
@@ -10,9 +10,9 @@
 import android.view.animation.AccelerateDecelerateInterpolator
 import androidx.appcompat.widget.AppCompatTextView
 import androidx.camera.core.AspectRatio
+import app.grapheneos.camera.CamConfig
 import app.grapheneos.camera.ui.activities.CaptureActivity
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 
 class CountDownTimerUI @JvmOverloads constructor(
     context: Context, attrs: AttributeSet? = null
@@ -20,6 +20,7 @@
 
     private lateinit var timer: CountDownTimer
     lateinit var mActivity: MainActivity
+    lateinit var camConfig: CamConfig
 
     companion object {
         private const val textAnimDuration = 700L
@@ -33,6 +34,7 @@
 
     fun setMainActivity(mainActivity: MainActivity) {
         this.mActivity = mainActivity
+        camConfig = mainActivity.camConfig
     }
 
     fun startTimer() {
@@ -136,4 +138,4 @@
     init {
         gravity = Gravity.CENTER
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/app/grapheneos/camera/ui/CustomGrid.kt b/app/src/main/java/app/grapheneos/camera/ui/CustomGrid.kt
index 3efaa4d..7391f33 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/CustomGrid.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/CustomGrid.kt
@@ -9,7 +9,6 @@
 import androidx.camera.core.AspectRatio
 import app.grapheneos.camera.CamConfig
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 
 class CustomGrid @JvmOverloads constructor(
     context: Context,
@@ -32,6 +31,8 @@
     }
 
     override fun onDraw(canvas: Canvas) {
+        val camConfig = mActivity.camConfig
+
         super.onDraw(canvas)
 
         if (camConfig.gridType == CamConfig.GridType.NONE) {
@@ -94,4 +95,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/app/grapheneos/camera/ui/QRToggle.kt b/app/src/main/java/app/grapheneos/camera/ui/QRToggle.kt
index 16d8db9..5fb09c5 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/QRToggle.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/QRToggle.kt
@@ -3,7 +3,6 @@
 import android.content.Context
 import android.util.AttributeSet
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import com.google.android.material.imageview.ShapeableImageView
 
 class QRToggle @JvmOverloads constructor(
@@ -31,6 +30,7 @@
 
     override fun setSelected(selected: Boolean) {
         super.setSelected(selected)
+        val camConfig = mActivity.camConfig
 
         if (!selected && camConfig.allowedFormats.size == 1) {
             mActivity.showMessage(
@@ -49,4 +49,4 @@
         private const val selectedAlpha = 1f
         private const val deselectedAlpha = 0.3f
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/app/grapheneos/camera/ui/SettingsDialog.kt b/app/src/main/java/app/grapheneos/camera/ui/SettingsDialog.kt
index de94203..319678d 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/SettingsDialog.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/SettingsDialog.kt
@@ -42,13 +42,14 @@
 import app.grapheneos.camera.databinding.SettingsBinding
 import app.grapheneos.camera.ui.activities.CaptureActivity
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import app.grapheneos.camera.ui.activities.MoreSettings
+import app.grapheneos.camera.ui.activities.SecureActivity
 import app.grapheneos.camera.ui.activities.SecureMainActivity
 import app.grapheneos.camera.ui.activities.VideoCaptureActivity
 
 class SettingsDialog(val mActivity: MainActivity) :
     Dialog(mActivity, R.style.Theme_App) {
+    val camConfig = mActivity.camConfig
 
     private val binding: SettingsBinding by lazy { SettingsBinding.inflate(layoutInflater) }
     private var dialog: View
@@ -99,7 +100,7 @@
         moreSettingsButton = binding.moreSettings
         moreSettingsButton.setOnClickListener {
             if (!mActivity.videoCapturer.isRecording) {
-                openMoreSettings()
+                MoreSettings.start(mActivity)
             } else {
                 mActivity.showMessage(getString(R.string.more_settings_unavailable_during_recording))
             }
@@ -726,15 +727,4 @@
 
         videoQualitySpinner.setSelection(titles.indexOf(qt))
     }
-
-    fun openMoreSettings() {
-        val mSIntent = Intent(mActivity, MoreSettings::class.java)
-        mSIntent.putExtra(
-            "show_storage_settings",
-            !(mActivity is SecureMainActivity ||
-                    (mActivity is CaptureActivity &&
-                            mActivity !is VideoCaptureActivity))
-        )
-        mActivity.startActivity(mSIntent)
-    }
 }
diff --git a/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt b/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt
index 4494574..2684ba0 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/activities/MainActivity.kt
@@ -1318,14 +1318,13 @@
         rotateView(settingsDialog.settingsFrame, iconRotation)
     }
 
+    lateinit var camConfig: CamConfig
+
     companion object {
         private const val TAG = "GOCam"
         private const val autoCenterFocusDuration = 2000L
         private val hexArray = "0123456789ABCDEF".toCharArray()
 
-        lateinit var camConfig: CamConfig
-        fun isCamConfigInitialized() = this::camConfig.isInitialized
-
         private const val SWIPE_THRESHOLD = 100
         private const val SWIPE_VELOCITY_THRESHOLD = 100
     }
diff --git a/app/src/main/java/app/grapheneos/camera/ui/activities/MoreSettings.kt b/app/src/main/java/app/grapheneos/camera/ui/activities/MoreSettings.kt
index f58f1a7..115f229 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/activities/MoreSettings.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/activities/MoreSettings.kt
@@ -20,11 +20,11 @@
 import app.grapheneos.camera.NumInputFilter
 import app.grapheneos.camera.R
 import app.grapheneos.camera.databinding.MoreSettingsBinding
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import app.grapheneos.camera.util.storageLocationToUiString
 import com.google.android.material.snackbar.Snackbar
 
 class MoreSettings : AppCompatActivity(), TextView.OnEditorActionListener {
+    private lateinit var camConfig: CamConfig
 
     private lateinit var binding: MoreSettingsBinding
     private lateinit var snackBar: Snackbar
@@ -70,12 +70,20 @@
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+
+        val camConfig = obtainCamConfig(intent)
+        if (camConfig == null) {
+            finish()
+            return
+        }
+        this.camConfig = camConfig
+
         binding = MoreSettingsBinding.inflate(layoutInflater)
         setContentView(binding.root)
         setTitle(R.string.more_settings)
         supportActionBar?.setDisplayHomeAsUpEnabled(true)
 
-        val showStorageSettings = intent.extras?.getBoolean("show_storage_settings") == true
+        val showStorageSettings = intent.getBooleanExtra(INTENT_EXTRA_SHOW_STORAGE_SETTINGS, false)
 
         val sIAPToggle = binding.saveImageAsPreviewToggle
 
@@ -304,4 +312,39 @@
         finish()
         return true
     }
+
+    companion object {
+        private var camConfigId = 0L
+        private var staticCamConfig: CamConfig? = null
+
+        private const val INTENT_EXTRA_CAM_CONFIG_ID = "camConfig_id"
+        private const val INTENT_EXTRA_SHOW_STORAGE_SETTINGS = "show_storage_settings"
+
+        fun start(caller: MainActivity) {
+            Intent(caller, MoreSettings::class.java).let {
+                it.putExtra(INTENT_EXTRA_SHOW_STORAGE_SETTINGS, caller !is SecureActivity)
+                camConfigId += 1
+                it.putExtra(INTENT_EXTRA_CAM_CONFIG_ID, camConfigId)
+                staticCamConfig = caller.camConfig
+
+                caller.startActivity(it)
+            }
+        }
+
+        private fun obtainCamConfig(intent: Intent): CamConfig? {
+            val camConfig = staticCamConfig
+            if (camConfigId != intent.getLongExtra(INTENT_EXTRA_CAM_CONFIG_ID, -1)) {
+                return null
+            }
+            return camConfig
+        }
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+
+        if (isFinishing) {
+            staticCamConfig = null
+        }
+    }
 }
diff --git a/app/src/main/java/app/grapheneos/camera/ui/seekbar/ExposureBar.kt b/app/src/main/java/app/grapheneos/camera/ui/seekbar/ExposureBar.kt
index c3ce481..1b22d4d 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/seekbar/ExposureBar.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/seekbar/ExposureBar.kt
@@ -17,7 +17,6 @@
 import androidx.transition.TransitionManager
 import app.grapheneos.camera.R
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 
 class ExposureBar : AppCompatSeekBar {
     constructor(context: Context) : super(context)
@@ -113,7 +112,7 @@
                 Log.i("progress", progress.toString())
                 Log.i("max", max.toString())
 
-                camConfig.camera?.cameraControl
+                mainActivity.camConfig.camera?.cameraControl
                     ?.setExposureCompensationIndex(progress)
 
                 showPanel()
diff --git a/app/src/main/java/app/grapheneos/camera/ui/seekbar/ZoomBar.kt b/app/src/main/java/app/grapheneos/camera/ui/seekbar/ZoomBar.kt
index 9d1b094..68dc4ce 100644
--- a/app/src/main/java/app/grapheneos/camera/ui/seekbar/ZoomBar.kt
+++ b/app/src/main/java/app/grapheneos/camera/ui/seekbar/ZoomBar.kt
@@ -18,9 +18,9 @@
 import androidx.transition.Fade
 import androidx.transition.Transition
 import androidx.transition.TransitionManager
+import app.grapheneos.camera.CamConfig
 import app.grapheneos.camera.R
 import app.grapheneos.camera.ui.activities.MainActivity
-import app.grapheneos.camera.ui.activities.MainActivity.Companion.camConfig
 import kotlin.math.roundToInt
 
 class ZoomBar : AppCompatSeekBar {
@@ -46,9 +46,11 @@
         .inflate(R.layout.zoom_bar_thumb, null, false)
 
     private lateinit var mainActivity: MainActivity
+    private lateinit var camConfig: CamConfig
 
     fun setMainActivity(mainActivity: MainActivity) {
         this.mainActivity = mainActivity
+        camConfig = mainActivity.camConfig
     }
 
     fun showPanel() {