diff --git a/core/api/current.txt b/core/api/current.txt index 08387fc7033dc..84aee66eb1892 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1747,6 +1747,7 @@ package android { field public static final int windowSplashScreenAnimatedIcon = 16844333; // 0x101062d field public static final int windowSplashScreenAnimationDuration = 16844334; // 0x101062e field public static final int windowSplashScreenBackground = 16844332; // 0x101062c + field public static final int windowSplashScreenBehavior; field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f field public static final int windowSplashScreenIconBackgroundColor = 16844336; // 0x1010630 field @Deprecated public static final int windowSplashscreenContent = 16844132; // 0x1010564 diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 090b1c527d15b..3a9cb2e52ce75 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2332,6 +2332,17 @@ contrast between the window background and the icon. Note the shape would also be masking like an icon. --> + + + + + + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index f05137e144d90..cc63fd6146a7d 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3275,6 +3275,7 @@ + diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9532a5c79d5b6..bb33e6ff71111 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -811,6 +811,27 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // How long we wait until giving up transfer splash screen. private static final int TRANSFER_SPLASH_SCREEN_TIMEOUT = 2000; + /** + * The icon is shown when the launching activity sets the splashScreenStyle to + * SPLASH_SCREEN_STYLE_ICON. If the launching activity does not specify any style, + * follow the system behavior. + * + * @see android.R.attr#windowSplashScreenBehavior + */ + private static final int SPLASH_SCREEN_BEHAVIOR_DEFAULT = 0; + /** + * The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_EMPTY. + * + * @see android.R.attr#windowSplashScreenBehavior + */ + private static final int SPLASH_SCREEN_BEHAVIOR_ICON_PREFERRED = 1; + + @IntDef(prefix = {"SPLASH_SCREEN_BEHAVIOR_"}, value = { + SPLASH_SCREEN_BEHAVIOR_DEFAULT, + SPLASH_SCREEN_BEHAVIOR_ICON_PREFERRED + }) + @interface SplashScreenBehavior { } + // TODO: Have a WindowContainer state for tracking exiting/deferred removal. boolean mIsExiting; // Force an app transition to be ran in the case the visibility of the app did not change. @@ -6594,8 +6615,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return null; } + private boolean isIconStylePreferred(int theme) { + if (theme == 0) { + return false; + } + final AttributeCache.Entry ent = AttributeCache.instance().get(packageName, theme, + R.styleable.Window, mWmService.mCurrentUserId); + if (ent != null) { + if (ent.array.hasValue(R.styleable.Window_windowSplashScreenBehavior)) { + return ent.array.getInt(R.styleable.Window_windowSplashScreenBehavior, + SPLASH_SCREEN_BEHAVIOR_DEFAULT) + == SPLASH_SCREEN_BEHAVIOR_ICON_PREFERRED; + } + } + return false; + } private boolean shouldUseEmptySplashScreen(ActivityRecord sourceRecord, boolean startActivity, - ActivityOptions options) { + ActivityOptions options, int resolvedTheme) { if (sourceRecord == null && !startActivity) { // Use empty style if this activity is not top activity. This could happen when adding // a splash screen window to the warm start activity which is re-create because top is @@ -6605,11 +6641,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return true; } } + + // setSplashScreenStyle decide in priority of windowSplashScreenBehavior. if (options != null) { final int optionsStyle = options.getSplashScreenStyle(); if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_EMPTY) { return true; - } else if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_ICON) { + } else if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_ICON + || isIconStylePreferred(resolvedTheme)) { return false; } // Choose the default behavior for Launcher and SystemUI when the SplashScreen style is @@ -6619,6 +6658,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI) { return true; } + } else if (isIconStylePreferred(resolvedTheme)) { + return false; } if (sourceRecord == null) { sourceRecord = searchCandidateLaunchingActivity(); @@ -6691,13 +6732,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } - mSplashScreenStyleEmpty = shouldUseEmptySplashScreen( - sourceRecord, startActivity, startOptions); - final int splashScreenTheme = startActivity ? getSplashscreenTheme(startOptions) : 0; final int resolvedTheme = evaluateStartingWindowTheme(prev, packageName, theme, splashScreenTheme); + mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord, startActivity, + startOptions, resolvedTheme); + final boolean activityCreated = mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(); // If this activity is just created and all activities below are finish, treat this