diff options
| author | 2015-11-09 20:13:12 +0000 | |
|---|---|---|
| committer | 2015-11-09 20:13:12 +0000 | |
| commit | 2f40db7357edfc0ccd7753a53b470a161dfebbf2 (patch) | |
| tree | d344dbe5198d9dae9efe5f487741085f94b0d563 | |
| parent | a8d3e1ff63078741495f6b339d310ab66c124abc (diff) | |
| parent | 78a08ee876794586e1d429e67d4b94209415ea5a (diff) | |
Merge "Fix blink when docking a window."
7 files changed, 95 insertions, 46 deletions
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index f048da08700b..425ff9b93b1c 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -133,6 +133,9 @@ class AppWindowToken extends WindowToken { // If not null, the window that will be used to replace the old one. This is being set when // the window is added and unset when this window reports its first draw. WindowState mReplacingWindow; + // Whether the new window has replaced the old one, so the old one can be removed without + // blinking. + boolean mHasReplacedWindow; AppWindowToken(WindowManagerService _service, IApplicationToken _token, boolean _voiceInteraction) { diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 228da0f3d6ee..38bd71dcc4c1 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -18,29 +18,35 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; - import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static com.android.server.wm.WindowManagerService.DEBUG_ANIM; +import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD; -import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION; -import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE; +import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS; +import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION; +import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; +import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER; +import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_TRACE; +import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; +import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION; import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING; +import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE; import android.content.Context; -import android.os.RemoteException; import android.os.Trace; import android.util.Slog; import android.util.SparseArray; import android.util.TimeUtils; +import android.view.Choreographer; import android.view.Display; import android.view.SurfaceControl; import android.view.WindowManagerPolicy; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; -import android.view.Choreographer; import java.io.PrintWriter; import java.util.ArrayList; @@ -101,6 +107,10 @@ public class WindowAnimator { static final int KEYGUARD_ANIMATING_OUT = 2; int mForceHiding = KEYGUARD_NOT_SHOWN; + // When set to true the animator will go over all windows after an animation frame is posted and + // check if some got replaced and can be removed. + private boolean mRemoveReplacedWindows = false; + private String forceHidingToString() { switch (mForceHiding) { case KEYGUARD_NOT_SHOWN: return "KEYGUARD_NOT_SHOWN"; @@ -164,7 +174,7 @@ public class WindowAnimator { setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, "appToken " + appAnimator.mAppToken + " done", displayId); - if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, + if (DEBUG_ANIM) Slog.v(TAG, "updateWindowsApps...: done animating " + appAnimator.mAppToken); } } @@ -182,7 +192,7 @@ public class WindowAnimator { setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, "exiting appToken " + appAnimator.mAppToken + " done", displayId); - if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, + if (DEBUG_ANIM) Slog.v(TAG, "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); } @@ -274,7 +284,7 @@ public class WindowAnimator { winAnimator.mWasAnimating = nowAnimating; mAnimating |= nowAnimating; - if (WindowManagerService.DEBUG_WALLPAPER) { + if (DEBUG_WALLPAPER) { Slog.v(TAG, win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating); } @@ -284,7 +294,7 @@ public class WindowAnimator { mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; setPendingLayoutChanges(Display.DEFAULT_DISPLAY, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + if (DEBUG_LAYOUT_REPEATS) { mWindowPlacerLocked.debugLayoutRepeats( "updateWindowsAndWallpaperLocked 2", getPendingLayoutChanges(Display.DEFAULT_DISPLAY)); @@ -293,13 +303,13 @@ public class WindowAnimator { if (mPolicy.isForceHiding(win.mAttrs)) { if (!wasAnimating && nowAnimating) { - if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_ANIM || - WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + if (DEBUG_KEYGUARD || DEBUG_ANIM || + DEBUG_VISIBILITY) Slog.v(TAG, "Animation started that could impact force hide: " + win); mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED; setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + if (DEBUG_LAYOUT_REPEATS) { mWindowPlacerLocked.debugLayoutRepeats( "updateWindowsAndWallpaperLocked 3", getPendingLayoutChanges(displayId)); @@ -318,7 +328,7 @@ public class WindowAnimator { mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN; } } - if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG, "Force hide " + forceHidingToString() + " hasSurface=" + win.mHasSurface + " policyVis=" + win.mPolicyVisibility @@ -333,7 +343,7 @@ public class WindowAnimator { // Was already hidden continue; } - if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG, "Now policy hidden: " + win); } else { boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null @@ -355,7 +365,7 @@ public class WindowAnimator { win.hideLw(false, false); continue; } - if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, + if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG, "Now policy shown: " + win); if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0 && win.mAttachedWindow == null) { @@ -385,7 +395,7 @@ public class WindowAnimator { // We are showing on top of the current // focus, so re-evaluate focus to make // sure it is correct. - if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG, + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "updateWindowsLocked: setting mFocusMayChange true"); mService.mFocusMayChange = true; } @@ -394,7 +404,7 @@ public class WindowAnimator { mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; setPendingLayoutChanges(Display.DEFAULT_DISPLAY, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + if (DEBUG_LAYOUT_REPEATS) { mWindowPlacerLocked.debugLayoutRepeats( "updateWindowsAndWallpaperLocked 4", getPendingLayoutChanges(Display.DEFAULT_DISPLAY)); @@ -419,7 +429,7 @@ public class WindowAnimator { if (winAnimator.performShowLocked()) { setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + if (DEBUG_LAYOUT_REPEATS) { mWindowPlacerLocked.debugLayoutRepeats( "updateWindowsAndWallpaperLocked 5", getPendingLayoutChanges(displayId)); @@ -561,7 +571,7 @@ public class WindowAnimator { } // end forall windows if (mWindowDetachedWallpaper != detachedWallpaper) { - if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, + if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from " + mWindowDetachedWallpaper + " to " + detachedWallpaper); mWindowDetachedWallpaper = detachedWallpaper; @@ -591,7 +601,7 @@ public class WindowAnimator { if (appAnimator.freezingScreen) { appAnimator.showAllWindowsLocked(); mService.unsetAppFreezingScreenLocked(wtoken, false, true); - if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG, + if (DEBUG_ORIENTATION) Slog.i(TAG, "Setting mOrientationChangeComplete=true because wtoken " + wtoken + " numInteresting=" + wtoken.numInterestingWindows + " numDrawn=" + wtoken.numDrawnWindows); @@ -628,11 +638,11 @@ public class WindowAnimator { boolean wasAnimating = mAnimating; mAnimating = false; mAppWindowAnimating = false; - if (WindowManagerService.DEBUG_WINDOW_TRACE) { + if (DEBUG_WINDOW_TRACE) { Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); } - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( + if (SHOW_TRANSACTIONS) Slog.i( TAG, ">>> OPEN TRANSACTION animateLocked"); SurfaceControl.openTransaction(); SurfaceControl.setAnimationTransaction(); @@ -707,7 +717,7 @@ public class WindowAnimator { Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { SurfaceControl.closeTransaction(); - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( + if (SHOW_TRANSACTIONS) Slog.i( TAG, "<<< CLOSE TRANSACTION animateLocked"); } @@ -744,14 +754,38 @@ public class WindowAnimator { } } + if (mRemoveReplacedWindows) { + removeReplacedWindowsLocked(); + } + mService.destroyPreservedSurfaceLocked(); - if (WindowManagerService.DEBUG_WINDOW_TRACE) { + if (DEBUG_WINDOW_TRACE) { Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating - + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) - + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" - + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY))); + + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) + + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" + + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY))); + } + } + + private void removeReplacedWindowsLocked() { + if (SHOW_TRANSACTIONS) Slog.i( + TAG, ">>> OPEN TRANSACTION removeReplacedWindows"); + SurfaceControl.openTransaction(); + try { + for (int i = mService.mDisplayContents.size() - 1; i >= 0; i--) { + DisplayContent display = mService.mDisplayContents.get(i); + final WindowList windows = mService.getWindowListLocked(display.getDisplayId()); + for (int j = windows.size() - 1; j >= 0; j--) { + windows.get(j).maybeRemoveReplacedWindow(); + } + } + } finally { + SurfaceControl.closeTransaction(); + if (SHOW_TRANSACTIONS) Slog.i( + TAG, "<<< CLOSE TRANSACTION removeReplacedWindows"); } + mRemoveReplacedWindows = false; } private static String bulkUpdateParamsToString(int bulkUpdateParams) { @@ -844,7 +878,7 @@ public class WindowAnimator { for (int i = windows.size() - 1; i >= 0; i--) { if (displayId == windows.get(i).getDisplayId()) { setPendingLayoutChanges(displayId, changes); - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + if (DEBUG_LAYOUT_REPEATS) { mWindowPlacerLocked.debugLayoutRepeats(reason, getPendingLayoutChanges(displayId)); } @@ -875,6 +909,14 @@ public class WindowAnimator { return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation; } + void requestRemovalOfReplacedWindows(WindowState win) { + final AppWindowToken token = win.mAppToken; + if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == win) { + token.mHasReplacedWindow = true; + } + mRemoveReplacedWindows = true; + } + private class DisplayContentsAnimator { ScreenRotationAnimation mScreenRotationAnimation = null; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5e68aa2d4aae..87ad1f889d85 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -57,7 +57,6 @@ import android.animation.ValueAnimator; import android.app.ActivityManagerNative; import android.app.AppOpsManager; import android.app.IActivityManager; -import android.app.StatusBarManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -226,6 +225,7 @@ public class WindowManagerService extends IWindowManager.Stub static final boolean SHOW_SURFACE_ALLOC = false; static final boolean SHOW_TRANSACTIONS = false; static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS; + static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS; static final boolean HIDE_STACK_CRAWLS = true; static final int LAYOUT_REPEAT_THRESHOLD = 4; @@ -5627,7 +5627,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation"); SurfaceControl.openTransaction(); try { @@ -5639,7 +5639,7 @@ public class WindowManagerService extends IWindowManager.Stub mStrictModeFlash.setVisibility(on); } finally { SurfaceControl.closeTransaction(); - if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation"); } } @@ -10116,6 +10116,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Marking app token " + appWindowToken + " as replacing window."); appWindowToken.mWillReplaceWindow = true; + appWindowToken.mHasReplacedWindow = false; appWindowToken.mAnimateReplacingWindow = animate; } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index a7aa9e14a6e4..c7b638cfa0c3 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1374,14 +1374,16 @@ final class WindowState implements WindowManagerPolicy.WindowState { void maybeRemoveReplacedWindow() { AppWindowToken token = mAppToken; - if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this) { + if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this + && token.mHasReplacedWindow) { if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replacing window: " + this); token.mWillReplaceWindow = false; token.mAnimateReplacingWindow = false; token.mReplacingRemoveRequested = false; token.mReplacingWindow = null; + token.mHasReplacedWindow = false; for (int i = token.allAppWindows.size() - 1; i >= 0; i--) { - WindowState win = token.allAppWindows.get(i); + final WindowState win = token.allAppWindows.get(i); if (win.mExiting) { mService.removeWindowInnerLocked(win); } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 91755ac879b0..81d0b4d26b38 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1287,6 +1287,7 @@ class WindowStateAnimator { if (prepared && mLastHidden && mDrawState == HAS_DRAWN) { if (showSurfaceRobustlyLocked()) { + mAnimator.requestRemovalOfReplacedWindows(w); mLastHidden = false; if (mIsWallpaper) { mWallpaperControllerLocked.dispatchWallpaperVisibility(w, true); @@ -1472,12 +1473,8 @@ class WindowStateAnimator { } mWin.mAppToken.updateReportedVisibilityLocked(); } - - mWin.maybeRemoveReplacedWindow(); - return true; } - return false; } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 2e2be5c48972..f8b8d6ced8d8 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -23,7 +23,6 @@ import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE; import static com.android.server.wm.WindowManagerService.HIDE_STACK_CRAWLS; import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; -import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -57,7 +56,6 @@ class WindowSurfaceController { private float mSurfaceAlpha = 0; private int mSurfaceLayer = 0; - private int mSurfaceFormat; // Surface flinger doesn't support crop rectangles where width or height is non-positive. // However, we need to somehow handle the situation where the cropping would completely hide @@ -72,7 +70,6 @@ class WindowSurfaceController { mSurfaceW = w; mSurfaceH = h; - mSurfaceFormat = format; title = name; @@ -389,6 +386,11 @@ class WindowSurfaceController { pw.print(" x "); pw.println(mSurfaceH); } + @Override + public String toString() { + return mSurfaceControl.toString(); + } + static class SurfaceTrace extends SurfaceControl { private final static String SURFACE_TAG = "SurfaceTrace"; private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE; diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 1f49e97294cd..92ea66bc94a7 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1190,9 +1190,13 @@ class WindowSurfacePlacer { int layer = -1; for (int j = 0; j < wtoken.windows.size(); j++) { final WindowState win = wtoken.windows.get(j); - // Clearing the mExiting flag before entering animation. It will be set - // to true if app window is removed, or window relayout to invisible. - win.mExiting = false; + // Clearing the mExiting flag before entering animation. It will be set to true + // if app window is removed, or window relayout to invisible. We don't want to + // clear it out for windows that get replaced, because the animation depends on + // the flag to remove the replaced window. + if (win.mAppToken == null || !win.mAppToken.mWillReplaceWindow) { + win.mExiting = false; + } if (win.mWinAnimator.mAnimLayer > layer) { layer = win.mWinAnimator.mAnimLayer; } @@ -1232,9 +1236,7 @@ class WindowSurfacePlacer { true /*updateInputWindows*/); mService.mFocusMayChange = false; mService.notifyActivityDrawnForKeyguard(); - return FINISH_LAYOUT_REDO_LAYOUT - | FINISH_LAYOUT_REDO_CONFIG; - + return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG; } private boolean transitionGoodToGo(int appsCount) { |