MainActivity.kt

4.4 KB · raw

1package com.peachpasswords23import android.content.Intent4import android.content.res.Configuration5import android.graphics.Color as AndroidColor6import android.graphics.drawable.ColorDrawable7import android.os.Bundle8import android.view.WindowManager9import androidx.activity.compose.setContent10import androidx.activity.enableEdgeToEdge11import androidx.compose.foundation.isSystemInDarkTheme12import androidx.compose.runtime.collectAsState13import androidx.compose.runtime.getValue14import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen15import androidx.fragment.app.FragmentActivity16import dagger.hilt.android.AndroidEntryPoint17import javax.inject.Inject18import com.peachpasswords.ui.PeachAppNavHost19import com.peachpasswords.ui.components.QaFlags20import com.peachpasswords.ui.onboarding.ONBOARD_KEY21import com.peachpasswords.ui.onboarding.ONBOARD_PREFS22import com.peachpasswords.ui.onboarding.onboardingStartDestination23import com.peachpasswords.ui.theme.ACCENT_COLORS24import com.peachpasswords.ui.theme.DEFAULT_ACCENT25import com.peachpasswords.ui.theme.PeachTheme26import com.peachpasswords.vault.VaultLockTimer27import com.peachpasswords.vault.VaultRepository2829// FragmentActivity (not ComponentActivity) so androidx BiometricPrompt can attach.30@AndroidEntryPoint31class MainActivity : FragmentActivity() {32    @Inject lateinit var vault: VaultRepository33    @Inject lateinit var lockTimer: VaultLockTimer3435    // Every touch/key event resets the idle auto-lock countdown (CF-1).36    override fun onUserInteraction() {37        super.onUserInteraction()38        lockTimer.poke()39    }4041    // launchMode="singleTask" reuses this instance across `adb shell am start`42    // relaunches, so the QA capture-bypass extra (see onCreate) needs to be43    // re-read here too, not just once at process start.44    override fun onNewIntent(intent: Intent) {45        super.onNewIntent(intent)46        setIntent(intent)47        if (BuildConfig.DEBUG) {48            QaFlags.disableSecureCaptureForQa = intent.getBooleanExtra("qa_disable_secure_flag", false)49        }50    }5152    override fun onCreate(savedInstanceState: Bundle?) {53        installSplashScreen()54        super.onCreate(savedInstanceState)5556        // Match the splash/window fill to the resolved theme's --bg so launch57        // never flashes the wrong colour before Compose draws. Resolved from the58        // persisted setting synchronously (system mode reads the device night mode).59        val initialTheme = vault.settings.value.theme60        val initialDark = when (initialTheme) {61            "light" -> false62            "system" -> (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==63                Configuration.UI_MODE_NIGHT_YES64            else -> true65        }66        window.setBackgroundDrawable(67            ColorDrawable(AndroidColor.parseColor(if (initialDark) "#0C0A06" else "#EFEEE9")),68        )6970        enableEdgeToEdge()7172        // Block screenshots / recents thumbnails of the vault in release builds.73        if (!BuildConfig.DEBUG) {74            window.setFlags(75                WindowManager.LayoutParams.FLAG_SECURE,76                WindowManager.LayoutParams.FLAG_SECURE,77            )78        } else {79            // QA-only, debug-build-only: `adb shell am start -n <pkg>/.MainActivity80            // --ez qa_disable_secure_flag true` lets automated visual QA screenshot81            // otherwise-FLAG_SECURE screens (SecureFlagEffect). Off unless asked.82            QaFlags.disableSecureCaptureForQa = intent.getBooleanExtra("qa_disable_secure_flag", false)83        }8485        // Onboarding runs once, only on a fresh install with no vault yet.86        val onboarded = getSharedPreferences(ONBOARD_PREFS, MODE_PRIVATE)87            .getBoolean(ONBOARD_KEY, false)88        val start = onboardingStartDestination(hasVault = vault.hasVault(), onboarded = onboarded)8990        setContent {91            val settings by vault.settings.collectAsState()92            val darkTheme = when (settings.theme) {93                "light" -> false94                "system" -> isSystemInDarkTheme()95                else -> true96            }97            val accent = ACCENT_COLORS[settings.accentColor] ?: DEFAULT_ACCENT98            PeachTheme(99                darkTheme = darkTheme,100                accent = accent,101                reduceMotion = settings.reduceMotion,102            ) {103                PeachAppNavHost(startDestination = start, isUnlocked = vault.isUnlocked)104            }105        }106    }107}