diff --git a/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java b/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java index 0628192..9230b67 100644 --- a/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java +++ b/library/main/src/com/android/setupwizardlib/util/WizardManagerHelper.java @@ -23,6 +23,7 @@ import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.provider.Settings; +import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; @@ -279,7 +280,25 @@ public class WizardManagerHelper { */ public static @StyleRes int getThemeRes(Intent intent, @StyleRes int defaultTheme) { final String theme = intent.getStringExtra(EXTRA_THEME); - return getThemeRes(theme, defaultTheme); + return getThemeRes(theme, defaultTheme, null); + } + + /** + * Gets the theme style resource defined by this library for the theme specified in the given + * intent. For example, for THEME_GLIF_LIGHT, the theme @style/SuwThemeGlif.Light is returned. + * + * @param intent The intent passed by setup wizard, or one with the theme propagated along using + * {@link #copyWizardManagerExtras(Intent, Intent)}. + * @return The style corresponding to the theme in the given intent, or {@code defaultTheme} if + * 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) + */ + 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); } /** @@ -302,28 +321,91 @@ public class WizardManagerHelper { * given theme is not recognized. */ public static @StyleRes int getThemeRes(String theme, @StyleRes int defaultTheme) { + return getThemeRes(theme, defaultTheme, null); + } + + /** + * 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, + @Nullable String oldestSupportedTheme) { + int returnedTheme = defaultTheme; if (theme != null) { switch (theme) { case THEME_GLIF_V3_LIGHT: - return R.style.SuwThemeGlifV3_Light; + returnedTheme = R.style.SuwThemeGlifV3_Light; + break; case THEME_GLIF_V3: - return R.style.SuwThemeGlifV3; + returnedTheme = R.style.SuwThemeGlifV3; + break; case THEME_GLIF_V2_LIGHT: - return R.style.SuwThemeGlifV2_Light; + returnedTheme = R.style.SuwThemeGlifV2_Light; + break; case THEME_GLIF_V2: - return R.style.SuwThemeGlifV2; + returnedTheme = R.style.SuwThemeGlifV2; + break; case THEME_GLIF_LIGHT: - return R.style.SuwThemeGlif_Light; + returnedTheme = R.style.SuwThemeGlif_Light; + break; case THEME_GLIF: - return R.style.SuwThemeGlif; + returnedTheme = R.style.SuwThemeGlif; + break; case THEME_MATERIAL_LIGHT: - return R.style.SuwThemeMaterial_Light; + returnedTheme = R.style.SuwThemeMaterial_Light; + break; case THEME_MATERIAL: - return R.style.SuwThemeMaterial; + 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; + } + + 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 defaultTheme; + return -1; } } 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 616ccdd..20549f2 100644 --- a/library/test/robotest/src/com/android/setupwizardlib/util/WizardManagerHelperTest.java +++ b/library/test/robotest/src/com/android/setupwizardlib/util/WizardManagerHelperTest.java @@ -161,6 +161,22 @@ public class WizardManagerHelperTest { unexpectedStringThemes.isEmpty()); } + @Test + public void getThemeRes_whenOldestSupportedThemeTakeEffect_shouldReturnDefault() { + Intent intent = new Intent(); + intent.putExtra(WizardManagerHelper.EXTRA_THEME, "material"); + assertEquals(0, + WizardManagerHelper.getThemeRes(intent, 0, WizardManagerHelper.THEME_GLIF_V2)); + } + + @Test + public void getThemeRes_whenOldestSupportedThemeNotTakeEffect_shouldReturnCurrent() { + Intent intent = new Intent(); + intent.putExtra(WizardManagerHelper.EXTRA_THEME, "glif_v3"); + assertEquals(R.style.SuwThemeGlifV3, + WizardManagerHelper.getThemeRes(intent, 0, WizardManagerHelper.THEME_GLIF_V2)); + } + @Test public void testIsLightThemeDefault() { final Intent intent = new Intent();