From cb5f57bc580d7f73b93c8f504daa4dcd74cdce72 Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Mon, 23 Nov 2015 17:57:03 -0800 Subject: [PATCH] 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 to SparseBooleanArray, which not only avoids boxing but also makes code simpler (no need to check for null) Bug: 25844096 Change-Id: I0e5462760ffbc947ce6dc52ef429fa270ffc6786 --- .../server/wm/WindowManagerService.java | 64 +++++++++++-------- .../com/android/server/wm/WindowState.java | 23 +++++-- .../server/wm/WindowStateAnimator.java | 21 +++--- .../server/wm/WindowSurfaceController.java | 6 +- .../server/wm/WindowSurfacePlacer.java | 20 +----- 5 files changed, 67 insertions(+), 67 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c7fccc39c6455..685ec49616874 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.Log; 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 @@ public class WindowManagerService extends IWindowManager.Stub /** * Windows whose surface should be destroyed. */ - final ArrayList mDestroySurface = new ArrayList<>(); + private final ArrayList mDestroySurface = new ArrayList<>(); /** * Windows with a preserved surface waiting to be destroyed. These windows @@ -442,11 +443,11 @@ public class WindowManagerService extends IWindowManager.Stub 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 mScreenCaptureDisabled = new SparseArray<>(); + private SparseBooleanArray mScreenCaptureDisabled = new SparseBooleanArray(); IInputMethodManager mInputMethodManager; @@ -2107,25 +2108,11 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } } - 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 01db707051b8c..3aa088d4ce50d 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 class WindowState implements WindowManagerPolicy.WindowState { 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 @@ final class WindowState implements WindowManagerPolicy.WindowState { mSubLayer = 0; mInputWindowHandle = null; mWinAnimator = null; + mDestroySurfaceWhenHidden = false; return; } mDeathRecipient = deathRecipient; @@ -556,6 +561,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mInputWindowHandle = new InputWindowHandle( mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, displayContent.getDisplayId()); + mDestroySurfaceWhenHidden = mAttrs.type == TYPE_DOCK_DIVIDER; } void attach() { @@ -1313,6 +1319,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { 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 @@ final class WindowState implements WindowManagerPolicy.WindowState { // 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 @@ final class WindowState implements WindowManagerPolicy.WindowState { doAnimation = false; } } - boolean current = doAnimation ? mPolicyVisibilityAfterAnim - : mPolicyVisibility; + final boolean current = doAnimation ? mPolicyVisibilityAfterAnim : mPolicyVisibility; if (!current) { // Already hiding. return false; @@ -1636,11 +1649,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { 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 93c2ff608442e..9726034d0c0f1 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 @@ class WindowStateAnimator { } } - if (!mWin.mExiting) { + if (!mWin.shouldDestroySurfaceWhenAnimationFinishes()) { return; } @@ -454,12 +454,13 @@ class WindowStateAnimator { 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 @@ class WindowStateAnimator { 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 @@ class WindowStateAnimator { mAnimLayer); mLastHidden = true; - if (WindowManagerService.localLOGV) Slog.v( + if (localLOGV) Slog.v( TAG, "Created surface " + this); } return mSurfaceController; @@ -973,7 +974,7 @@ class WindowStateAnimator { //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 @@ class WindowStateAnimator { 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 f8b8d6ced8d84..b3c23d1a8ab0a 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 @@ class WindowSurfaceController { } 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 6292c21910cf8..da7f45edc37c0 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 @@ class WindowSurfacePlacer { } // 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) {