diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 6aa0dc9ab1198..a5b30208a5505 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1386,6 +1386,8 @@ public class ActivityManagerService extends IActivityManager.Stub final long[] mTmpLong = new long[2]; + private final ArraySet mTmpBroadcastQueue = new ArraySet(); + static final class ProcessChangeItem { static final int CHANGE_ACTIVITIES = 1<<0; static final int CHANGE_PROCESS_STATE = 1<<1; @@ -19521,7 +19523,7 @@ public class ActivityManagerService extends IActivityManager.Stub int schedGroup; int procState; boolean foregroundActivities = false; - final ArraySet queues = new ArraySet(); + mTmpBroadcastQueue.clear(); if (app == TOP_APP) { // The last app on the list is the foreground app. adj = ProcessList.FOREGROUND_APP_ADJ; @@ -19535,13 +19537,13 @@ public class ActivityManagerService extends IActivityManager.Stub schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.adjType = "instrumentation"; procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; - } else if (isReceivingBroadcastLocked(app, queues)) { + } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) { // An app that is currently receiving a broadcast also // counts as being in the foreground for OOM killer purposes. // It's placed in a sched group based on the nature of the // broadcast as reflected by which queue it's active in. adj = ProcessList.FOREGROUND_APP_ADJ; - schedGroup = (queues.contains(mFgBroadcastQueue)) + schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue)) ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "broadcast"; procState = ActivityManager.PROCESS_STATE_RECEIVER; diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index e93081804e176..00c37d2d899ac 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1253,7 +1253,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree mService.mAnimator.mAppWindowAnimating = true; } else if (mAppAnimator.wasAnimating) { // stopped animating, do one more pass through the layout - setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER, "appToken " + this + " done"); + setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER, + DEBUG_LAYOUT_REPEATS ? "appToken " + this + " done" : null); if (DEBUG_ANIM) Slog.v(TAG, "updateWindowsApps...: done animating " + this); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 1df7c66c8cca1..203137d4d481d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -124,6 +124,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; /** * Utility class for keeping track of the WindowStates and other pertinent contents of a @@ -156,6 +158,11 @@ class DisplayContent extends WindowContainer mTokenMap = new HashMap(); @@ -178,7 +185,7 @@ class DisplayContent extends WindowContainer mExitingTokens = new ArrayList<>(); @@ -200,7 +207,7 @@ class DisplayContent extends WindowContainer mTapExcludedWindows = new ArrayList<>(); @@ -231,9 +238,390 @@ class DisplayContent extends WindowContainer mUpdateWindowsForAnimator = w -> { + WindowStateAnimator winAnimator = w.mWinAnimator; + if (winAnimator.hasSurface()) { + final boolean wasAnimating = winAnimator.mWasAnimating; + final boolean nowAnimating = winAnimator.stepAnimationLocked( + mTmpWindowAnimator.mCurrentTime); + winAnimator.mWasAnimating = nowAnimating; + mTmpWindowAnimator.orAnimating(nowAnimating); + + if (DEBUG_WALLPAPER) Slog.v(TAG, + w + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating); + + if (wasAnimating && !winAnimator.mAnimating + && mWallpaperController.isWallpaperTarget(w)) { + mTmpWindowAnimator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; + pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; + if (DEBUG_LAYOUT_REPEATS) { + mService.mWindowPlacerLocked.debugLayoutRepeats( + "updateWindowsAndWallpaperLocked 2", pendingLayoutChanges); + } + } + } + + final AppWindowToken atoken = w.mAppToken; + if (winAnimator.mDrawState == READY_TO_SHOW) { + if (atoken == null || atoken.allDrawn) { + if (w.performShowLocked()) { + pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM; + if (DEBUG_LAYOUT_REPEATS) { + mService.mWindowPlacerLocked.debugLayoutRepeats( + "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges); + } + } + } + } + final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; + if (appAnimator != null && appAnimator.thumbnail != null) { + if (appAnimator.thumbnailTransactionSeq + != mTmpWindowAnimator.mAnimTransactionSequence) { + appAnimator.thumbnailTransactionSeq = + mTmpWindowAnimator.mAnimTransactionSequence; + appAnimator.thumbnailLayer = 0; + } + if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) { + appAnimator.thumbnailLayer = winAnimator.mAnimLayer; + } + } + }; + + private final Consumer mUpdateWallpaperForAnimator = w -> { + final WindowStateAnimator winAnimator = w.mWinAnimator; + if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) { + return; + } + + final int flags = w.mAttrs.flags; + + // If this window is animating, make a note that we have an animating window and take + // care of a request to run a detached wallpaper animation. + if (winAnimator.mAnimating) { + if (winAnimator.mAnimation != null) { + if ((flags & FLAG_SHOW_WALLPAPER) != 0 + && winAnimator.mAnimation.getDetachWallpaper()) { + mTmpWindow = w; + } + final int color = winAnimator.mAnimation.getBackgroundColor(); + if (color != 0) { + final TaskStack stack = w.getStack(); + if (stack != null) { + stack.setAnimationBackground(winAnimator, color); + } + } + } + mTmpWindowAnimator.setAnimating(true); + } + + // If this window's app token is running a detached wallpaper animation, make a note so + // we can ensure the wallpaper is displayed behind it. + final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; + if (appAnimator != null && appAnimator.animation != null + && appAnimator.animating) { + if ((flags & FLAG_SHOW_WALLPAPER) != 0 + && appAnimator.animation.getDetachWallpaper()) { + mTmpWindow = w; + } + + final int color = appAnimator.animation.getBackgroundColor(); + if (color != 0) { + final TaskStack stack = w.getStack(); + if (stack != null) { + stack.setAnimationBackground(winAnimator, color); + } + } + } + }; + + private final Consumer mSetInputMethodAnimLayerAdjustment = + w -> w.adjustAnimLayer(mInputMethodAnimLayerAdjustment); + + private final Consumer mScheduleToastTimeout = w -> { + final int lostFocusUid = mTmpWindow.mOwnerUid; + final Handler handler = mService.mH; + if (w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == lostFocusUid) { + if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, w)) { + handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w), + w.mAttrs.hideTimeoutMilliseconds); + } + } + }; + + private final ToBooleanFunction mFindFocusedWindow = w -> { + final AppWindowToken focusedApp = mService.mFocusedApp; + if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w + + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys()); + + if (!w.canReceiveKeys()) { + return false; + } + + final AppWindowToken wtoken = w.mAppToken; + + // If this window's application has been removed, just skip it. + if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { + if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " + + (wtoken.removed ? "removed" : "sendingToBottom")); + return false; + } + + if (focusedApp == null) { + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" + + " using new focus @ " + w); + mTmpWindow = w; + return true; + } + + if (!focusedApp.windowsAreFocusable()) { + // Current focused app windows aren't focusable... + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" + + " focusable using new focus @ " + w); + mTmpWindow = w; + return true; + } + + // Descend through all of the app tokens and find the first that either matches + // win.mAppToken (return win) or mFocusedApp (return null). + if (wtoken != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) { + if (focusedApp.compareTo(wtoken) > 0) { + // App stack below focused app stack. No focus for you!!! + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, + "findFocusedWindow: Reached focused app=" + focusedApp); + mTmpWindow = null; + return true; + } + } + + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w); + mTmpWindow = w; + return true; + }; + + private final Consumer mPrepareWindowSurfaces = + w -> w.mWinAnimator.prepareSurfaceLocked(true); + + private final Consumer mPerformLayout = w -> { + // Don't do layout of a window if it is not visible, or soon won't be visible, to avoid + // wasting time and funky changes while a window is animating away. + final boolean gone = (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w)) + || w.isGoneForLayoutLw(); + + if (DEBUG_LAYOUT && !w.mLayoutAttached) { + Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame + + " mLayoutAttached=" + w.mLayoutAttached + + " screen changed=" + w.isConfigChanged()); + final AppWindowToken atoken = w.mAppToken; + if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility + + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.hidden + + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + + " parentHidden=" + w.isParentWindowHidden()); + else Slog.v(TAG, " VIS: mViewVisibility=" + w.mViewVisibility + + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.hidden + + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + + " parentHidden=" + w.isParentWindowHidden()); + } + + // If this view is GONE, then skip it -- keep the current frame, and let the caller know + // so they can ignore it if they want. (We do the normal layout for INVISIBLE windows, + // since that means "perform layout as normal, just don't display"). + if (!gone || !w.mHaveFrame || w.mLayoutNeeded + || ((w.isConfigChanged() || w.setReportResizeHints()) + && !w.isGoneForLayoutLw() && + ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || + (w.mHasSurface && w.mAppToken != null && + w.mAppToken.layoutConfigChanges)))) { + if (!w.mLayoutAttached) { + if (mTmpInitial) { + //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); + w.mContentChanged = false; + } + if (w.mAttrs.type == TYPE_DREAM) { + // Don't layout windows behind a dream, so that if it does stuff like hide + // the status bar we won't get a bad transition when it goes away. + mTmpWindow = w; + } + w.mLayoutNeeded = false; + w.prelayout(); + mService.mPolicy.layoutWindowLw(w, null); + w.mLayoutSeq = mService.mLayoutSeq; + + // Window frames may have changed. Update dim layer with the new bounds. + final Task task = w.getTask(); + if (task != null) { + mDimLayerController.updateDimLayer(task); + } + + if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame + + " mContainingFrame=" + w.mContainingFrame + + " mDisplayFrame=" + w.mDisplayFrame); + } + } + }; + + private final Consumer mPerformLayoutAttached = w -> { + if (w.mLayoutAttached) { + if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame + + " mViewVisibility=" + w.mViewVisibility + + " mRelayoutCalled=" + w.mRelayoutCalled); + // If this view is GONE, then skip it -- keep the current frame, and let the caller + // know so they can ignore it if they want. (We do the normal layout for INVISIBLE + // windows, since that means "perform layout as normal, just don't display"). + if (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w)) { + return; + } + if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame + || w.mLayoutNeeded) { + if (mTmpInitial) { + //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); + w.mContentChanged = false; + } + w.mLayoutNeeded = false; + w.prelayout(); + mService.mPolicy.layoutWindowLw(w, w.getParentWindow()); + w.mLayoutSeq = mService.mLayoutSeq; + if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame + + " mContainingFrame=" + w.mContainingFrame + + " mDisplayFrame=" + w.mDisplayFrame); + } + } else if (w.mAttrs.type == TYPE_DREAM) { + // Don't layout windows behind a dream, so that if it does stuff like hide the + // status bar we won't get a bad transition when it goes away. + mTmpWindow = mTmpWindow2; + } + }; + + private final Predicate mComputeImeTargetPredicate = w -> { + if (DEBUG_INPUT_METHOD && mUpdateImeTarget) Slog.i(TAG_WM, "Checking window @" + w + + " fl=0x" + Integer.toHexString(w.mAttrs.flags)); + return w.canBeImeTarget(); + }; + + private final Consumer mApplyPostLayoutPolicy = + w -> mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), + mService.mInputMethodTarget); + + private final Consumer mApplySurfaceChangesTransaction = w -> { + final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; + final boolean obscuredChanged = w.mObscured != + mTmpApplySurfaceChangesTransactionState.obscured; + final RootWindowContainer root = mService.mRoot; + // Only used if default window + final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty(); + + // Update effect. + w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured; + if (!mTmpApplySurfaceChangesTransactionState.obscured) { + final boolean isDisplayed = w.isDisplayedLw(); + + if (isDisplayed && w.isObscuringDisplay()) { + // This window completely covers everything behind it, so we want to leave all + // of them as undimmed (for performance reasons). + root.mObscuringWindow = w; + mTmpApplySurfaceChangesTransactionState.obscured = true; + } + + mTmpApplySurfaceChangesTransactionState.displayHasContent |= + root.handleNotObscuredLocked(w, + mTmpApplySurfaceChangesTransactionState.obscured, + mTmpApplySurfaceChangesTransactionState.syswin); + + if (w.mHasSurface && isDisplayed) { + final int type = w.mAttrs.type; + if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR + || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { + mTmpApplySurfaceChangesTransactionState.syswin = true; + } + if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0 + && w.mAttrs.preferredRefreshRate != 0) { + mTmpApplySurfaceChangesTransactionState.preferredRefreshRate + = w.mAttrs.preferredRefreshRate; + } + if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0 + && w.mAttrs.preferredDisplayModeId != 0) { + mTmpApplySurfaceChangesTransactionState.preferredModeId + = w.mAttrs.preferredDisplayModeId; + } + } + } + + w.applyDimLayerIfNeeded(); + + if (isDefaultDisplay && obscuredChanged && w.isVisibleLw() + && mWallpaperController.isWallpaperTarget(w)) { + // This is the wallpaper target and its obscured state changed... make sure the + // current wallpaper's visibility has been updated accordingly. + mWallpaperController.updateWallpaperVisibility(); + } + + w.handleWindowMovedIfNeeded(); + + final WindowStateAnimator winAnimator = w.mWinAnimator; + + //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing"); + w.mContentChanged = false; + + // Moved from updateWindowsAndWallpaperLocked(). + if (w.mHasSurface) { + // Take care of the window being ready to display. + final boolean committed = winAnimator.commitFinishDrawingLocked(); + if (isDefaultDisplay && committed) { + if (w.mAttrs.type == TYPE_DREAM) { + // HACK: When a dream is shown, it may at that point hide the lock screen. + // So we need to redo the layout to let the phone window manager make this + // happen. + pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT; + if (DEBUG_LAYOUT_REPEATS) { + surfacePlacer.debugLayoutRepeats( + "dream and commitFinishDrawingLocked true", + pendingLayoutChanges); + } + } + if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { + if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, + "First draw done in potential wallpaper target " + w); + root.mWallpaperMayChange = true; + pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; + if (DEBUG_LAYOUT_REPEATS) { + surfacePlacer.debugLayoutRepeats( + "wallpaper and commitFinishDrawingLocked true", + pendingLayoutChanges); + } + } + } + if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) { + // Updates the shown frame before we set up the surface. This is needed + // because the resizing could change the top-left position (in addition to + // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to + // position the surface. + // + // If an animation is being started, we can't call this method because the + // animation hasn't processed its initial transformation yet, but in general + // we do want to update the position if the window is animating. + winAnimator.computeShownFrameLocked(); + } + winAnimator.setSurfaceBoundariesLocked(mTmpRecoveringMemory /* recoveringMemory */); + } + + final AppWindowToken atoken = w.mAppToken; + if (atoken != null) { + final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w); + if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) { + mTmpUpdateAllDrawn.add(atoken); + } + } + + if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus + && w.isDisplayedLw()) { + mTmpApplySurfaceChangesTransactionState.focusDisplayed = true; + } + + w.updateResizingWindowIfNeeded(); + }; + /** * @param display May not be null. * @param service You know. @@ -905,9 +1293,8 @@ class DisplayContent extends WindowContainer { - w.adjustAnimLayer(adj); - }, true /* traverseTopToBottom */); + mImeWindowsContainers.forAllWindows(mSetInputMethodAnimLayerAdjustment, + true /* traverseTopToBottom */); } /** @@ -1105,71 +1492,17 @@ class DisplayContent extends WindowContainer { - if (w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == lostFocusUid) { - if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, w)) { - handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w), - w.mAttrs.hideTimeoutMilliseconds); - } - } - }, false /* traverseTopToBottom */); + // Used to communicate the old focus to the callback method. + mTmpWindow = oldFocus; + + forAllWindows(mScheduleToastTimeout, false /* traverseTopToBottom */); } WindowState findFocusedWindow() { - final AppWindowToken focusedApp = mService.mFocusedApp; mTmpWindow = null; - forAllWindows(w -> { - if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w - + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys()); - - if (!w.canReceiveKeys()) { - return false; - } - - final AppWindowToken wtoken = w.mAppToken; - - // If this window's application has been removed, just skip it. - if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { - if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " - + (wtoken.removed ? "removed" : "sendingToBottom")); - return false; - } - - if (focusedApp == null) { - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" - + " using new focus @ " + w); - mTmpWindow = w; - return true; - } - - if (!focusedApp.windowsAreFocusable()) { - // Current focused app windows aren't focusable... - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" - + " focusable using new focus @ " + w); - mTmpWindow = w; - return true; - } - - // Descend through all of the app tokens and find the first that either matches - // win.mAppToken (return win) or mFocusedApp (return null). - if (wtoken != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) { - if (focusedApp.compareTo(wtoken) > 0) { - // App stack below focused app stack. No focus for you!!! - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, - "findFocusedWindow: Reached focused app=" + focusedApp); - mTmpWindow = null; - return true; - } - } - - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w); - mTmpWindow = w; - return true; - }, true /* traverseTopToBottom */); + forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */); if (mTmpWindow == null) { if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); @@ -1251,11 +1584,8 @@ class DisplayContent extends WindowContainer { - if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.i(TAG_WM, "Checking window @" - + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags)); - return w.canBeImeTarget(); - }); + mUpdateImeTarget = updateImeTarget; + WindowState target = getWindow(mComputeImeTargetPredicate); // Yet more tricksyness! If this window is a "starting" window, we do actually want @@ -1518,51 +1848,8 @@ class DisplayContent extends WindowContainer { - WindowStateAnimator winAnimator = w.mWinAnimator; - if (winAnimator.hasSurface()) { - final boolean wasAnimating = winAnimator.mWasAnimating; - final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime); - winAnimator.mWasAnimating = nowAnimating; - animator.orAnimating(nowAnimating); - - if (DEBUG_WALLPAPER) Slog.v(TAG, - w + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating); - - if (wasAnimating && !winAnimator.mAnimating - && mWallpaperController.isWallpaperTarget(w)) { - animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; - pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; - if (DEBUG_LAYOUT_REPEATS) { - mService.mWindowPlacerLocked.debugLayoutRepeats( - "updateWindowsAndWallpaperLocked 2", pendingLayoutChanges); - } - } - } - - final AppWindowToken atoken = w.mAppToken; - if (winAnimator.mDrawState == READY_TO_SHOW) { - if (atoken == null || atoken.allDrawn) { - if (w.performShowLocked()) { - pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM; - if (DEBUG_LAYOUT_REPEATS) { - mService.mWindowPlacerLocked.debugLayoutRepeats( - "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges); - } - } - } - } - final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; - if (appAnimator != null && appAnimator.thumbnail != null) { - if (appAnimator.thumbnailTransactionSeq != animator.mAnimTransactionSequence) { - appAnimator.thumbnailTransactionSeq = animator.mAnimTransactionSequence; - appAnimator.thumbnailLayer = 0; - } - if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) { - appAnimator.thumbnailLayer = winAnimator.mAnimLayer; - } - } - }, true /* traverseTopToBottom */); + mTmpWindowAnimator = animator; + forAllWindows(mUpdateWindowsForAnimator, true /* traverseTopToBottom */); } void updateWallpaperForAnimator(WindowAnimator animator) { @@ -1570,53 +1857,9 @@ class DisplayContent extends WindowContainer { - final WindowStateAnimator winAnimator = w.mWinAnimator; - if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) { - return; - } - - final int flags = w.mAttrs.flags; - - // If this window is animating, make a note that we have an animating window and take - // care of a request to run a detached wallpaper animation. - if (winAnimator.mAnimating) { - if (winAnimator.mAnimation != null) { - if ((flags & FLAG_SHOW_WALLPAPER) != 0 - && winAnimator.mAnimation.getDetachWallpaper()) { - mTmpWindow = w; - } - final int color = winAnimator.mAnimation.getBackgroundColor(); - if (color != 0) { - final TaskStack stack = w.getStack(); - if (stack != null) { - stack.setAnimationBackground(winAnimator, color); - } - } - } - animator.setAnimating(true); - } - - // If this window's app token is running a detached wallpaper animation, make a note so - // we can ensure the wallpaper is displayed behind it. - final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; - if (appAnimator != null && appAnimator.animation != null - && appAnimator.animating) { - if ((flags & FLAG_SHOW_WALLPAPER) != 0 - && appAnimator.animation.getDetachWallpaper()) { - mTmpWindow = w; - } - - final int color = appAnimator.animation.getBackgroundColor(); - if (color != 0) { - final TaskStack stack = w.getStack(); - if (stack != null) { - stack.setAnimationBackground(winAnimator, color); - } - } - } - }, true /* traverseTopToBottom */); + forAllWindows(mUpdateWallpaperForAnimator, true /* traverseTopToBottom */); if (animator.mWindowDetachedWallpaper != mTmpWindow) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from " @@ -1627,9 +1870,7 @@ class DisplayContent extends WindowContainer { - w.mWinAnimator.prepareSurfaceLocked(true); - }, false /* traverseTopToBottom */); + forAllWindows(mPrepareWindowSurfaces, false /* traverseTopToBottom */); } boolean inputMethodClientHasFocus(IInputMethodClient client) { @@ -1765,136 +2006,18 @@ class DisplayContent extends WindowContainer { - mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), - mService.mInputMethodTarget); - }, true /* traverseTopToBottom */); + forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); pendingLayoutChanges |= mService.mPolicy.finishPostLayoutPolicyLw(); if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats( "after finishPostLayoutPolicyLw", pendingLayoutChanges); } } while (pendingLayoutChanges != 0); - final RootWindowContainer root = mService.mRoot; mTmpApplySurfaceChangesTransactionState.reset(); resetDimming(); - // Only used if default window - final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty(); - - forAllWindows(w -> { - final boolean obscuredChanged = w.mObscured != - mTmpApplySurfaceChangesTransactionState.obscured; - - // Update effect. - w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured; - if (!mTmpApplySurfaceChangesTransactionState.obscured) { - final boolean isDisplayed = w.isDisplayedLw(); - - if (isDisplayed && w.isObscuringDisplay()) { - // This window completely covers everything behind it, so we want to leave all - // of them as undimmed (for performance reasons). - root.mObscuringWindow = w; - mTmpApplySurfaceChangesTransactionState.obscured = true; - } - - mTmpApplySurfaceChangesTransactionState.displayHasContent |= - root.handleNotObscuredLocked(w, - mTmpApplySurfaceChangesTransactionState.obscured, - mTmpApplySurfaceChangesTransactionState.syswin); - - if (w.mHasSurface && isDisplayed) { - final int type = w.mAttrs.type; - if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR - || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { - mTmpApplySurfaceChangesTransactionState.syswin = true; - } - if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0 - && w.mAttrs.preferredRefreshRate != 0) { - mTmpApplySurfaceChangesTransactionState.preferredRefreshRate - = w.mAttrs.preferredRefreshRate; - } - if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0 - && w.mAttrs.preferredDisplayModeId != 0) { - mTmpApplySurfaceChangesTransactionState.preferredModeId - = w.mAttrs.preferredDisplayModeId; - } - } - } - - w.applyDimLayerIfNeeded(); - - if (isDefaultDisplay && obscuredChanged && w.isVisibleLw() - && mWallpaperController.isWallpaperTarget(w)) { - // This is the wallpaper target and its obscured state changed... make sure the - // current wallpaper's visibility has been updated accordingly. - mWallpaperController.updateWallpaperVisibility(); - } - - w.handleWindowMovedIfNeeded(); - - final WindowStateAnimator winAnimator = w.mWinAnimator; - - //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing"); - w.mContentChanged = false; - - // Moved from updateWindowsAndWallpaperLocked(). - if (w.mHasSurface) { - // Take care of the window being ready to display. - final boolean committed = winAnimator.commitFinishDrawingLocked(); - if (isDefaultDisplay && committed) { - if (w.mAttrs.type == TYPE_DREAM) { - // HACK: When a dream is shown, it may at that point hide the lock screen. - // So we need to redo the layout to let the phone window manager make this - // happen. - pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT; - if (DEBUG_LAYOUT_REPEATS) { - surfacePlacer.debugLayoutRepeats( - "dream and commitFinishDrawingLocked true", - pendingLayoutChanges); - } - } - if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { - if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, - "First draw done in potential wallpaper target " + w); - root.mWallpaperMayChange = true; - pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; - if (DEBUG_LAYOUT_REPEATS) { - surfacePlacer.debugLayoutRepeats( - "wallpaper and commitFinishDrawingLocked true", - pendingLayoutChanges); - } - } - } - if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) { - // Updates the shown frame before we set up the surface. This is needed - // because the resizing could change the top-left position (in addition to - // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to - // position the surface. - // - // If an animation is being started, we can't call this method because the - // animation hasn't processed its initial transformation yet, but in general - // we do want to update the position if the window is animating. - winAnimator.computeShownFrameLocked(); - } - winAnimator.setSurfaceBoundariesLocked(recoveringMemory); - } - - final AppWindowToken atoken = w.mAppToken; - if (atoken != null) { - final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w); - if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) { - mTmpUpdateAllDrawn.add(atoken); - } - } - - if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus - && w.isDisplayedLw()) { - mTmpApplySurfaceChangesTransactionState.focusDisplayed = true; - } - - w.updateResizingWindowIfNeeded(); - }, true /* traverseTopToBottom */); + mTmpRecoveringMemory = recoveringMemory; + forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */); mService.mDisplayManagerInternal.setDisplayProperties(mDisplayId, mTmpApplySurfaceChangesTransactionState.displayHasContent, @@ -1923,8 +2046,6 @@ class DisplayContent extends WindowContainer