Add new API windowSplashScreenBehavior for declare splash screen style

Add new API windowSplashScreenBehavior, app can use this API to
declare that this app would prefers to show icon-style splash screen,
and this attribute would takes effect if the launching activity did
not start the activity with SPLASH_SCREEN_STYLE_EMPTY.

Bug: 205907456
Test: atest SplashscreenTests
Change-Id: I576793ec43e704f35ad611c71e250a0e2b080cf1
This commit is contained in:
wilsonshih
2022-01-03 20:38:02 +08:00
parent e7d6aeeb26
commit 6310f4d578
4 changed files with 59 additions and 5 deletions

View File

@@ -1745,6 +1745,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

View File

@@ -2332,6 +2332,17 @@
contrast between the window background and the icon. Note the shape would also be
masking like an icon. -->
<attr name="windowSplashScreenIconBackgroundColor" format="color"/>
<!-- Specify whether this application always wants the icon to be displayed on the splash
screen. -->
<attr name="windowSplashScreenBehavior">
<!-- 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. -->
<enum name="default" value="0" />
<!-- The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_EMPTY -->
<enum name="icon_preferred" value="1" />
</attr>
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->

View File

@@ -3275,6 +3275,7 @@
<public name="toExtendRight" />
<public name="toExtendBottom" />
<public name="tileService" />
<public name="windowSplashScreenBehavior" />
</staging-public-group>
<staging-public-group type="id" first-id="0x01de0000">

View File

@@ -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.
@@ -6590,8 +6611,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
@@ -6601,11 +6637,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
@@ -6615,6 +6654,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();
@@ -6687,13 +6728,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