summaryrefslogtreecommitdiff
path: root/library/main/src/com/android/setupwizardlib/util/ThemeResolver.java
diff options
context:
space:
mode:
Diffstat (limited to 'library/main/src/com/android/setupwizardlib/util/ThemeResolver.java')
-rw-r--r--library/main/src/com/android/setupwizardlib/util/ThemeResolver.java219
1 files changed, 219 insertions, 0 deletions
diff --git a/library/main/src/com/android/setupwizardlib/util/ThemeResolver.java b/library/main/src/com/android/setupwizardlib/util/ThemeResolver.java
new file mode 100644
index 0000000..14fdc85
--- /dev/null
+++ b/library/main/src/com/android/setupwizardlib/util/ThemeResolver.java
@@ -0,0 +1,219 @@
+package com.android.setupwizardlib.util;
+
+import android.app.Activity;
+import android.content.Intent;
+import androidx.annotation.Nullable;
+import androidx.annotation.StyleRes;
+import com.android.setupwizardlib.R;
+
+/**
+ * A resolver to resolve the theme from a string or an activity intent, setting options like the
+ * default theme and the oldest supported theme. Apps can share the resolver across the entire
+ * process by calling {@link #setDefault(ThemeResolver)} in {@link
+ * android.app.Application#onCreate()}. If an app needs more granular sharing of the theme default
+ * values, additional instances of {@link ThemeResolver} can be created using the builder.
+ */
+public class ThemeResolver {
+ @StyleRes private final int defaultTheme;
+ @Nullable private final String oldestSupportedTheme;
+ private final boolean useDayNight;
+
+ @Nullable private static ThemeResolver defaultResolver;
+
+ /**
+ * Sets the default instance used for the whole process. Can be null to reset the default to the
+ * preset one.
+ */
+ public static void setDefault(@Nullable ThemeResolver resolver) {
+ defaultResolver = resolver;
+ }
+
+ /**
+ * Returns the default instance, which can be changed using {@link #setDefault(ThemeResolver)}.
+ */
+ public static ThemeResolver getDefault() {
+ if (defaultResolver == null) {
+ defaultResolver =
+ new ThemeResolver.Builder()
+ .setDefaultTheme(R.style.SuwThemeGlif_DayNight)
+ .setUseDayNight(true)
+ .build();
+ }
+ return defaultResolver;
+ }
+
+ private ThemeResolver(
+ int defaultTheme, @Nullable String oldestSupportedTheme, boolean useDayNight) {
+ this.defaultTheme = defaultTheme;
+ this.oldestSupportedTheme = oldestSupportedTheme;
+ this.useDayNight = useDayNight;
+ }
+
+ /**
+ * Returns the style for the theme specified in the intent extra. If the specified string theme is
+ * older than the oldest supported theme, the default will be returned instead. Note that the
+ * default theme is returned without processing -- it may not be a DayNight theme even if {@link
+ * #useDayNight} is true.
+ */
+ @StyleRes
+ public int resolve(Intent intent) {
+ return resolve(
+ intent.getStringExtra(WizardManagerHelper.EXTRA_THEME),
+ /* suppressDayNight= */ WizardManagerHelper.isSetupWizardIntent(intent));
+ }
+
+ /**
+ * Returns the style for the given string theme. If the specified string theme is older than the
+ * oldest supported theme, the default will be returned instead. Note that the default theme is
+ * returned without processing -- it may not be a DayNight theme even if {@link #useDayNight} is
+ * true.
+ */
+ @StyleRes
+ public int resolve(@Nullable String theme) {
+ return resolve(theme, /* suppressDayNight= */ false);
+ }
+
+ @StyleRes
+ private int resolve(@Nullable String theme, boolean suppressDayNight) {
+ int themeResource =
+ useDayNight && !suppressDayNight ? getDayNightThemeRes(theme) : getThemeRes(theme);
+ if (themeResource == 0) {
+ return defaultTheme;
+ }
+
+ if (oldestSupportedTheme != null && compareThemes(theme, oldestSupportedTheme) < 0) {
+ return defaultTheme;
+ }
+ return themeResource;
+ }
+
+ /** Reads the theme from the intent, and applies the resolved theme to the activity. */
+ public void applyTheme(Activity activity) {
+ activity.setTheme(resolve(activity.getIntent()));
+ }
+
+ /**
+ * Returns the corresponding DayNight theme resource ID for the given string theme. DayNight
+ * themes are themes that will be either light or dark depending on the system setting. For
+ * example, the string {@link WizardManagerHelper#THEME_GLIF_LIGHT} will return
+ * {@code @style/SuwThemeGlif.DayNight}.
+ */
+ @StyleRes
+ private static int getDayNightThemeRes(@Nullable String theme) {
+ if (theme != null) {
+ switch (theme) {
+ case WizardManagerHelper.THEME_GLIF_V3_LIGHT:
+ case WizardManagerHelper.THEME_GLIF_V3:
+ return R.style.SuwThemeGlifV3_DayNight;
+ case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
+ case WizardManagerHelper.THEME_GLIF_V2:
+ return R.style.SuwThemeGlifV2_DayNight;
+ case WizardManagerHelper.THEME_GLIF_LIGHT:
+ case WizardManagerHelper.THEME_GLIF:
+ return R.style.SuwThemeGlif_DayNight;
+ case WizardManagerHelper.THEME_MATERIAL_LIGHT:
+ case WizardManagerHelper.THEME_MATERIAL:
+ return R.style.SuwThemeMaterial_DayNight;
+ default:
+ // fall through
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Returns the theme resource ID for the given string theme. For example, the string {@link
+ * WizardManagerHelper#THEME_GLIF_LIGHT} will return {@code @style/SuwThemeGlif.Light}.
+ */
+ @StyleRes
+ private static int getThemeRes(@Nullable String theme) {
+ if (theme != null) {
+ switch (theme) {
+ case WizardManagerHelper.THEME_GLIF_V3_LIGHT:
+ return R.style.SuwThemeGlifV3_Light;
+ case WizardManagerHelper.THEME_GLIF_V3:
+ return R.style.SuwThemeGlifV3;
+ case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
+ return R.style.SuwThemeGlifV2_Light;
+ case WizardManagerHelper.THEME_GLIF_V2:
+ return R.style.SuwThemeGlifV2;
+ case WizardManagerHelper.THEME_GLIF_LIGHT:
+ return R.style.SuwThemeGlif_Light;
+ case WizardManagerHelper.THEME_GLIF:
+ return R.style.SuwThemeGlif;
+ case WizardManagerHelper.THEME_MATERIAL_LIGHT:
+ return R.style.SuwThemeMaterial_Light;
+ case WizardManagerHelper.THEME_MATERIAL:
+ return R.style.SuwThemeMaterial;
+ default:
+ // fall through
+ }
+ }
+ return 0;
+ }
+
+ /** Compares whether the versions of {@code theme1} and {@code theme2} to check which is newer. */
+ private static int compareThemes(String theme1, String theme2) {
+ return Integer.valueOf(getThemeVersion(theme1)).compareTo(getThemeVersion(theme2));
+ }
+
+ /**
+ * Returns the version of the theme. The absolute number of the theme version is not defined, but
+ * a larger number in the version indicates a newer theme.
+ */
+ private static int getThemeVersion(String theme) {
+ if (theme != null) {
+ switch (theme) {
+ case WizardManagerHelper.THEME_GLIF_V3_LIGHT:
+ case WizardManagerHelper.THEME_GLIF_V3:
+ return 4;
+ case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
+ case WizardManagerHelper.THEME_GLIF_V2:
+ return 3;
+ case WizardManagerHelper.THEME_GLIF_LIGHT:
+ case WizardManagerHelper.THEME_GLIF:
+ return 2;
+ case WizardManagerHelper.THEME_MATERIAL_LIGHT:
+ case WizardManagerHelper.THEME_MATERIAL:
+ return 1;
+ default:
+ // fall through
+ }
+ }
+ return -1;
+ }
+
+ /** Builder class for {@link ThemeResolver}. */
+ public static class Builder {
+ @StyleRes private int defaultTheme = R.style.SuwThemeGlif_DayNight;
+ @Nullable private String oldestSupportedTheme = null;
+ private boolean useDayNight = true;
+
+ public Builder() {}
+
+ public Builder(ThemeResolver themeResolver) {
+ this.defaultTheme = themeResolver.defaultTheme;
+ this.oldestSupportedTheme = themeResolver.oldestSupportedTheme;
+ this.useDayNight = themeResolver.useDayNight;
+ }
+
+ public Builder setDefaultTheme(@StyleRes int defaultTheme) {
+ this.defaultTheme = defaultTheme;
+ return this;
+ }
+
+ public Builder setOldestSupportedTheme(String oldestSupportedTheme) {
+ this.oldestSupportedTheme = oldestSupportedTheme;
+ return this;
+ }
+
+ public Builder setUseDayNight(boolean useDayNight) {
+ this.useDayNight = useDayNight;
+ return this;
+ }
+
+ public ThemeResolver build() {
+ return new ThemeResolver(defaultTheme, oldestSupportedTheme, useDayNight);
+ }
+ }
+}