Loading core/java/android/app/Activity.java +9 −12 Original line number Diff line number Diff line Loading @@ -970,8 +970,7 @@ public class Activity extends ContextThemeWrapper private UiTranslationController mUiTranslationController; private SplashScreen mSplashScreen; /** @hide */ SplashScreenView mSplashScreenView; private SplashScreenView mSplashScreenView; private final WindowControllerCallback mWindowControllerCallback = new WindowControllerCallback() { Loading Loading @@ -1631,16 +1630,14 @@ public class Activity extends ContextThemeWrapper } } /** * Clear the splash screen view if exist. * @hide */ public void detachSplashScreenView() { synchronized (this) { if (mSplashScreenView != null) { mSplashScreenView = null; } /** @hide */ public void setSplashScreenView(SplashScreenView v) { mSplashScreenView = v; } /** @hide */ SplashScreenView getSplashScreenView() { return mSplashScreenView; } /** Loading core/java/android/app/ActivityThread.java +8 −10 Original line number Diff line number Diff line Loading @@ -4051,10 +4051,7 @@ public final class ActivityThread extends ClientTransactionHandler final SplashScreenView.Builder builder = new SplashScreenView.Builder(r.activity); final SplashScreenView view = builder.createFromParcel(parcelable).build(); decorView.addView(view); view.cacheRootWindow(r.window); view.makeSystemUIColorsTransparent(); r.activity.mSplashScreenView = view; view.attachHostActivity(r.activity); view.attachHostActivityAndSetSystemUIColors(r.activity, r.window); view.requestLayout(); // Ensure splash screen view is shown before remove the splash screen window. final ViewRootImpl impl = decorView.getViewRootImpl(); Loading Loading @@ -4096,12 +4093,13 @@ public final class ActivityThread extends ClientTransactionHandler @Override public void handOverSplashScreenView(@NonNull ActivityClientRecord r) { if (r.activity.mSplashScreenView != null) { final SplashScreenView v = r.activity.getSplashScreenView(); if (v == null) { return; } synchronized (this) { if (mSplashScreenGlobal != null) { mSplashScreenGlobal.dispatchOnExitAnimation(r.token, r.activity.mSplashScreenView); } mSplashScreenGlobal.dispatchOnExitAnimation(r.token, v); } } } Loading core/java/android/view/Window.java +5 −0 Original line number Diff line number Diff line Loading @@ -1354,6 +1354,11 @@ public abstract class Window { public void setDecorFitsSystemWindows(boolean decorFitsSystemWindows) { } /** @hide */ public boolean decorFitsSystemWindows() { return false; } /** * Specify custom window attributes. <strong>PLEASE NOTE:</strong> the * layout params you give here should generally be from values previously Loading core/java/android/window/SplashScreenView.java +57 −34 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package android.window; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import android.annotation.ColorInt; import android.annotation.NonNull; Loading @@ -40,11 +42,13 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowInsetsController; import android.view.WindowManager; import android.widget.FrameLayout; import com.android.internal.R; import com.android.internal.policy.DecorView; import com.android.internal.util.ContrastColorUtil; import java.time.Duration; import java.time.Instant; Loading @@ -69,6 +73,12 @@ public final class SplashScreenView extends FrameLayout { private static final String TAG = SplashScreenView.class.getSimpleName(); private static final boolean DEBUG = false; private static final int LIGHT_BARS_MASK = WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; private static final int WINDOW_FLAG_MASK = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS | FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS; private boolean mNotCopyable; private boolean mRevealAnimationSupported = true; private int mInitBackgroundColor; Loading @@ -84,10 +94,14 @@ public final class SplashScreenView extends FrameLayout { private Activity mHostActivity; // cache original window and status private Window mWindow; private boolean mDrawBarBackground; private int mAppWindowFlags; private int mStatusBarColor; private int mNavigationBarColor; private int mSystemBarsAppearance; private boolean mHasRemoved; private boolean mNavigationContrastEnforced; private boolean mStatusContrastEnforced; private boolean mDecorFitsSystemWindows; /** * Internal builder to create a SplashScreenView object. Loading Loading @@ -347,54 +361,63 @@ public final class SplashScreenView extends FrameLayout { mWindow = null; } if (mHostActivity != null) { mHostActivity.detachSplashScreenView(); mHostActivity.setSplashScreenView(null); mHostActivity = null; } mHasRemoved = true; } /** * Called when this view is attached to an activity. * Called when this view is attached to an activity. This also makes SystemUI colors * transparent so the content of splash screen view can draw fully. * @hide */ public void attachHostActivity(Activity activity) { public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) { activity.setSplashScreenView(this); mHostActivity = activity; } /** * Cache the root window. * @hide */ public void cacheRootWindow(Window window) { mWindow = window; final WindowManager.LayoutParams attr = window.getAttributes(); mAppWindowFlags = attr.flags; mStatusBarColor = window.getStatusBarColor(); mNavigationBarColor = window.getNavigationBarColor(); mSystemBarsAppearance = window.getInsetsController().getSystemBarsAppearance(); mNavigationContrastEnforced = window.isNavigationBarContrastEnforced(); mStatusContrastEnforced = window.isStatusBarContrastEnforced(); mDecorFitsSystemWindows = window.decorFitsSystemWindows(); applySystemBarsContrastColor(window.getInsetsController(), mInitBackgroundColor); // Let app draw the background of bars. window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); // Use specified bar colors instead of window background. window.clearFlags(FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION); window.setStatusBarColor(Color.TRANSPARENT); window.setNavigationBarColor(Color.TRANSPARENT); window.setDecorFitsSystemWindows(false); window.setStatusBarContrastEnforced(false); window.setNavigationBarContrastEnforced(false); } /** Called when this view is removed from the host activity. */ private void restoreSystemUIColors() { mWindow.setFlags(mAppWindowFlags, WINDOW_FLAG_MASK); mWindow.setStatusBarColor(mStatusBarColor); mWindow.setNavigationBarColor(mNavigationBarColor); mWindow.getInsetsController().setSystemBarsAppearance(mSystemBarsAppearance, LIGHT_BARS_MASK); mWindow.setDecorFitsSystemWindows(mDecorFitsSystemWindows); mWindow.setStatusBarContrastEnforced(mStatusContrastEnforced); mWindow.setNavigationBarContrastEnforced(mNavigationContrastEnforced); } /** * Called after SplashScreenView has added on the root window. * Makes the icon color of system bars contrast. * @hide */ public void makeSystemUIColorsTransparent() { if (mWindow != null) { final WindowManager.LayoutParams attr = mWindow.getAttributes(); mDrawBarBackground = (attr.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; mWindow.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); mStatusBarColor = mWindow.getStatusBarColor(); mNavigationBarColor = mWindow.getNavigationBarDividerColor(); mWindow.setStatusBarColor(Color.TRANSPARENT); mWindow.setNavigationBarColor(Color.TRANSPARENT); } setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } private void restoreSystemUIColors() { if (mWindow != null) { if (!mDrawBarBackground) { mWindow.clearFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); } mWindow.setStatusBarColor(mStatusBarColor); mWindow.setNavigationBarColor(mNavigationBarColor); } public static void applySystemBarsContrastColor(WindowInsetsController windowInsetsController, int backgroundColor) { final int lightBarAppearance = ContrastColorUtil.isColorLight(backgroundColor) ? LIGHT_BARS_MASK : 0; windowInsetsController.setSystemBarsAppearance(lightBarAppearance, LIGHT_BARS_MASK); } /** Loading core/java/com/android/internal/policy/PhoneWindow.java +5 −0 Original line number Diff line number Diff line Loading @@ -3931,6 +3931,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { applyDecorFitsSystemWindows(); } @Override public boolean decorFitsSystemWindows() { return mDecorFitsSystemWindows; } private void applyDecorFitsSystemWindows() { ViewRootImpl impl = getViewRootImplOrNull(); if (impl != null) { Loading Loading
core/java/android/app/Activity.java +9 −12 Original line number Diff line number Diff line Loading @@ -970,8 +970,7 @@ public class Activity extends ContextThemeWrapper private UiTranslationController mUiTranslationController; private SplashScreen mSplashScreen; /** @hide */ SplashScreenView mSplashScreenView; private SplashScreenView mSplashScreenView; private final WindowControllerCallback mWindowControllerCallback = new WindowControllerCallback() { Loading Loading @@ -1631,16 +1630,14 @@ public class Activity extends ContextThemeWrapper } } /** * Clear the splash screen view if exist. * @hide */ public void detachSplashScreenView() { synchronized (this) { if (mSplashScreenView != null) { mSplashScreenView = null; } /** @hide */ public void setSplashScreenView(SplashScreenView v) { mSplashScreenView = v; } /** @hide */ SplashScreenView getSplashScreenView() { return mSplashScreenView; } /** Loading
core/java/android/app/ActivityThread.java +8 −10 Original line number Diff line number Diff line Loading @@ -4051,10 +4051,7 @@ public final class ActivityThread extends ClientTransactionHandler final SplashScreenView.Builder builder = new SplashScreenView.Builder(r.activity); final SplashScreenView view = builder.createFromParcel(parcelable).build(); decorView.addView(view); view.cacheRootWindow(r.window); view.makeSystemUIColorsTransparent(); r.activity.mSplashScreenView = view; view.attachHostActivity(r.activity); view.attachHostActivityAndSetSystemUIColors(r.activity, r.window); view.requestLayout(); // Ensure splash screen view is shown before remove the splash screen window. final ViewRootImpl impl = decorView.getViewRootImpl(); Loading Loading @@ -4096,12 +4093,13 @@ public final class ActivityThread extends ClientTransactionHandler @Override public void handOverSplashScreenView(@NonNull ActivityClientRecord r) { if (r.activity.mSplashScreenView != null) { final SplashScreenView v = r.activity.getSplashScreenView(); if (v == null) { return; } synchronized (this) { if (mSplashScreenGlobal != null) { mSplashScreenGlobal.dispatchOnExitAnimation(r.token, r.activity.mSplashScreenView); } mSplashScreenGlobal.dispatchOnExitAnimation(r.token, v); } } } Loading
core/java/android/view/Window.java +5 −0 Original line number Diff line number Diff line Loading @@ -1354,6 +1354,11 @@ public abstract class Window { public void setDecorFitsSystemWindows(boolean decorFitsSystemWindows) { } /** @hide */ public boolean decorFitsSystemWindows() { return false; } /** * Specify custom window attributes. <strong>PLEASE NOTE:</strong> the * layout params you give here should generally be from values previously Loading
core/java/android/window/SplashScreenView.java +57 −34 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package android.window; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import android.annotation.ColorInt; import android.annotation.NonNull; Loading @@ -40,11 +42,13 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowInsetsController; import android.view.WindowManager; import android.widget.FrameLayout; import com.android.internal.R; import com.android.internal.policy.DecorView; import com.android.internal.util.ContrastColorUtil; import java.time.Duration; import java.time.Instant; Loading @@ -69,6 +73,12 @@ public final class SplashScreenView extends FrameLayout { private static final String TAG = SplashScreenView.class.getSimpleName(); private static final boolean DEBUG = false; private static final int LIGHT_BARS_MASK = WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; private static final int WINDOW_FLAG_MASK = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS | FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS; private boolean mNotCopyable; private boolean mRevealAnimationSupported = true; private int mInitBackgroundColor; Loading @@ -84,10 +94,14 @@ public final class SplashScreenView extends FrameLayout { private Activity mHostActivity; // cache original window and status private Window mWindow; private boolean mDrawBarBackground; private int mAppWindowFlags; private int mStatusBarColor; private int mNavigationBarColor; private int mSystemBarsAppearance; private boolean mHasRemoved; private boolean mNavigationContrastEnforced; private boolean mStatusContrastEnforced; private boolean mDecorFitsSystemWindows; /** * Internal builder to create a SplashScreenView object. Loading Loading @@ -347,54 +361,63 @@ public final class SplashScreenView extends FrameLayout { mWindow = null; } if (mHostActivity != null) { mHostActivity.detachSplashScreenView(); mHostActivity.setSplashScreenView(null); mHostActivity = null; } mHasRemoved = true; } /** * Called when this view is attached to an activity. * Called when this view is attached to an activity. This also makes SystemUI colors * transparent so the content of splash screen view can draw fully. * @hide */ public void attachHostActivity(Activity activity) { public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) { activity.setSplashScreenView(this); mHostActivity = activity; } /** * Cache the root window. * @hide */ public void cacheRootWindow(Window window) { mWindow = window; final WindowManager.LayoutParams attr = window.getAttributes(); mAppWindowFlags = attr.flags; mStatusBarColor = window.getStatusBarColor(); mNavigationBarColor = window.getNavigationBarColor(); mSystemBarsAppearance = window.getInsetsController().getSystemBarsAppearance(); mNavigationContrastEnforced = window.isNavigationBarContrastEnforced(); mStatusContrastEnforced = window.isStatusBarContrastEnforced(); mDecorFitsSystemWindows = window.decorFitsSystemWindows(); applySystemBarsContrastColor(window.getInsetsController(), mInitBackgroundColor); // Let app draw the background of bars. window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); // Use specified bar colors instead of window background. window.clearFlags(FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION); window.setStatusBarColor(Color.TRANSPARENT); window.setNavigationBarColor(Color.TRANSPARENT); window.setDecorFitsSystemWindows(false); window.setStatusBarContrastEnforced(false); window.setNavigationBarContrastEnforced(false); } /** Called when this view is removed from the host activity. */ private void restoreSystemUIColors() { mWindow.setFlags(mAppWindowFlags, WINDOW_FLAG_MASK); mWindow.setStatusBarColor(mStatusBarColor); mWindow.setNavigationBarColor(mNavigationBarColor); mWindow.getInsetsController().setSystemBarsAppearance(mSystemBarsAppearance, LIGHT_BARS_MASK); mWindow.setDecorFitsSystemWindows(mDecorFitsSystemWindows); mWindow.setStatusBarContrastEnforced(mStatusContrastEnforced); mWindow.setNavigationBarContrastEnforced(mNavigationContrastEnforced); } /** * Called after SplashScreenView has added on the root window. * Makes the icon color of system bars contrast. * @hide */ public void makeSystemUIColorsTransparent() { if (mWindow != null) { final WindowManager.LayoutParams attr = mWindow.getAttributes(); mDrawBarBackground = (attr.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; mWindow.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); mStatusBarColor = mWindow.getStatusBarColor(); mNavigationBarColor = mWindow.getNavigationBarDividerColor(); mWindow.setStatusBarColor(Color.TRANSPARENT); mWindow.setNavigationBarColor(Color.TRANSPARENT); } setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } private void restoreSystemUIColors() { if (mWindow != null) { if (!mDrawBarBackground) { mWindow.clearFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); } mWindow.setStatusBarColor(mStatusBarColor); mWindow.setNavigationBarColor(mNavigationBarColor); } public static void applySystemBarsContrastColor(WindowInsetsController windowInsetsController, int backgroundColor) { final int lightBarAppearance = ContrastColorUtil.isColorLight(backgroundColor) ? LIGHT_BARS_MASK : 0; windowInsetsController.setSystemBarsAppearance(lightBarAppearance, LIGHT_BARS_MASK); } /** Loading
core/java/com/android/internal/policy/PhoneWindow.java +5 −0 Original line number Diff line number Diff line Loading @@ -3931,6 +3931,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { applyDecorFitsSystemWindows(); } @Override public boolean decorFitsSystemWindows() { return mDecorFitsSystemWindows; } private void applyDecorFitsSystemWindows() { ViewRootImpl impl = getViewRootImplOrNull(); if (impl != null) { Loading