diff --git a/library/gingerbread/AndroidManifest.xml b/library/gingerbread/AndroidManifest.xml
new file mode 100644
index 0000000..bf7d42f
--- /dev/null
+++ b/library/gingerbread/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/library/grandfathered_lint_checks.txt b/library/grandfathered_lint_checks.txt
new file mode 100644
index 0000000..e69de29
diff --git a/library/main/res/values-night/styles.xml b/library/main/res/values-night/styles.xml
new file mode 100644
index 0000000..912e149
--- /dev/null
+++ b/library/main/res/values-night/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/main/res/values/styles.xml b/library/main/res/values/styles.xml
index 6c813b8..34a917f 100644
--- a/library/main/res/values/styles.xml
+++ b/library/main/res/values/styles.xml
@@ -58,6 +58,12 @@
- @anim/suw_slide_back_out
+
+
+
+
+
+
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);
+ }
+ }
+}
diff --git a/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java b/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java
index c946bb6..2342fa5 100644
--- a/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java
+++ b/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java
@@ -16,6 +16,7 @@
package com.android.setupwizardlib.util;
+import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources.Theme;
@@ -25,9 +26,13 @@ import android.provider.Settings;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.annotation.VisibleForTesting;
-import com.android.setupwizardlib.R;
import java.util.Arrays;
+/**
+ * Helper to interact with Wizard Manager in setup wizard, which should be used when a screen is
+ * shown inside the setup flow. This includes things like parsing extras passed by Wizard Manager,
+ * and invoking Wizard Manager to start the next action.
+ */
public class WizardManagerHelper {
private static final String ACTION_NEXT = "com.android.wizard.NEXT";
@@ -227,7 +232,7 @@ public class WizardManagerHelper {
/**
* Checks the intent whether the extra indicates that the light theme should be used or not. If
* the theme is not specified in the intent, or the theme specified is unknown, the value def will
- * be returned.
+ * be returned. Note that day-night themes are not taken into account by this method.
*
* @param intent The intent used to start the activity, which the theme extra will be read from.
* @param def The default value if the theme is not specified.
@@ -240,7 +245,8 @@ public class WizardManagerHelper {
/**
* Checks whether {@code theme} represents a light or dark theme. If the theme specified is
- * unknown, the value def will be returned.
+ * unknown, the value def will be returned. Note that day-night themes are not taken into account
+ * by this method.
*
* @param theme The theme as specified from an intent sent from setup wizard.
* @param def The default value if the theme is not known.
@@ -273,10 +279,16 @@ public class WizardManagerHelper {
* @return The style corresponding to the theme in the given intent, or {@code defaultTheme} if
* the given theme is not recognized.
* @see #getThemeRes(String, int)
+ * @deprecated it is recommended to use {@link ThemeResolver} which allows setting the default
+ * theme in one place and applying it to multiple screens.
*/
+ @Deprecated
public static @StyleRes int getThemeRes(Intent intent, @StyleRes int defaultTheme) {
- final String theme = intent.getStringExtra(EXTRA_THEME);
- return getThemeRes(theme, defaultTheme, null);
+ return new ThemeResolver.Builder(ThemeResolver.getDefault())
+ .setDefaultTheme(defaultTheme)
+ .setUseDayNight(false)
+ .build()
+ .resolve(intent);
}
/**
@@ -289,34 +301,18 @@ public class WizardManagerHelper {
* the given theme is not recognized. Return the {@code defaultTheme} if the specified theme
* is older than the oldest supported one.
* @see #getThemeRes(String, int)
+ * @deprecated it is recommended to use {@link ThemeResolver} which allows setting the default
+ * theme and oldest supported theme in one place and applying it to multiple screens.
*/
+ @Deprecated
public static @StyleRes int getThemeRes(
Intent intent, @StyleRes int defaultTheme, @Nullable String oldestSupportedTheme) {
- final String theme = intent.getStringExtra(EXTRA_THEME);
- return getThemeRes(theme, defaultTheme, oldestSupportedTheme);
- }
-
- /**
- * Gets the theme style resource defined by this library for the given theme name. For example,
- * for THEME_GLIF_LIGHT, the theme @style/SuwThemeGlif.Light is returned.
- *
- *
If you require extra theme attributes but want to ensure forward compatibility with new
- * themes added here, consider overriding {@link android.app.Activity#onApplyThemeResource} in
- * your activity and call {@link Theme#applyStyle(int, boolean)} using your theme overlay.
- *
- *
{@code
- * protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
- * super.onApplyThemeResource(theme, resid, first);
- * theme.applyStyle(R.style.MyThemeOverlay, true);
- * }
- * }
- *
- * @param theme The string representation of the theme.
- * @return The style corresponding to the given {@code theme}, or {@code defaultTheme} if the
- * given theme is not recognized.
- */
- public static @StyleRes int getThemeRes(String theme, @StyleRes int defaultTheme) {
- return getThemeRes(theme, defaultTheme, null);
+ return new ThemeResolver.Builder(ThemeResolver.getDefault())
+ .setDefaultTheme(defaultTheme)
+ .setUseDayNight(false)
+ .setOldestSupportedTheme(oldestSupportedTheme)
+ .build()
+ .resolve(intent);
}
/**
@@ -337,70 +333,68 @@ public class WizardManagerHelper {
* @param theme The string representation of the theme.
* @return The style corresponding to the given {@code theme}, or {@code defaultTheme} if the
* given theme is not recognized.
+ * @deprecated it is recommended to use {@link ThemeResolver} which allows setting the default
+ * theme in one place and applying it to multiple screens.
*/
+ @Deprecated
public static @StyleRes int getThemeRes(
String theme, @StyleRes int defaultTheme, @Nullable String oldestSupportedTheme) {
- int returnedTheme = defaultTheme;
- if (theme != null) {
- switch (theme) {
- case THEME_GLIF_V3_LIGHT:
- returnedTheme = R.style.SuwThemeGlifV3_Light;
- break;
- case THEME_GLIF_V3:
- returnedTheme = R.style.SuwThemeGlifV3;
- break;
- case THEME_GLIF_V2_LIGHT:
- returnedTheme = R.style.SuwThemeGlifV2_Light;
- break;
- case THEME_GLIF_V2:
- returnedTheme = R.style.SuwThemeGlifV2;
- break;
- case THEME_GLIF_LIGHT:
- returnedTheme = R.style.SuwThemeGlif_Light;
- break;
- case THEME_GLIF:
- returnedTheme = R.style.SuwThemeGlif;
- break;
- case THEME_MATERIAL_LIGHT:
- returnedTheme = R.style.SuwThemeMaterial_Light;
- break;
- case THEME_MATERIAL:
- returnedTheme = R.style.SuwThemeMaterial;
- break;
- default:
- // fall through
- }
-
- // b/79540471 Return the default theme if the specified theme
- // is older than the oldest supported one.
- if (oldestSupportedTheme != null
- && (getThemeVersion(theme) < getThemeVersion(oldestSupportedTheme))) {
- returnedTheme = defaultTheme;
- }
- }
-
- return returnedTheme;
+ return new ThemeResolver.Builder(ThemeResolver.getDefault())
+ .setDefaultTheme(defaultTheme)
+ .setUseDayNight(false)
+ .setOldestSupportedTheme(oldestSupportedTheme)
+ .build()
+ .resolve(theme);
}
- private static int getThemeVersion(String theme) {
- if (theme != null) {
- switch (theme) {
- case THEME_GLIF_V3_LIGHT:
- case THEME_GLIF_V3:
- return 4;
- case THEME_GLIF_V2_LIGHT:
- case THEME_GLIF_V2:
- return 3;
- case THEME_GLIF_LIGHT:
- case THEME_GLIF:
- return 2;
- case THEME_MATERIAL_LIGHT:
- case THEME_MATERIAL:
- return 1;
- default:
- // fall through
- }
- }
- return -1;
+ /**
+ * Gets the theme style resource defined by this library for the given theme name. For example,
+ * for THEME_GLIF_LIGHT, the theme @style/SuwThemeGlif.Light is returned.
+ *
+ * If you require extra theme attributes but want to ensure forward compatibility with new
+ * themes added here, consider overriding {@link android.app.Activity#onApplyThemeResource} in
+ * your activity and call {@link Theme#applyStyle(int, boolean)} using your theme overlay.
+ *
+ *
{@code
+ * protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
+ * super.onApplyThemeResource(theme, resid, first);
+ * theme.applyStyle(R.style.MyThemeOverlay, true);
+ * }
+ * }
+ *
+ * @param theme The string representation of the theme.
+ * @return The style corresponding to the given {@code theme}, or {@code defaultTheme} if the
+ * given theme is not recognized.
+ * @deprecated it is recommended to use {@link ThemeResolver} which allows setting the default
+ * theme in one place and applying it to multiple screens.
+ */
+ @Deprecated
+ public static @StyleRes int getThemeRes(@Nullable String theme, @StyleRes int defaultTheme) {
+ return new ThemeResolver.Builder(ThemeResolver.getDefault())
+ .setDefaultTheme(defaultTheme)
+ .setUseDayNight(false)
+ .build()
+ .resolve(theme);
+ }
+
+ /**
+ * Reads the theme from the intent, and applies the theme to the activity as resolved by {@link
+ * ThemeResolver#getDefault()}.
+ *
+ * If you require extra theme attributes, consider overriding {@link
+ * android.app.Activity#onApplyThemeResource} in your activity and call {@link
+ * Theme#applyStyle(int, boolean)} using your theme overlay.
+ *
+ *
{@code
+ * protected void onApplyThemeResource(Theme theme, int resid, boolean first) {
+ * super.onApplyThemeResource(theme, resid, first);
+ * theme.applyStyle(R.style.MyThemeOverlay, true);
+ * }
+ * }
+ *
+ * @param activity the activity to get the intent from and apply the resulting theme to.
+ */
+ public static void applyTheme(Activity activity) {
+ ThemeResolver.getDefault().applyTheme(activity);
}
}
diff --git a/library/platform/AndroidManifest.xml b/library/platform/AndroidManifest.xml
new file mode 100644
index 0000000..9aa24dc
--- /dev/null
+++ b/library/platform/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/library/test/robotest/src/com/android/setupwizardlib/util/ThemeResolverTest.java b/library/test/robotest/src/com/android/setupwizardlib/util/ThemeResolverTest.java
new file mode 100644
index 0000000..33ea6ad
--- /dev/null
+++ b/library/test/robotest/src/com/android/setupwizardlib/util/ThemeResolverTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.setupwizardlib.util;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Activity;
+import android.content.Intent;
+import androidx.annotation.StyleRes;
+import com.android.setupwizardlib.R;
+import com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+@RunWith(SuwLibRobolectricTestRunner.class)
+@Config(sdk = Config.NEWEST_SDK)
+public class ThemeResolverTest {
+
+ @After
+ public void resetDefaultThemeResolver() {
+ ThemeResolver.setDefault(null);
+ }
+
+ @Test
+ public void resolve_nonDayNight_shouldReturnCorrespondingTheme() {
+ @StyleRes int defaultTheme = 12345;
+ ThemeResolver themeResolver =
+ new ThemeResolver.Builder().setDefaultTheme(defaultTheme).setUseDayNight(false).build();
+ assertThat(themeResolver.resolve("material")).isEqualTo(R.style.SuwThemeMaterial);
+ assertThat(themeResolver.resolve("material_light")).isEqualTo(R.style.SuwThemeMaterial_Light);
+ assertThat(themeResolver.resolve("glif")).isEqualTo(R.style.SuwThemeGlif);
+ assertThat(themeResolver.resolve("glif_light")).isEqualTo(R.style.SuwThemeGlif_Light);
+ assertThat(themeResolver.resolve("glif_v2")).isEqualTo(R.style.SuwThemeGlifV2);
+ assertThat(themeResolver.resolve("glif_v2_light")).isEqualTo(R.style.SuwThemeGlifV2_Light);
+ assertThat(themeResolver.resolve("glif_v3")).isEqualTo(R.style.SuwThemeGlifV3);
+ assertThat(themeResolver.resolve("glif_v3_light")).isEqualTo(R.style.SuwThemeGlifV3_Light);
+ assertThat(themeResolver.resolve("unknown_theme")).isEqualTo(defaultTheme);
+ }
+
+ @Test
+ public void resolve_dayNight_shouldReturnDayNightTheme() {
+ @StyleRes int defaultTheme = 12345;
+ ThemeResolver themeResolver = new ThemeResolver.Builder().setDefaultTheme(defaultTheme).build();
+ assertThat(themeResolver.resolve("material")).isEqualTo(R.style.SuwThemeMaterial_DayNight);
+ assertThat(themeResolver.resolve("material_light"))
+ .isEqualTo(R.style.SuwThemeMaterial_DayNight);
+ assertThat(themeResolver.resolve("glif")).isEqualTo(R.style.SuwThemeGlif_DayNight);
+ assertThat(themeResolver.resolve("glif_light")).isEqualTo(R.style.SuwThemeGlif_DayNight);
+ assertThat(themeResolver.resolve("glif_v2")).isEqualTo(R.style.SuwThemeGlifV2_DayNight);
+ assertThat(themeResolver.resolve("glif_v2_light")).isEqualTo(R.style.SuwThemeGlifV2_DayNight);
+ assertThat(themeResolver.resolve("glif_v3")).isEqualTo(R.style.SuwThemeGlifV3_DayNight);
+ assertThat(themeResolver.resolve("glif_v3_light")).isEqualTo(R.style.SuwThemeGlifV3_DayNight);
+ assertThat(themeResolver.resolve("unknown_theme")).isEqualTo(defaultTheme);
+ }
+
+ @Test
+ public void resolve_newerThanOldestSupportedTheme_shouldReturnSpecifiedTheme() {
+ ThemeResolver themeResolver =
+ new ThemeResolver.Builder()
+ .setOldestSupportedTheme(WizardManagerHelper.THEME_GLIF_V2)
+ .build();
+ assertThat(themeResolver.resolve("glif_v2")).isEqualTo(R.style.SuwThemeGlifV2_DayNight);
+ assertThat(themeResolver.resolve("glif_v2_light")).isEqualTo(R.style.SuwThemeGlifV2_DayNight);
+ assertThat(themeResolver.resolve("glif_v3")).isEqualTo(R.style.SuwThemeGlifV3_DayNight);
+ assertThat(themeResolver.resolve("glif_v3_light")).isEqualTo(R.style.SuwThemeGlifV3_DayNight);
+ }
+
+ @Test
+ public void resolve_olderThanOldestSupportedTheme_shouldReturnDefault() {
+ @StyleRes int defaultTheme = 12345;
+ ThemeResolver themeResolver =
+ new ThemeResolver.Builder()
+ .setDefaultTheme(defaultTheme)
+ .setOldestSupportedTheme(WizardManagerHelper.THEME_GLIF_V2)
+ .build();
+ assertThat(themeResolver.resolve("material")).isEqualTo(defaultTheme);
+ assertThat(themeResolver.resolve("material_light")).isEqualTo(defaultTheme);
+ assertThat(themeResolver.resolve("glif")).isEqualTo(defaultTheme);
+ assertThat(themeResolver.resolve("glif_light")).isEqualTo(defaultTheme);
+ }
+
+ @Test
+ public void resolve_intentTheme_shouldReturnCorrespondingTheme() {
+ @StyleRes int defaultTheme = 12345;
+ ThemeResolver themeResolver =
+ new ThemeResolver.Builder().setDefaultTheme(defaultTheme).setUseDayNight(false).build();
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "material")))
+ .isEqualTo(R.style.SuwThemeMaterial);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "material_light")))
+ .isEqualTo(R.style.SuwThemeMaterial_Light);
+ assertThat(
+ themeResolver.resolve(new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "glif")))
+ .isEqualTo(R.style.SuwThemeGlif);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "glif_light")))
+ .isEqualTo(R.style.SuwThemeGlif_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v2")))
+ .isEqualTo(R.style.SuwThemeGlifV2);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v2_light")))
+ .isEqualTo(R.style.SuwThemeGlifV2_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v3")))
+ .isEqualTo(R.style.SuwThemeGlifV3);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v3_light")))
+ .isEqualTo(R.style.SuwThemeGlifV3_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent().putExtra(WizardManagerHelper.EXTRA_THEME, "unknown_theme")))
+ .isEqualTo(defaultTheme);
+ }
+
+ @Test
+ public void resolve_suwIntent_shouldForceNonDayNightTheme() {
+ @StyleRes int defaultTheme = 12345;
+ ThemeResolver themeResolver =
+ new ThemeResolver.Builder().setDefaultTheme(defaultTheme).setUseDayNight(true).build();
+ Intent originalIntent = new Intent().putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent).putExtra(WizardManagerHelper.EXTRA_THEME, "material")))
+ .isEqualTo(R.style.SuwThemeMaterial);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent)
+ .putExtra(WizardManagerHelper.EXTRA_THEME, "material_light")))
+ .isEqualTo(R.style.SuwThemeMaterial_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent).putExtra(WizardManagerHelper.EXTRA_THEME, "glif")))
+ .isEqualTo(R.style.SuwThemeGlif);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent).putExtra(WizardManagerHelper.EXTRA_THEME, "glif_light")))
+ .isEqualTo(R.style.SuwThemeGlif_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent).putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v2")))
+ .isEqualTo(R.style.SuwThemeGlifV2);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent)
+ .putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v2_light")))
+ .isEqualTo(R.style.SuwThemeGlifV2_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent).putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v3")))
+ .isEqualTo(R.style.SuwThemeGlifV3);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent)
+ .putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v3_light")))
+ .isEqualTo(R.style.SuwThemeGlifV3_Light);
+ assertThat(
+ themeResolver.resolve(
+ new Intent(originalIntent)
+ .putExtra(WizardManagerHelper.EXTRA_THEME, "unknown_theme")))
+ .isEqualTo(defaultTheme);
+ }
+
+ @Test
+ public void applyTheme_glifV3_shouldSetActivityThemeToGlifV3() {
+ @StyleRes int defaultTheme = 12345;
+ ThemeResolver themeResolver =
+ new ThemeResolver.Builder().setUseDayNight(false).setDefaultTheme(defaultTheme).build();
+
+ Activity activity =
+ Robolectric.buildActivity(
+ Activity.class,
+ new Intent()
+ .putExtra(WizardManagerHelper.EXTRA_THEME, WizardManagerHelper.THEME_GLIF_V3))
+ .setup()
+ .get();
+
+ themeResolver.applyTheme(activity);
+
+ assertThat(shadowOf(activity).callGetThemeResId()).isEqualTo(R.style.SuwThemeGlifV3);
+ }
+
+ @Test
+ public void setDefault_shouldSetDefaultResolver() {
+ ThemeResolver themeResolver = new ThemeResolver.Builder().setUseDayNight(false).build();
+
+ ThemeResolver.setDefault(themeResolver);
+ assertThat(ThemeResolver.getDefault()).isSameAs(themeResolver);
+ }
+}
diff --git a/library/test/robotest/src/com/android/setupwizardlib/util/WizardManagerHelperTest.java b/library/test/robotest/src/com/android/setupwizardlib/util/WizardManagerHelperTest.java
index 5259f6a..0420f97 100644
--- a/library/test/robotest/src/com/android/setupwizardlib/util/WizardManagerHelperTest.java
+++ b/library/test/robotest/src/com/android/setupwizardlib/util/WizardManagerHelperTest.java
@@ -16,10 +16,12 @@
package com.android.setupwizardlib.util;
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.robolectric.RuntimeEnvironment.application;
+import static org.robolectric.Shadows.shadowOf;
import android.annotation.TargetApi;
import android.app.Activity;
@@ -37,6 +39,7 @@ import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
@RunWith(SuwLibRobolectricTestRunner.class)
@@ -345,4 +348,20 @@ public class WizardManagerHelperTest {
Settings.Secure.putInt(application.getContentResolver(), Secure.DEVICE_PROVISIONED, 0);
assertFalse(WizardManagerHelper.isDeviceProvisioned(application));
}
+
+ @Test
+ public void applyTheme_glifDayNight_shouldApplyThemeToActivity() {
+ Activity activity =
+ Robolectric.buildActivity(
+ Activity.class,
+ new Intent()
+ .putExtra(
+ WizardManagerHelper.EXTRA_THEME, WizardManagerHelper.THEME_GLIF_LIGHT))
+ .setup()
+ .get();
+
+ WizardManagerHelper.applyTheme(activity);
+
+ assertThat(shadowOf(activity).callGetThemeResId()).isEqualTo(R.style.SuwThemeGlif_DayNight);
+ }
}