diff --git a/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java b/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java index 29bd70e19..f87f5d0ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/BaseActivity.java @@ -12,10 +12,13 @@ import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityOptionsCompat; import org.thoughtcrime.securesms.logging.Log; +import org.thoughtcrime.securesms.util.ConfigurationUtil; +import org.thoughtcrime.securesms.util.ContextUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.WindowUtil; import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper; @@ -75,17 +78,20 @@ public abstract class BaseActivity extends AppCompatActivity { } @Override - protected void attachBaseContext(Context newBase) { + protected void attachBaseContext(@NonNull Context newBase) { super.attachBaseContext(newBase); - Configuration configuration = new Configuration(); - configuration.uiMode = (configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK) | getDelegate().getLocalNightMode(); + Configuration configuration = new Configuration(newBase.getResources().getConfiguration()); + int appCompatNightMode = getDelegate().getLocalNightMode() != AppCompatDelegate.MODE_NIGHT_UNSPECIFIED ? getDelegate().getLocalNightMode() + : AppCompatDelegate.getDefaultNightMode(); + + configuration.uiMode = (configuration.uiMode & ~Configuration.UI_MODE_NIGHT_MASK) | mapNightModeToConfigurationUiMode(newBase, appCompatNightMode); applyOverrideConfiguration(configuration); } @Override - public void applyOverrideConfiguration(Configuration overrideConfiguration) { + public void applyOverrideConfiguration(@NonNull Configuration overrideConfiguration) { DynamicLanguageContextWrapper.prepareOverrideConfiguration(this, overrideConfiguration); super.applyOverrideConfiguration(overrideConfiguration); } @@ -97,4 +103,13 @@ public abstract class BaseActivity extends AppCompatActivity { public final @NonNull ActionBar requireSupportActionBar() { return Objects.requireNonNull(getSupportActionBar()); } + + private static int mapNightModeToConfigurationUiMode(@NonNull Context context, @AppCompatDelegate.NightMode int appCompatNightMode) { + if (appCompatNightMode == AppCompatDelegate.MODE_NIGHT_YES) { + return Configuration.UI_MODE_NIGHT_YES; + } else if (appCompatNightMode == AppCompatDelegate.MODE_NIGHT_NO) { + return Configuration.UI_MODE_NIGHT_NO; + } + return ConfigurationUtil.getNightModeConfiguration(context.getApplicationContext()); + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/CachedInflater.java b/app/src/main/java/org/thoughtcrime/securesms/util/CachedInflater.java index 78505f71c..c62e4327a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/CachedInflater.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/CachedInflater.java @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.util; import android.content.Context; +import android.content.res.Configuration; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -50,7 +51,7 @@ public class CachedInflater { @MainThread @SuppressWarnings("unchecked") public V inflate(@LayoutRes int layoutRes, @Nullable ViewGroup parent, boolean attachToRoot) { - View cached = ViewCache.getInstance().pull(layoutRes, ContextUtil.getNightModeConfiguration(context)); + View cached = ViewCache.getInstance().pull(layoutRes, context.getResources().getConfiguration()); if (cached != null) { if (parent != null && attachToRoot) { parent.addView(cached); @@ -84,9 +85,9 @@ public class CachedInflater { private final Map> cache = new HashMap<>(); - private long lastClearTime; - - private int nightModeConfiguration; + private long lastClearTime; + private int nightModeConfiguration; + private float fontScale; static ViewCache getInstance() { return INSTANCE; @@ -94,10 +95,14 @@ public class CachedInflater { @MainThread void cacheUntilLimit(@NonNull Context context, @LayoutRes int layoutRes, @Nullable ViewGroup parent, int limit) { - int currentNightModeConfiguration = ContextUtil.getNightModeConfiguration(context); - if (nightModeConfiguration != currentNightModeConfiguration) { + Configuration configuration = context.getResources().getConfiguration(); + int currentNightModeConfiguration = ConfigurationUtil.getNightModeConfiguration(configuration); + float currentFontScale = ConfigurationUtil.getFontScale(configuration); + + if (nightModeConfiguration != currentNightModeConfiguration || fontScale != currentFontScale) { clear(); nightModeConfiguration = currentNightModeConfiguration; + fontScale = currentFontScale; } AsyncLayoutInflater inflater = new AsyncLayoutInflater(context); @@ -125,8 +130,8 @@ public class CachedInflater { } @MainThread - @Nullable View pull(@LayoutRes int layoutRes, int nightModeConfiguration) { - if (this.nightModeConfiguration != nightModeConfiguration) { + @Nullable View pull(@LayoutRes int layoutRes, @NonNull Configuration configuration) { + if (this.nightModeConfiguration != ConfigurationUtil.getNightModeConfiguration(configuration) || this.fontScale != ConfigurationUtil.getFontScale(configuration)) { clear(); return null; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationUtil.java new file mode 100644 index 000000000..bfd8128a0 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationUtil.java @@ -0,0 +1,23 @@ +package org.thoughtcrime.securesms.util; + +import android.content.Context; +import android.content.res.Configuration; + +import androidx.annotation.NonNull; + +public final class ConfigurationUtil { + + private ConfigurationUtil() {} + + public static int getNightModeConfiguration(@NonNull Context context) { + return getNightModeConfiguration(context.getResources().getConfiguration()); + } + + public static int getNightModeConfiguration(@NonNull Configuration configuration) { + return configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; + } + + public static float getFontScale(@NonNull Configuration configuration) { + return configuration.fontScale; + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ContextUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ContextUtil.java index 4277b5036..f89cf738e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ContextUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ContextUtil.java @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.util; import android.content.Context; -import android.content.res.Configuration; import android.graphics.drawable.Drawable; import androidx.annotation.DrawableRes; @@ -17,7 +16,4 @@ public final class ContextUtil { return Objects.requireNonNull(ContextCompat.getDrawable(context, drawable)); } - public static int getNightModeConfiguration(@NonNull Context context) { - return context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/DynamicTheme.java b/app/src/main/java/org/thoughtcrime/securesms/util/DynamicTheme.java index e9fdc7b78..a7bf801a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/DynamicTheme.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/DynamicTheme.java @@ -10,9 +10,12 @@ import androidx.annotation.StyleRes; import androidx.appcompat.app.AppCompatDelegate; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.logging.Log; public class DynamicTheme { + private static final String TAG = Log.tag(DynamicTheme.class); + public static final String DARK = "dark"; public static final String LIGHT = "light"; public static final String SYSTEM = "system"; @@ -24,18 +27,20 @@ public class DynamicTheme { public void onCreate(@NonNull Activity activity) { int previousGlobalConfiguration = globalNightModeConfiguration; - onCreateNightModeConfiguration = ContextUtil.getNightModeConfiguration(activity); + onCreateNightModeConfiguration = ConfigurationUtil.getNightModeConfiguration(activity); globalNightModeConfiguration = onCreateNightModeConfiguration; activity.setTheme(getTheme()); if (previousGlobalConfiguration != globalNightModeConfiguration) { + Log.d(TAG, "Previous night mode has changed previous: " + previousGlobalConfiguration + " now: " + globalNightModeConfiguration); CachedInflater.from(activity).clear(); } } public void onResume(@NonNull Activity activity) { - if (onCreateNightModeConfiguration != ContextUtil.getNightModeConfiguration(activity)) { + if (onCreateNightModeConfiguration != ConfigurationUtil.getNightModeConfiguration(activity)) { + Log.d(TAG, "Create configuration different from current previous: " + onCreateNightModeConfiguration + " now: " + ConfigurationUtil.getNightModeConfiguration(activity)); CachedInflater.from(activity).clear(); } } @@ -52,10 +57,13 @@ public class DynamicTheme { String theme = TextSecurePreferences.getTheme(context); if (theme.equals(SYSTEM)) { + Log.d(TAG, "Setting to follow system expecting: " + ConfigurationUtil.getNightModeConfiguration(context.getApplicationContext())); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); } else if (DynamicTheme.isDarkTheme(context)) { + Log.d(TAG, "Setting to always night"); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { + Log.d(TAG, "Setting to always day"); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); }