Merge "Clear the system bars color when removing the splash screen window." into tm-dev

This commit is contained in:
Wei Sheng Shih
2022-04-15 02:18:23 +00:00
committed by Android (Google) Code Review
4 changed files with 62 additions and 90 deletions

View File

@@ -4114,8 +4114,8 @@ public final class ActivityThread extends ClientTransactionHandler
@NonNull SurfaceControl startingWindowLeash) {
final SplashScreenView.Builder builder = new SplashScreenView.Builder(r.activity);
final SplashScreenView view = builder.createFromParcel(parcelable).build();
view.attachHostWindow(r.window);
decorView.addView(view);
view.attachHostActivityAndSetSystemUIColors(r.activity, r.window);
view.requestLayout();
view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {

View File

@@ -16,9 +16,6 @@
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 static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLASHSCREEN_AVD;
@@ -29,11 +26,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UiThread;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
@@ -52,15 +47,12 @@ import android.view.SurfaceView;
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 android.widget.ImageView;
import com.android.internal.R;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.policy.DecorView;
import com.android.internal.util.ContrastColorUtil;
import java.time.Duration;
import java.time.Instant;
@@ -87,12 +79,6 @@ public final class SplashScreenView extends FrameLayout {
private static final String TAG = SplashScreenView.class.getSimpleName();
private static final boolean DEBUG = Build.IS_DEBUGGABLE;
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 mIsCopied;
private int mInitBackgroundColor;
@@ -107,9 +93,6 @@ public final class SplashScreenView extends FrameLayout {
private final Rect mTmpRect = new Rect();
private final int[] mTmpPos = new int[2];
// The host activity when transfer view to it.
private Activity mHostActivity;
@Nullable
private SurfaceControlViewHost.SurfacePackage mSurfacePackageCopy;
@Nullable
@@ -123,14 +106,7 @@ public final class SplashScreenView extends FrameLayout {
// cache original window and status
private Window mWindow;
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.
@@ -570,7 +546,6 @@ public final class SplashScreenView extends FrameLayout {
if (decorView != null) {
decorView.removeView(this);
}
restoreSystemUIColors();
mWindow = null;
}
mHasRemoved = true;
@@ -651,56 +626,12 @@ public final class SplashScreenView extends FrameLayout {
}
/**
* 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.
* Called when this view is attached to a window of an activity.
*
* @hide
*/
public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) {
mHostActivity = activity;
public void attachHostWindow(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);
}
/**
* Makes the icon color of system bars contrast.
* @hide
*/
public static void applySystemBarsContrastColor(WindowInsetsController windowInsetsController,
int backgroundColor) {
final int lightBarAppearance = ContrastColorUtil.isColorLight(backgroundColor)
? LIGHT_BARS_MASK : 0;
windowInsetsController.setSystemBarsAppearance(lightBarAppearance, LIGHT_BARS_MASK);
}
/**

View File

@@ -56,7 +56,6 @@ import android.util.ArrayMap;
import android.util.Slog;
import android.view.ContextThemeWrapper;
import android.view.SurfaceControl;
import android.view.View;
import android.window.SplashScreenView;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
@@ -543,22 +542,6 @@ public class SplashscreenContentDrawer {
mBrandingImageHeight);
}
final SplashScreenView splashScreenView = builder.build();
if (mSuggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
splashScreenView.addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
SplashScreenView.applySystemBarsContrastColor(
v.getWindowInsetsController(),
splashScreenView.getInitBackgroundColor());
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return splashScreenView;
}

View File

@@ -50,6 +50,7 @@ import android.view.Choreographer;
import android.view.Display;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.widget.FrameLayout;
@@ -63,6 +64,7 @@ import android.window.TaskSnapshot;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ContrastColorUtil;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TransactionPool;
@@ -121,6 +123,9 @@ public class StartingSurfaceDrawer {
private StartingSurface.SysuiProxy mSysuiProxy;
private final StartingWindowRemovalInfo mTmpRemovalInfo = new StartingWindowRemovalInfo();
private static final int LIGHT_BARS_MASK =
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
| WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
/**
* The minimum duration during which the splash screen is shown when the splash screen icon is
* animated.
@@ -361,9 +366,27 @@ public class StartingSurfaceDrawer {
// the window before first round relayoutWindow, which will happen after insets
// animation.
mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
// Block until we get the background color.
final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
record.parseAppSystemBarColor(context);
// Block until we get the background color.
final SplashScreenView contentView = viewSupplier.get();
if (suggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
contentView.addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
final int lightBarAppearance = ContrastColorUtil.isColorLight(
contentView.getInitBackgroundColor())
? LIGHT_BARS_MASK : 0;
contentView.getWindowInsetsController().setSystemBarsAppearance(
lightBarAppearance, LIGHT_BARS_MASK);
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
}
record.mBGColor = contentView.getInitBackgroundColor();
} else {
// release the icon view host
@@ -613,6 +636,7 @@ public class StartingSurfaceDrawer {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
"Removing splash screen window for task: %d", taskId);
if (record.mContentView != null) {
record.clearSystemBarColor();
if (immediately
|| record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
removeWindowInner(record.mDecorView, false);
@@ -670,6 +694,8 @@ public class StartingSurfaceDrawer {
private @StartingWindowType int mSuggestType;
private int mBGColor;
private final long mCreateTime;
private int mSystemBarAppearance;
private boolean mDrawsSystemBarBackgrounds;
StartingWindowRecord(IBinder appToken, View decorView,
TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
@@ -690,5 +716,37 @@ public class StartingSurfaceDrawer {
mContentView = splashScreenView;
mSetSplashScreen = true;
}
private void parseAppSystemBarColor(Context context) {
final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
mDrawsSystemBarBackgrounds = a.getBoolean(
R.styleable.Window_windowDrawsSystemBarBackgrounds, false);
if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
}
if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
}
a.recycle();
}
// Reset the system bar color which set by splash screen, make it align to the app.
private void clearSystemBarColor() {
if (mDecorView == null) {
return;
}
if (mDecorView.getLayoutParams() instanceof WindowManager.LayoutParams) {
final WindowManager.LayoutParams lp =
(WindowManager.LayoutParams) mDecorView.getLayoutParams();
if (mDrawsSystemBarBackgrounds) {
lp.flags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
} else {
lp.flags &= ~WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
}
mDecorView.setLayoutParams(lp);
}
mDecorView.getWindowInsetsController().setSystemBarsAppearance(
mSystemBarAppearance, LIGHT_BARS_MASK);
}
}
}