summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Filip Gruszczynski <gruszczy@google.com> 2015-11-09 20:13:12 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2015-11-09 20:13:12 +0000
commit2f40db7357edfc0ccd7753a53b470a161dfebbf2 (patch)
treed344dbe5198d9dae9efe5f487741085f94b0d563
parenta8d3e1ff63078741495f6b339d310ab66c124abc (diff)
parent78a08ee876794586e1d429e67d4b94209415ea5a (diff)
Merge "Fix blink when docking a window."
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java98
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfacePlacer.java14
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) {