diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 3d23a33c8bc6a..e5401f509394c 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1747,6 +1747,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } prevDc.mClosingApps.remove(this); + prevDc.getDisplayPolicy().removeRelaunchingApp(this); if (prevDc.mFocusedApp == this) { prevDc.setFocusedApp(null); @@ -3959,6 +3960,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void startRelaunching() { if (mPendingRelaunchCount == 0) { mRelaunchStartTime = SystemClock.elapsedRealtime(); + if (mVisibleRequested) { + mDisplayContent.getDisplayPolicy().addRelaunchingApp(this); + } } clearAllDrawn(); @@ -3972,7 +3976,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mPendingRelaunchCount--; if (mPendingRelaunchCount == 0 && !isClientVisible()) { // Don't count if the client won't report drawn. - mRelaunchStartTime = 0; + finishOrAbortReplacingWindow(); } } else { // Update keyguard flags upon finishing relaunch. @@ -3993,7 +3997,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } mPendingRelaunchCount = 0; + finishOrAbortReplacingWindow(); + } + + void finishOrAbortReplacingWindow() { mRelaunchStartTime = 0; + mDisplayContent.getDisplayPolicy().removeRelaunchingApp(this); } /** @@ -5102,6 +5111,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mTaskSupervisor.onProcessActivityStateChanged(app, false /* forceBatch */); } logAppCompatState(); + if (!visible) { + finishOrAbortReplacingWindow(); + } } /** diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index a1efd2d09184c..25891485330e9 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -270,6 +270,12 @@ public class DisplayPolicy { private final ArraySet mInsetsSourceWindowsExceptIme = new ArraySet<>(); + /** Apps which are controlling the appearance of system bars */ + private final ArraySet mSystemBarColorApps = new ArraySet<>(); + + /** Apps which are relaunching and were controlling the appearance of system bars */ + private final ArraySet mRelaunchingSystemBarColorApps = new ArraySet<>(); + private boolean mIsFreeformWindowOverlappingWithNavBar; private boolean mLastImmersiveMode; @@ -1449,6 +1455,7 @@ public class DisplayPolicy { mStatusBarBackgroundWindows.clear(); mStatusBarColorCheckedBounds.setEmpty(); mStatusBarBackgroundCheckedBounds.setEmpty(); + mSystemBarColorApps.clear(); mAllowLockscreenWhenOn = false; mShowingDream = false; @@ -1525,6 +1532,7 @@ public class DisplayPolicy { win.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS, new Rect(win.getFrame()))); mStatusBarColorCheckedBounds.union(sTmpRect); + addSystemBarColorApp(win); } } @@ -1537,6 +1545,7 @@ public class DisplayPolicy { if (isOverlappingWithNavBar) { if (mNavBarColorWindowCandidate == null) { mNavBarColorWindowCandidate = win; + addSystemBarColorApp(win); } if (mNavBarBackgroundWindow == null) { mNavBarBackgroundWindow = win; @@ -1555,9 +1564,11 @@ public class DisplayPolicy { } } else if (win.isDimming()) { if (mStatusBar != null) { - addStatusBarAppearanceRegionsForDimmingWindow( + if (addStatusBarAppearanceRegionsForDimmingWindow( win.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS, - mStatusBar.getFrame(), win.getBounds(), win.getFrame()); + mStatusBar.getFrame(), win.getBounds(), win.getFrame())) { + addSystemBarColorApp(win); + } } if (isOverlappingWithNavBar && mNavBarColorWindowCandidate == null) { mNavBarColorWindowCandidate = win; @@ -1565,18 +1576,21 @@ public class DisplayPolicy { } } - private void addStatusBarAppearanceRegionsForDimmingWindow(int appearance, Rect statusBarFrame, - Rect winBounds, Rect winFrame) { + /** + * Returns true if mStatusBarAppearanceRegionList is changed. + */ + private boolean addStatusBarAppearanceRegionsForDimmingWindow( + int appearance, Rect statusBarFrame, Rect winBounds, Rect winFrame) { if (!sTmpRect.setIntersect(winBounds, statusBarFrame)) { - return; + return false; } if (mStatusBarColorCheckedBounds.contains(sTmpRect)) { - return; + return false; } if (appearance == 0 || !sTmpRect2.setIntersect(winFrame, statusBarFrame)) { mStatusBarAppearanceRegionList.add(new AppearanceRegion(0, new Rect(winBounds))); mStatusBarColorCheckedBounds.union(sTmpRect); - return; + return true; } // A dimming window can divide status bar into different appearance regions (up to 3). // +---------+-------------+---------+ @@ -1605,6 +1619,14 @@ public class DisplayPolicy { // We don't have vertical status bar yet, so we don't handle the other orientation. } mStatusBarColorCheckedBounds.union(sTmpRect); + return true; + } + + private void addSystemBarColorApp(WindowState win) { + final ActivityRecord app = win.mActivityRecord; + if (app != null) { + mSystemBarColorApps.add(app); + } } /** @@ -2086,6 +2108,25 @@ public class DisplayPolicy { return mDisplayContent.getInsetsPolicy(); } + /** + * Called when an app has started replacing its main window. + */ + void addRelaunchingApp(ActivityRecord app) { + if (mSystemBarColorApps.contains(app)) { + mRelaunchingSystemBarColorApps.add(app); + } + } + + /** + * Called when an app has finished replacing its main window or aborted. + */ + void removeRelaunchingApp(ActivityRecord app) { + final boolean removed = mRelaunchingSystemBarColorApps.remove(app); + if (removed & mRelaunchingSystemBarColorApps.isEmpty()) { + updateSystemBarAttributes(); + } + } + void resetSystemBarAttributes() { mLastDisableFlags = 0; updateSystemBarAttributes(); @@ -2128,6 +2169,11 @@ public class DisplayPolicy { final int displayId = getDisplayId(); final int disableFlags = win.getDisableFlags(); final int opaqueAppearance = updateSystemBarsLw(win, disableFlags); + if (!mRelaunchingSystemBarColorApps.isEmpty()) { + // The appearance of system bars might change while relaunching apps. We don't report + // the intermediate state to system UI. Otherwise, it might trigger redundant effects. + return; + } final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate, mDisplayContent.mInputMethodWindow, mNavigationBarPosition); final boolean isNavbarColorManagedByIme = @@ -2590,6 +2636,14 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState="); pw.println(mTopFullscreenOpaqueWindowState); } + if (!mSystemBarColorApps.isEmpty()) { + pw.print(prefix); pw.print("mSystemBarColorApps="); + pw.println(mSystemBarColorApps); + } + if (!mRelaunchingSystemBarColorApps.isEmpty()) { + pw.print(prefix); pw.print("mRelaunchingSystemBarColorApps="); + pw.println(mRelaunchingSystemBarColorApps); + } if (mNavBarColorWindowCandidate != null) { pw.print(prefix); pw.print("mNavBarColorWindowCandidate="); pw.println(mNavBarColorWindowCandidate); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index bc7e169ebc22c..2712cb7c4c355 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -6018,7 +6018,7 @@ class WindowState extends WindowContainer implements WindowManagerP final long duration = SystemClock.elapsedRealtime() - mActivityRecord.mRelaunchStartTime; Slog.i(TAG, "finishDrawing of relaunch: " + this + " " + duration + "ms"); - mActivityRecord.mRelaunchStartTime = 0; + mActivityRecord.finishOrAbortReplacingWindow(); } if (mActivityRecord != null && mAttrs.type == TYPE_APPLICATION_STARTING) { mWmService.mAtmService.mTaskSupervisor.getActivityMetricsLogger()