ui: no need to manually recreate activities after night change

Since version 1.1.0, setDefaultNightMode now takes care of that. Also,
set the initial mode in a blocking fashion to prevent flashing white.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2023-04-05 16:03:54 +02:00
parent dc1860c74d
commit eae9216fe4
5 changed files with 21 additions and 42 deletions

View File

@ -35,6 +35,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.Locale import java.util.Locale
@ -92,10 +93,19 @@ class Application : android.app.Application() {
toolsInstaller = ToolsInstaller(applicationContext, rootShell) toolsInstaller = ToolsInstaller(applicationContext, rootShell)
preferencesDataStore = PreferenceDataStoreFactory.create { applicationContext.preferencesDataStoreFile("settings") } preferencesDataStore = PreferenceDataStoreFactory.create { applicationContext.preferencesDataStoreFile("settings") }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
coroutineScope.launch { runBlocking {
AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.setDefaultNightMode(if (UserKnobs.darkTheme.first()) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO)
if (UserKnobs.darkTheme.first()) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO)
} }
UserKnobs.darkTheme.onEach {
val newMode = if (it) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
if (AppCompatDelegate.getDefaultNightMode() != newMode) {
AppCompatDelegate.setDefaultNightMode(newMode)
}
}.launchIn(coroutineScope)
} else { } else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
} }

View File

@ -5,6 +5,7 @@
package com.wireguard.android.activity package com.wireguard.android.activity
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.CallbackRegistry import androidx.databinding.CallbackRegistry
import androidx.databinding.CallbackRegistry.NotifierCallback import androidx.databinding.CallbackRegistry.NotifierCallback
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -15,7 +16,7 @@ import kotlinx.coroutines.launch
/** /**
* Base class for activities that need to remember the currently-selected tunnel. * Base class for activities that need to remember the currently-selected tunnel.
*/ */
abstract class BaseActivity : ThemeChangeAwareActivity() { abstract class BaseActivity : AppCompatActivity() {
private val selectionChangeRegistry = SelectionChangeRegistry() private val selectionChangeRegistry = SelectionChangeRegistry()
private var created = false private var created = false
var selectedTunnel: ObservableTunnel? = null var selectedTunnel: ObservableTunnel? = null

View File

@ -8,6 +8,7 @@ import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.commit import androidx.fragment.app.commit
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference import androidx.preference.Preference
@ -24,7 +25,7 @@ import kotlinx.coroutines.withContext
/** /**
* Interface for changing application-global persistent settings. * Interface for changing application-global persistent settings.
*/ */
class SettingsActivity : ThemeChangeAwareActivity() { class SettingsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (supportFragmentManager.findFragmentById(android.R.id.content) == null) { if (supportFragmentManager.findFragmentById(android.R.id.content) == null) {

View File

@ -1,33 +0,0 @@
/*
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.activity
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.lifecycleScope
import com.wireguard.android.util.UserKnobs
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
abstract class ThemeChangeAwareActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
UserKnobs.darkTheme.onEach {
val newMode = if (it) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
if (AppCompatDelegate.getDefaultNightMode() != newMode) {
AppCompatDelegate.setDefaultNightMode(newMode)
recreate()
}
}.launchIn(lifecycleScope)
}
}
}

View File

@ -21,6 +21,7 @@ import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
@ -48,13 +49,14 @@ import com.wireguard.android.util.ErrorMessages
import com.wireguard.android.util.QuantityFormatter import com.wireguard.android.util.QuantityFormatter
import com.wireguard.android.util.TunnelImporter import com.wireguard.android.util.TunnelImporter
import com.wireguard.android.util.UserKnobs import com.wireguard.android.util.UserKnobs
import com.wireguard.android.util.applicationScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
class TvMainActivity : ThemeChangeAwareActivity() { class TvMainActivity : AppCompatActivity() {
private val tunnelFileImportResultLauncher = registerForActivityResult(object : ActivityResultContracts.GetContent() { private val tunnelFileImportResultLauncher = registerForActivityResult(object : ActivityResultContracts.GetContent() {
override fun createIntent(context: Context, input: String): Intent { override fun createIntent(context: Context, input: String): Intent {
val intent = super.createIntent(context, input) val intent = super.createIntent(context, input)
@ -112,11 +114,9 @@ class TvMainActivity : ThemeChangeAwareActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
if (AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_YES) { if (AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_YES) {
/* First set it this way to prevent a white flash. */
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
/* Then update the preference, which triggers the recreation. */ applicationScope.launch {
lifecycleScope.launch {
UserKnobs.setDarkTheme(true) UserKnobs.setDarkTheme(true)
} }
} }