Destroy docked divider surface when it's hidden.
Also includes bunch of small refactorings:
* destroying surfaces is now fully contained within
WindowManagerServices and mDestroySurface can be privatized;
* WMS.isDockedStackResizingLocked can be removed;
* mScreenCaptureDisabled changes from being SparseArray<Boolean> to
SparseBooleanArray, which not only avoids boxing but also makes code
simpler (no need to check for null)
Bug: 25844096
Change-Id: I0e5462760ffbc947ce6dc52ef429fa270ffc6786
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c7fccc3..685ec49 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -110,6 +110,7 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.TypedValue;
@@ -405,7 +406,7 @@
/**
* Windows whose surface should be destroyed.
*/
- final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
+ private final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
/**
* Windows with a preserved surface waiting to be destroyed. These windows
@@ -442,11 +443,11 @@
WindowState[] mRebuildTmp = new WindowState[20];
/**
- * Stores for each user whether screencapture is disabled
+ * Stores for each user whether screencapture is disabled for all their windows.
* This array is essentially a cache for all userId for
* {@link android.app.admin.DevicePolicyManager#getScreenCaptureDisabled}
*/
- SparseArray<Boolean> mScreenCaptureDisabled = new SparseArray<>();
+ private SparseBooleanArray mScreenCaptureDisabled = new SparseBooleanArray();
IInputMethodManager mInputMethodManager;
@@ -2107,25 +2108,11 @@
executeAppTransition();
}
- /**
- * Returns whether screen capture is disabled for all windows of a specific user.
- */
- boolean isScreenCaptureDisabledLocked(int userId) {
- Boolean disabled = mScreenCaptureDisabled.get(userId);
- if (disabled == null) {
- return false;
- }
- return disabled;
- }
-
boolean isSecureLocked(WindowState w) {
- if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ if ((w.mAttrs.flags & FLAG_SECURE) != 0) {
return true;
}
- if (isScreenCaptureDisabledLocked(UserHandle.getUserId(w.mOwnerUid))) {
- return true;
- }
- return false;
+ return mScreenCaptureDisabled.get(UserHandle.getUserId(w.mOwnerUid));
}
/**
@@ -2649,8 +2636,10 @@
Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
+ " newVis=" + viewVisibility, stack);
}
- if (viewVisibility == View.VISIBLE &&
- (win.mAppToken == null || !win.mAppToken.clientHidden)) {
+ final AppWindowToken appToken = win.mAppToken;
+ final boolean visible = viewVisibility == View.VISIBLE
+ && (appToken == null ? win.mPolicyVisibility : !appToken.clientHidden);
+ if (visible) {
result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges,
oldVisibility);
try {
@@ -2736,8 +2725,8 @@
mWallpaperControllerLocked.updateWallpaperOffset(
win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
}
- if (win.mAppToken != null) {
- win.mAppToken.updateReportedVisibilityLocked();
+ if (appToken != null) {
+ appToken.updateReportedVisibilityLocked();
}
if (winAnimator.mReportSurfaceResized) {
winAnimator.mReportSurfaceResized = false;
@@ -2864,7 +2853,7 @@
win.setDragResizing();
// We can only change top level windows to the full-screen surface when
// resizing (as we only have one full-screen surface). So there is no need
- // to preserve and destroy windows which are attached to another, they
+ // to preserve and destroy windows which are attached to another, they
// will keep their surface and its size may change over time.
if (win.mHasSurface && win.mAttachedWindow == null) {
winAnimator.preserveSurfaceLocked();
@@ -10150,14 +10139,33 @@
}
}
- boolean isDockedStackResizingLocked() {
- return getDefaultDisplayContentLocked().getDockedDividerController().isResizing();
- }
-
static int dipToPixel(int dip, DisplayMetrics displayMetrics) {
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
}
+ void scheduleSurfaceDestroy(WindowState win) {
+ mDestroySurface.add(win);
+ }
+
+ boolean destroySurfacesLocked() {
+ boolean wallpaperDestroyed = false;
+ for (int i = mDestroySurface.size() - 1; i >= 0; i--) {
+ WindowState win = mDestroySurface.get(i);
+ win.mDestroying = false;
+ if (mInputMethodWindow == win) {
+ mInputMethodWindow = null;
+ }
+ if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
+ wallpaperDestroyed = true;
+ }
+ if (!win.shouldSaveSurface()) {
+ win.mWinAnimator.destroySurfaceLocked();
+ }
+ }
+ mDestroySurface.clear();
+ return wallpaperDestroyed;
+ }
+
private final class LocalService extends WindowManagerInternal {
@Override
public void requestTraversalFromDisplayManager() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 01db707..3aa088d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -411,6 +411,10 @@
final private Rect mTmpRect = new Rect();
+ // This window often remains added but hidden, so we want to destroy its surface when it's not
+ // visible.
+ private final boolean mDestroySurfaceWhenHidden;
+
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, final DisplayContent displayContent) {
@@ -458,6 +462,7 @@
mSubLayer = 0;
mInputWindowHandle = null;
mWinAnimator = null;
+ mDestroySurfaceWhenHidden = false;
return;
}
mDeathRecipient = deathRecipient;
@@ -556,6 +561,7 @@
mInputWindowHandle = new InputWindowHandle(
mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,
displayContent.getDisplayId());
+ mDestroySurfaceWhenHidden = mAttrs.type == TYPE_DOCK_DIVIDER;
}
void attach() {
@@ -1313,6 +1319,10 @@
mHasSurface = hasSurface;
}
+ boolean shouldDestroySurfaceWhenAnimationFinishes() {
+ return mExiting || (mDestroySurfaceWhenHidden && !mPolicyVisibilityAfterAnim);
+ }
+
private final class DeadWindowEventReceiver extends InputEventReceiver {
DeadWindowEventReceiver(InputChannel inputChannel) {
super(inputChannel, mService.mH.getLooper());
@@ -1589,6 +1599,10 @@
// Already showing.
return false;
}
+ if (!mHasSurface) {
+ mDestroying = false;
+ mWinAnimator.createSurfaceLocked();
+ }
if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
if (doAnimation) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
@@ -1624,8 +1638,7 @@
doAnimation = false;
}
}
- boolean current = doAnimation ? mPolicyVisibilityAfterAnim
- : mPolicyVisibility;
+ final boolean current = doAnimation ? mPolicyVisibilityAfterAnim : mPolicyVisibility;
if (!current) {
// Already hiding.
return false;
@@ -1636,11 +1649,9 @@
doAnimation = false;
}
}
- if (doAnimation) {
- mPolicyVisibilityAfterAnim = false;
- } else {
+ mPolicyVisibilityAfterAnim = false;
+ if (!doAnimation) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
- mPolicyVisibilityAfterAnim = false;
mPolicyVisibility = false;
// Window is no longer visible -- make sure if we were waiting
// for it to be displayed before enabling the display, that
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 93c2ff6..9726034 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -446,7 +446,7 @@
}
}
- if (!mWin.mExiting) {
+ if (!mWin.shouldDestroySurfaceWhenAnimationFinishes()) {
return;
}
@@ -454,12 +454,13 @@
return;
}
- if (WindowManagerService.localLOGV) Slog.v(
- TAG, "Exit animation finished in " + this
- + ": remove=" + mWin.mRemoveOnExit);
+ if (localLOGV) Slog.v(TAG, "Exit animation finished in " + this + ": remove="
+ + mWin.mRemoveOnExit);
if (mSurfaceController != null && mSurfaceController.hasSurface()) {
- mService.mDestroySurface.add(mWin);
- mWin.mDestroying = true;
+ mService.scheduleSurfaceDestroy(mWin);
+ if (mWin.mExiting) {
+ mWin.mDestroying = true;
+ }
hide("finishExit");
}
mWin.mExiting = false;
@@ -645,7 +646,7 @@
return null;
}
- if (WindowManagerService.localLOGV) {
+ if (localLOGV) {
Slog.v(TAG, "Got surface: " + mSurfaceController
+ ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
+ ", animLayer=" + mAnimLayer);
@@ -666,7 +667,7 @@
mAnimLayer);
mLastHidden = true;
- if (WindowManagerService.localLOGV) Slog.v(
+ if (localLOGV) Slog.v(
TAG, "Created surface " + this);
}
return mSurfaceController;
@@ -973,7 +974,7 @@
//Slog.i(TAG, "Not applying alpha transform");
}
- if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
+ if ((DEBUG_SURFACE_TRACE || localLOGV)
&& (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
+ " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
@@ -994,7 +995,7 @@
return;
}
- if (WindowManagerService.localLOGV) Slog.v(
+ if (localLOGV) Slog.v(
TAG, "computeShownFrameLocked: " + this +
" not attached, mAlpha=" + mAlpha);
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index f8b8d6c..b3c23d1 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -296,10 +296,8 @@
}
boolean showRobustlyInTransaction() {
- if (SHOW_TRANSACTIONS) logSurface(
- "SHOW (performLayout)", null);
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
- + " during relayout");
+ if (SHOW_TRANSACTIONS) logSurface("SHOW (performLayout)", null);
+ if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this + " during relayout");
if (mHiddenForCrop) {
return false;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 6292c21..da7f45e 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -381,25 +381,7 @@
}
// Destroy the surface of any windows that are no longer visible.
- boolean wallpaperDestroyed = false;
- i = mService.mDestroySurface.size();
- if (i > 0) {
- do {
- i--;
- WindowState win = mService.mDestroySurface.get(i);
- win.mDestroying = false;
- if (mService.mInputMethodWindow == win) {
- mService.mInputMethodWindow = null;
- }
- if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
- wallpaperDestroyed = true;
- }
- if (!win.shouldSaveSurface()) {
- win.mWinAnimator.destroySurfaceLocked();
- }
- } while (i > 0);
- mService.mDestroySurface.clear();
- }
+ final boolean wallpaperDestroyed = mService.destroySurfacesLocked();
// Time to remove any exiting tokens?
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {