Merge "Refactorings for Window Manager module."

This commit is contained in:
Filip Gruszczynski
2015-09-09 19:49:15 +00:00
committed by Android (Google) Code Review
7 changed files with 357 additions and 361 deletions

View File

@@ -133,6 +133,7 @@ public class AppTransition implements Dump {
private static final int DEFAULT_APP_TRANSITION_DURATION = 336;
private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336;
private static final long APP_TRANSITION_TIMEOUT_MS = 5000;
private final Context mContext;
private final Handler mH;
@@ -242,10 +243,6 @@ public class AppTransition implements Dump {
return mNextAppTransition != TRANSIT_UNSET;
}
boolean isTransitionNone() {
return mNextAppTransition == TRANSIT_NONE;
}
boolean isTransitionEqual(int transit) {
return mNextAppTransition == transit;
}
@@ -254,7 +251,7 @@ public class AppTransition implements Dump {
return mNextAppTransition;
}
void setAppTransition(int transit) {
private void setAppTransition(int transit) {
mNextAppTransition = transit;
}
@@ -299,7 +296,7 @@ public class AppTransition implements Dump {
return mNextAppTransitionScaleUp;
}
boolean prepare() {
private boolean prepare() {
if (!isRunning()) {
mAppTransitionState = APP_STATE_IDLE;
notifyAppTransitionPendingLocked();
@@ -1458,4 +1455,34 @@ public class AppTransition implements Dump {
public void setCurrentUser(int newUserId) {
mCurrentUserId = newUserId;
}
/**
* @return true if transition is not running and should not be skipped, false if transition is
* already running
*/
boolean prepareAppTransitionLocked(int transit, boolean alwaysKeepCurrent) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
+ " transit=" + appTransitionToString(transit)
+ " " + this
+ " alwaysKeepCurrent=" + alwaysKeepCurrent
+ " Callers=" + Debug.getCallers(3));
if (!isTransitionSet() || mNextAppTransition == TRANSIT_NONE) {
setAppTransition(transit);
} else if (!alwaysKeepCurrent) {
if (transit == TRANSIT_TASK_OPEN && isTransitionEqual(TRANSIT_TASK_CLOSE)) {
// Opening a new task always supersedes a close for the anim.
setAppTransition(transit);
} else if (transit == TRANSIT_ACTIVITY_OPEN
&& isTransitionEqual(TRANSIT_ACTIVITY_CLOSE)) {
// Opening a new activity always supersedes a close for the anim.
setAppTransition(transit);
}
}
boolean prepared = prepare();
if (isTransitionSet()) {
mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, APP_TRANSITION_TIMEOUT_MS);
}
return prepared;
}
}

View File

@@ -25,7 +25,6 @@ import android.graphics.Rect;
import android.os.Debug;
import android.os.RemoteException;
import android.util.EventLog;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayInfo;
@@ -34,7 +33,6 @@ import com.android.server.EventLogTags;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class TaskStack implements DimLayer.DimLayerUser {
@@ -414,7 +412,7 @@ public class TaskStack implements DimLayer.DimLayerUser {
}
}
if (doAnotherLayoutPass) {
mService.requestTraversalLocked();
mService.mWindowPlacerLocked.requestTraversal();
}
if (mStackId == DOCKED_STACK_ID) {

View File

@@ -57,6 +57,7 @@ public class WindowAnimator {
final WindowManagerService mService;
final Context mContext;
final WindowManagerPolicy mPolicy;
private final WindowSurfacePlacer mWindowPlacerLocked;
/** Is any window animating? */
boolean mAnimating;
@@ -112,6 +113,7 @@ public class WindowAnimator {
mService = service;
mContext = service.mContext;
mPolicy = service.mPolicy;
mWindowPlacerLocked = service.mWindowPlacerLocked;
mAnimationFrameCallback = new Choreographer.FrameCallback() {
public void doFrame(long frameTimeNs) {
@@ -300,7 +302,7 @@ public class WindowAnimator {
setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(
mWindowPlacerLocked.debugLayoutRepeats(
"updateWindowsAndWallpaperLocked 2",
getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
}
@@ -315,7 +317,7 @@ public class WindowAnimator {
setPendingLayoutChanges(displayId,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(
mWindowPlacerLocked.debugLayoutRepeats(
"updateWindowsAndWallpaperLocked 3",
getPendingLayoutChanges(displayId));
}
@@ -410,7 +412,7 @@ public class WindowAnimator {
setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(
mWindowPlacerLocked.debugLayoutRepeats(
"updateWindowsAndWallpaperLocked 4",
getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
}
@@ -435,7 +437,7 @@ public class WindowAnimator {
setPendingLayoutChanges(displayId,
WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(
mWindowPlacerLocked.debugLayoutRepeats(
"updateWindowsAndWallpaperLocked 5",
getPendingLayoutChanges(displayId));
}
@@ -741,15 +743,15 @@ public class WindowAnimator {
boolean doRequest = false;
if (mBulkUpdateParams != 0) {
doRequest = mService.mWindowPlacerLocked.copyAnimToLayoutParamsLocked();
doRequest = mWindowPlacerLocked.copyAnimToLayoutParamsLocked();
}
if (hasPendingLayoutChanges || doRequest) {
mService.requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
if (!mAnimating && wasAnimating) {
mService.requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
if (WindowManagerService.DEBUG_WINDOW_TRACE) {
Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
@@ -850,7 +852,7 @@ public class WindowAnimator {
if (displayId == windows.get(i).getDisplayId()) {
setPendingLayoutChanges(displayId, changes);
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(reason,
mWindowPlacerLocked.debugLayoutRepeats(reason,
getPendingLayoutChanges(displayId));
}
break;

View File

@@ -471,7 +471,6 @@ public class WindowManagerService extends IWindowManager.Stub
int mSystemDecorLayer = 0;
final Rect mScreenRect = new Rect();
boolean mTraversalScheduled = false;
boolean mDisplayFrozen = false;
long mDisplayFreezeTime = 0;
int mLastDisplayFreezeDuration = 0;
@@ -2773,7 +2772,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (displayContent != null) {
displayContent.layoutNeeded = true;
}
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
}
} finally {
@@ -3472,35 +3471,12 @@ public class WindowManagerService extends IWindowManager.Stub
"prepareAppTransition()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
+ " transit=" + AppTransition.appTransitionToString(transit)
+ " " + mAppTransition
+ " alwaysKeepCurrent=" + alwaysKeepCurrent
+ " Callers=" + Debug.getCallers(3));
if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
mAppTransition.setAppTransition(transit);
} else if (!alwaysKeepCurrent) {
if (transit == AppTransition.TRANSIT_TASK_OPEN
&& mAppTransition.isTransitionEqual(
AppTransition.TRANSIT_TASK_CLOSE)) {
// Opening a new task always supersedes a close for the anim.
mAppTransition.setAppTransition(transit);
} else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
&& mAppTransition.isTransitionEqual(
AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
// Opening a new activity always supersedes a close for the anim.
mAppTransition.setAppTransition(transit);
}
}
if (okToDisplay() && mAppTransition.prepare()) {
boolean prepared = mAppTransition.prepareAppTransitionLocked(
transit, alwaysKeepCurrent);
if (prepared && okToDisplay()) {
mSkipAppTransitionAnimation = false;
}
if (mAppTransition.isTransitionSet()) {
mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
}
}
}
@@ -3836,7 +3812,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (atoken != null) {
atoken.appFullscreen = toOpaque;
setWindowOpaqueLocked(token, toOpaque);
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
}
}
@@ -4841,7 +4817,7 @@ public class WindowManagerService extends IWindowManager.Stub
mAnimator.mKeyguardGoingAway = true;
mAnimator.mKeyguardGoingAwayToNotificationShade = keyguardGoingToNotificationShade;
mAnimator.mKeyguardGoingAwayDisableWindowAnimations = disableWindowAnimations;
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
}
@@ -7180,7 +7156,6 @@ public class WindowManagerService extends IWindowManager.Stub
case DO_TRAVERSAL: {
synchronized(mWindowMap) {
mTraversalScheduled = false;
mWindowPlacerLocked.performSurfacePlacement();
}
} break;
@@ -8463,14 +8438,7 @@ public class WindowManagerService extends IWindowManager.Stub
void requestTraversal() {
synchronized (mWindowMap) {
requestTraversalLocked();
}
}
void requestTraversalLocked() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mH.sendEmptyMessage(H.DO_TRAVERSAL);
mWindowPlacerLocked.requestTraversal();
}
}
@@ -9334,6 +9302,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (mInputMethodWindow != null) {
pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
}
mWindowPlacerLocked.dump(pw, " ");
mWallpaperControllerLocked.dump(pw, " ");
if (mInputMethodAnimLayerAdjustment != 0 ||
mWallpaperControllerLocked.getAnimLayerAdjustment() != 0) {
@@ -9369,8 +9338,7 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
pw.print(" mSkipAppTransitionAnimation=");pw.println(mSkipAppTransitionAnimation);
pw.println(" mLayoutToAnim:");
mAppTransition.dump(pw, " ");
}
@@ -9728,7 +9696,7 @@ public class WindowManagerService extends IWindowManager.Stub
createDisplayContentLocked(display);
displayReady(displayId);
}
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
}
@@ -9751,7 +9719,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
mAnimator.removeDisplayLocked(displayId);
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
public void onDisplayChanged(int displayId) {
@@ -9763,7 +9731,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (displayContent != null) {
displayContent.updateDisplayInfo();
}
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
@Override
@@ -9910,7 +9878,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
requestTraversalLocked();
mWindowPlacerLocked.requestTraversal();
}
mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
if (mWaitingForDrawn.isEmpty()) {

View File

@@ -1640,7 +1640,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
Slog.w(TAG, "Failed to report 'resized' to the client of " + this
+ ", removing this window.");
mService.mPendingRemove.add(this);
mService.requestTraversalLocked();
mService.mWindowPlacerLocked.requestTraversal();
}
}

View File

@@ -1446,7 +1446,7 @@ class WindowStateAnimator {
updateSurfaceWindowCrop(recoveringMemory);
}
public void prepareSurfaceLocked(final boolean recoveringMemory) {
void prepareSurfaceLocked(final boolean recoveringMemory) {
final WindowState w = mWin;
if (mSurfaceControl == null) {
if (w.mOrientationChanging) {
@@ -1782,17 +1782,14 @@ class WindowStateAnimator {
*
* @return Returns true if the surface was successfully shown.
*/
boolean showSurfaceRobustlyLocked() {
private boolean showSurfaceRobustlyLocked() {
try {
if (mSurfaceControl != null) {
mSurfaceShown = true;
mSurfaceControl.show();
if (mWin.mTurnOnScreen) {
if (DEBUG_VISIBILITY) Slog.v(TAG,
"Show surface turning screen on: " + mWin);
mWin.mTurnOnScreen = false;
mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
}
mSurfaceShown = true;
mSurfaceControl.show();
if (mWin.mTurnOnScreen) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
mWin.mTurnOnScreen = false;
mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
}
return true;
} catch (RuntimeException e) {

View File

@@ -57,6 +57,7 @@ import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import java.io.PrintWriter;
import java.util.ArrayList;
/**
@@ -108,6 +109,8 @@ class WindowSurfacePlacer {
private int mPreferredModeId = 0;
private boolean mTraversalScheduled;
public WindowSurfacePlacer(WindowManagerService service) {
mService = service;
mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
@@ -116,11 +119,11 @@ class WindowSurfacePlacer {
final void performSurfacePlacement() {
int loopCount = 6;
do {
mService.mTraversalScheduled = false;
mTraversalScheduled = false;
performSurfacePlacementLoop();
mService.mH.removeMessages(DO_TRAVERSAL);
loopCount--;
} while (mService.mTraversalScheduled && loopCount > 0);
} while (mTraversalScheduled && loopCount > 0);
mWallpaperActionPending = false;
}
@@ -177,7 +180,7 @@ class WindowSurfacePlacer {
if (mService.needsLayout()) {
if (++mLayoutRepeatCount < 6) {
mService.requestTraversalLocked();
requestTraversal();
} else {
Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
mLayoutRepeatCount = 0;
@@ -257,290 +260,7 @@ class WindowSurfacePlacer {
">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
SurfaceControl.openTransaction();
try {
if (mService.mWatermark != null) {
mService.mWatermark.positionSurface(defaultDw, defaultDh);
}
if (mService.mStrictModeFlash != null) {
mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
}
if (mService.mCircularDisplayMask != null) {
mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
mService.mRotation);
}
if (mService.mEmulatorDisplayOverlay != null) {
mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
mService.mRotation);
}
boolean focusDisplayed = false;
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
boolean updateAllDrawn = false;
WindowList windows = displayContent.getWindowList();
DisplayInfo displayInfo = displayContent.getDisplayInfo();
final int displayId = displayContent.getDisplayId();
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
final int innerDw = displayInfo.appWidth;
final int innerDh = displayInfo.appHeight;
final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
// Reset for each display.
mDisplayHasContent = false;
mPreferredRefreshRate = 0;
mPreferredModeId = 0;
int repeats = 0;
do {
repeats++;
if (repeats > 6) {
Slog.w(TAG, "Animation repeat aborted after too many iterations");
displayContent.layoutNeeded = false;
break;
}
if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
"On entry to LockedInner", displayContent.pendingLayoutChanges);
if ((displayContent.pendingLayoutChanges
& FINISH_LAYOUT_REDO_WALLPAPER) != 0
&& mWallpaperControllerLocked.adjustWallpaperWindows()) {
mService.assignLayersLocked(windows);
displayContent.layoutNeeded = true;
}
if (isDefaultDisplay && (displayContent.pendingLayoutChanges
& FINISH_LAYOUT_REDO_CONFIG) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG,
"Computing new config from layout");
if (mService.updateOrientationFromAppTokensLocked(true)) {
displayContent.layoutNeeded = true;
mService.mH.sendEmptyMessage(
SEND_NEW_CONFIGURATION);
}
}
if ((displayContent.pendingLayoutChanges
& FINISH_LAYOUT_REDO_LAYOUT) != 0) {
displayContent.layoutNeeded = true;
}
// FIRST LOOP: Perform a layout, if needed.
if (repeats < LAYOUT_REPEAT_THRESHOLD) {
performLayoutLockedInner(displayContent, repeats == 1,
false /*updateInputWindows*/);
} else {
Slog.w(TAG, "Layout repeat skipped after too many iterations");
}
// FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
// it is animating.
displayContent.pendingLayoutChanges = 0;
if (isDefaultDisplay) {
mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
for (i = windows.size() - 1; i >= 0; i--) {
WindowState w = windows.get(i);
if (w.mHasSurface) {
mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
w.mAttachedWindow);
}
}
displayContent.pendingLayoutChanges |=
mService.mPolicy.finishPostLayoutPolicyLw();
if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
"after finishPostLayoutPolicyLw",
displayContent.pendingLayoutChanges);
}
} while (displayContent.pendingLayoutChanges != 0);
mObscured = false;
mSyswin = false;
displayContent.resetDimming();
// Only used if default window
final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
final int N = windows.size();
for (i=N-1; i>=0; i--) {
WindowState w = windows.get(i);
final Task task = w.getTask();
if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
continue;
}
final boolean obscuredChanged = w.mObscured != mObscured;
// Update effect.
w.mObscured = mObscured;
if (!mObscured) {
handleNotObscuredLocked(w, innerDw, innerDh);
}
if (task != null && !task.getContinueDimming()) {
w.handleFlagDimBehind();
}
if (isDefaultDisplay && obscuredChanged
&& mWallpaperControllerLocked.isWallpaperTarget(w)
&& w.isVisibleLw()) {
// This is the wallpaper target and its obscured state
// changed... make sure the current wallaper's visibility
// has been updated accordingly.
mWallpaperControllerLocked.updateWallpaperVisibility();
}
final WindowStateAnimator winAnimator = w.mWinAnimator;
// If the window has moved due to its containing content frame changing, then
// notify the listeners and optionally animate it.
if (w.hasMoved()) {
// Frame has moved, containing content frame has also moved, and we're not
// currently animating... let's do something.
final int left = w.mFrame.left;
final int top = w.mFrame.top;
if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
Animation a = AnimationUtils.loadAnimation(mService.mContext,
com.android.internal.R.anim.window_move_from_decor);
winAnimator.setAnimation(a);
winAnimator.mAnimDw = w.mLastFrame.left - left;
winAnimator.mAnimDh = w.mLastFrame.top - top;
winAnimator.mAnimateMove = true;
winAnimator.mAnimatingMove = true;
}
//TODO (multidisplay): Accessibility supported only for the default display.
if (mService.mAccessibilityController != null
&& displayId == Display.DEFAULT_DISPLAY) {
mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
}
try {
w.mClient.moved(left, top);
} catch (RemoteException e) {
}
}
//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.
displayContent.pendingLayoutChanges |=
FINISH_LAYOUT_REDO_LAYOUT;
if (DEBUG_LAYOUT_REPEATS) {
debugLayoutRepeats(
"dream and commitFinishDrawingLocked true",
displayContent.pendingLayoutChanges);
}
}
if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
"First draw done in potential wallpaper target " + w);
mWallpaperMayChange = true;
displayContent.pendingLayoutChanges |=
FINISH_LAYOUT_REDO_WALLPAPER;
if (DEBUG_LAYOUT_REPEATS) {
debugLayoutRepeats(
"wallpaper and commitFinishDrawingLocked true",
displayContent.pendingLayoutChanges);
}
}
}
winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
}
final AppWindowToken atoken = w.mAppToken;
if (DEBUG_STARTING_WINDOW && atoken != null
&& w == atoken.startingWindow) {
Slog.d(TAG, "updateWindows: starting " + w
+ " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+ " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
}
if (atoken != null
&& (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
atoken.lastTransactionSequence = mService.mTransactionSequence;
atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
atoken.startingDisplayed = false;
}
if ((w.isOnScreenIgnoringKeyguard()
|| winAnimator.mAttrType == TYPE_BASE_APPLICATION)
&& !w.mExiting && !w.mDestroying) {
if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ w.isDrawnLw()
+ ", isAnimating=" + winAnimator.isAnimating());
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s="
+ winAnimator.mSurfaceControl
+ " pv=" + w.mPolicyVisibility
+ " mDrawState=" + winAnimator.drawStateToString()
+ " ah=" + w.mAttachedHidden
+ " th=" + atoken.hiddenRequested
+ " a=" + winAnimator.mAnimating);
}
}
if (w != atoken.startingWindow) {
if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
atoken.numInterestingWindows++;
if (w.isDrawnLw()) {
atoken.numDrawnWindows++;
if (DEBUG_VISIBILITY
|| DEBUG_ORIENTATION)
Slog.v(TAG,
"tokenMayBeDrawn: " + atoken
+ " freezingScreen="
+ atoken.mAppAnimator.freezingScreen
+ " mAppFreezing=" + w.mAppFreezing);
updateAllDrawn = true;
}
}
} else if (w.isDrawnLw()) {
atoken.startingDisplayed = true;
}
}
}
if (isDefaultDisplay && someoneLosingFocus && (w == mService.mCurrentFocus)
&& w.isDisplayedLw()) {
focusDisplayed = true;
}
mService.updateResizingWindows(w);
}
mService.mDisplayManagerInternal.setDisplayProperties(displayId,
mDisplayHasContent,
mPreferredRefreshRate,
mPreferredModeId,
true /* inTraversal, must call performTraversalInTrans... below */);
mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
if (updateAllDrawn) {
updateAllDrawnLocked(displayContent);
}
}
if (focusDisplayed) {
mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
}
// Give the display manager a chance to adjust properties
// like display rotation if it needs to.
mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
@@ -801,6 +521,279 @@ class WindowSurfacePlacer {
}
}
private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
int defaultDw, int defaultDh) {
if (mService.mWatermark != null) {
mService.mWatermark.positionSurface(defaultDw, defaultDh);
}
if (mService.mStrictModeFlash != null) {
mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
}
if (mService.mCircularDisplayMask != null) {
mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
mService.mRotation);
}
if (mService.mEmulatorDisplayOverlay != null) {
mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
mService.mRotation);
}
boolean focusDisplayed = false;
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
boolean updateAllDrawn = false;
WindowList windows = displayContent.getWindowList();
DisplayInfo displayInfo = displayContent.getDisplayInfo();
final int displayId = displayContent.getDisplayId();
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
final int innerDw = displayInfo.appWidth;
final int innerDh = displayInfo.appHeight;
final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
// Reset for each display.
mDisplayHasContent = false;
mPreferredRefreshRate = 0;
mPreferredModeId = 0;
int repeats = 0;
do {
repeats++;
if (repeats > 6) {
Slog.w(TAG, "Animation repeat aborted after too many iterations");
displayContent.layoutNeeded = false;
break;
}
if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
"On entry to LockedInner", displayContent.pendingLayoutChanges);
if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
mWallpaperControllerLocked.adjustWallpaperWindows()) {
mService.assignLayersLocked(windows);
displayContent.layoutNeeded = true;
}
if (isDefaultDisplay
&& (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
if (mService.updateOrientationFromAppTokensLocked(true)) {
displayContent.layoutNeeded = true;
mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
}
}
if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
displayContent.layoutNeeded = true;
}
// FIRST LOOP: Perform a layout, if needed.
if (repeats < LAYOUT_REPEAT_THRESHOLD) {
performLayoutLockedInner(displayContent, repeats == 1,
false /* updateInputWindows */);
} else {
Slog.w(TAG, "Layout repeat skipped after too many iterations");
}
// FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
// it is animating.
displayContent.pendingLayoutChanges = 0;
if (isDefaultDisplay) {
mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState w = windows.get(i);
if (w.mHasSurface) {
mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
w.mAttachedWindow);
}
}
displayContent.pendingLayoutChanges |=
mService.mPolicy.finishPostLayoutPolicyLw();
if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
displayContent.pendingLayoutChanges);
}
} while (displayContent.pendingLayoutChanges != 0);
mObscured = false;
mSyswin = false;
displayContent.resetDimming();
// Only used if default window
final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState w = windows.get(i);
final Task task = w.getTask();
if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
continue;
}
final boolean obscuredChanged = w.mObscured != mObscured;
// Update effect.
w.mObscured = mObscured;
if (!mObscured) {
handleNotObscuredLocked(w, innerDw, innerDh);
}
if (task != null && !task.getContinueDimming()) {
w.handleFlagDimBehind();
}
if (isDefaultDisplay && obscuredChanged
&& mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
// This is the wallpaper target and its obscured state
// changed... make sure the current wallaper's visibility
// has been updated accordingly.
mWallpaperControllerLocked.updateWallpaperVisibility();
}
final WindowStateAnimator winAnimator = w.mWinAnimator;
// If the window has moved due to its containing content frame changing, then
// notify the listeners and optionally animate it.
if (w.hasMoved()) {
// Frame has moved, containing content frame has also moved, and we're not
// currently animating... let's do something.
final int left = w.mFrame.left;
final int top = w.mFrame.top;
if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
Animation a = AnimationUtils.loadAnimation(mService.mContext,
com.android.internal.R.anim.window_move_from_decor);
winAnimator.setAnimation(a);
winAnimator.mAnimDw = w.mLastFrame.left - left;
winAnimator.mAnimDh = w.mLastFrame.top - top;
winAnimator.mAnimateMove = true;
winAnimator.mAnimatingMove = true;
}
//TODO (multidisplay): Accessibility supported only for the default display.
if (mService.mAccessibilityController != null
&& displayId == Display.DEFAULT_DISPLAY) {
mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
}
try {
w.mClient.moved(left, top);
} catch (RemoteException e) {
}
}
//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.
displayContent.pendingLayoutChanges |=
FINISH_LAYOUT_REDO_LAYOUT;
if (DEBUG_LAYOUT_REPEATS) {
debugLayoutRepeats("dream and commitFinishDrawingLocked true",
displayContent.pendingLayoutChanges);
}
}
if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
if (DEBUG_WALLPAPER_LIGHT)
Slog.v(TAG, "First draw done in potential wallpaper target " + w);
mWallpaperMayChange = true;
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
if (DEBUG_LAYOUT_REPEATS) {
debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
displayContent.pendingLayoutChanges);
}
}
}
winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
}
final AppWindowToken atoken = w.mAppToken;
if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Slog.d(TAG, "updateWindows: starting " + w
+ " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+ " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
}
if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
atoken.lastTransactionSequence = mService.mTransactionSequence;
atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
atoken.startingDisplayed = false;
}
if ((w.isOnScreenIgnoringKeyguard()
|| winAnimator.mAttrType == TYPE_BASE_APPLICATION)
&& !w.mExiting && !w.mDestroying) {
if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ w.isDrawnLw()
+ ", isAnimating=" + winAnimator.isAnimating());
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s="
+ winAnimator.mSurfaceControl
+ " pv=" + w.mPolicyVisibility
+ " mDrawState=" + winAnimator.drawStateToString()
+ " ah=" + w.mAttachedHidden
+ " th=" + atoken.hiddenRequested
+ " a=" + winAnimator.mAnimating);
}
}
if (w != atoken.startingWindow) {
if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
atoken.numInterestingWindows++;
if (w.isDrawnLw()) {
atoken.numDrawnWindows++;
if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Slog.v(TAG, "tokenMayBeDrawn: " + atoken
+ " freezingScreen="
+ atoken.mAppAnimator.freezingScreen
+ " mAppFreezing=" + w.mAppFreezing);
updateAllDrawn = true;
}
}
} else if (w.isDrawnLw()) {
atoken.startingDisplayed = true;
}
}
}
if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
&& w.isDisplayedLw()) {
focusDisplayed = true;
}
mService.updateResizingWindows(w);
}
mService.mDisplayManagerInternal.setDisplayProperties(displayId,
mDisplayHasContent,
mPreferredRefreshRate,
mPreferredModeId,
true /* inTraversal, must call performTraversalInTrans... below */);
mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
if (updateAllDrawn) {
updateAllDrawnLocked(displayContent);
}
}
if (focusDisplayed) {
mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
}
// Give the display manager a chance to adjust properties
// like display rotation if it needs to.
mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
}
boolean isInLayout() {
return mInLayout;
}
@@ -1514,4 +1507,15 @@ class WindowSurfacePlacer {
return doRequest;
}
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mService.mH.sendEmptyMessage(DO_TRAVERSAL);
}
}
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
}
}