Loading services/core/java/com/android/server/wm/DisplayContent.java +2 −4 Original line number Diff line number Diff line Loading @@ -141,8 +141,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; /** * Utility class for keeping track of the WindowStates and other pertinent contents of a Loading Loading @@ -2546,7 +2544,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (!obscured) { final boolean isDisplayed = w.isDisplayedLw(); if (isDisplayed && w.isObscuringFullscreen(mDisplayInfo)) { if (isDisplayed && w.isObscuringDisplay()) { // This window completely covers everything behind it, so we want to leave all // of them as undimmed (for performance reasons). root.mObscuringWindow = w; Loading Loading @@ -2945,7 +2943,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo screenshotReady = true; } if (ws.isObscuringFullscreen(mDisplayInfo)){ if (ws.isObscuringDisplay()){ break; } } Loading services/core/java/com/android/server/wm/WindowLayersController.java +24 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ class WindowLayersController { private boolean mAnyLayerChanged; private int mHighestLayerInImeTargetBaseLayer; private WindowState mImeTarget; private boolean mAboveImeTarget; private ArrayDeque<WindowState> mAboveImeTargetAppWindows = new ArrayDeque(); final void assignWindowLayers(DisplayContent dc) { if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based", Loading Loading @@ -143,6 +145,8 @@ class WindowLayersController { mImeTarget = mService.mInputMethodTarget; mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0; mAboveImeTarget = false; mAboveImeTargetAppWindows.clear(); } private void collectSpecialWindows(WindowState w) { Loading @@ -157,6 +161,20 @@ class WindowLayersController { mInputMethodWindows.add(w); return; } if (mImeTarget != null) { if (w.getParentWindow() == mImeTarget && w.mSubLayer > 0) { // Child windows of the ime target with a positive sub-layer should be placed above // the IME. mAboveImeTargetAppWindows.add(w); } else if (mAboveImeTarget && w.mAppToken != null) { // windows of apps above the IME target should be placed above the IME. mAboveImeTargetAppWindows.add(w); } if (w == mImeTarget) { mAboveImeTarget = true; } } final Task task = w.getTask(); if (task == null) { return; Loading Loading @@ -211,6 +229,12 @@ class WindowLayersController { while (!mInputMethodWindows.isEmpty()) { layer = assignAndIncreaseLayerIfNeeded(mInputMethodWindows.remove(), layer); } // Adjust app windows the should be displayed above the IME since they are above the IME // target. while (!mAboveImeTargetAppWindows.isEmpty()) { layer = assignAndIncreaseLayerIfNeeded(mAboveImeTargetAppWindows.remove(), layer); } } } Loading services/core/java/com/android/server/wm/WindowState.java +4 −9 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedList; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import static android.app.ActivityManager.StackId; Loading Loading @@ -91,7 +89,6 @@ import static android.view.WindowManager.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; Loading Loading @@ -1654,18 +1651,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP && (!mIsChildWindow || !getParentWindow().hasMoved()); } boolean isObscuringFullscreen(final DisplayInfo displayInfo) { boolean isObscuringDisplay() { Task task = getTask(); if (task != null && task.mStack != null && !task.mStack.fillsParent()) { return false; } if (!isOpaqueDrawn() || !isFrameFullscreen(displayInfo)) { return false; } return true; return isOpaqueDrawn() && fillsDisplay(); } boolean isFrameFullscreen(final DisplayInfo displayInfo) { boolean fillsDisplay() { final DisplayInfo displayInfo = getDisplayInfo(); return mFrame.left <= 0 && mFrame.top <= 0 && mFrame.right >= displayInfo.appWidth && mFrame.bottom >= displayInfo.appHeight; } Loading services/core/java/com/android/server/wm/WindowStateAnimator.java +3 −6 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ import android.os.Trace; import android.util.Slog; import android.view.DisplayInfo; import android.view.MagnificationSpec; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.WindowManager; Loading Loading @@ -1108,10 +1107,9 @@ class WindowStateAnimator { /** * Calculate the window-space crop rect and fill clipRect. * @return true if clipRect has been filled otherwise, no window space * crop should be applied. * @return true if clipRect has been filled otherwise, no window space crop should be applied. */ boolean calculateCrop(Rect clipRect) { private boolean calculateCrop(Rect clipRect) { final WindowState w = mWin; final DisplayContent displayContent = w.getDisplayContent(); clipRect.setEmpty(); Loading @@ -1130,7 +1128,6 @@ class WindowStateAnimator { return false; } final DisplayInfo displayInfo = displayContent.getDisplayInfo(); if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Updating crop win=" + w + " mLastCrop=" + mLastClipRect); Loading @@ -1139,7 +1136,7 @@ class WindowStateAnimator { if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame=" + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect); final boolean fullscreen = w.isFrameFullscreen(displayInfo); final boolean fullscreen = w.fillsDisplay(); final boolean isFreeformResizing = w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM; Loading services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java +57 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; Loading Loading @@ -120,6 +121,62 @@ public class WindowLayersControllerTests extends WindowTestsBase { assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow); } @Test public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception { final WindowState imeAppTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget"); final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget, TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken, "imeAppTargetChildAboveWindow"); final WindowState imeAppTargetChildBelowWindow = createWindow(imeAppTarget, TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken, "imeAppTargetChildBelowWindow"); sWm.mInputMethodTarget = imeAppTarget; sLayersController.assignWindowLayers(sDisplayContent); // Ime should be above all app windows except for child windows that are z-ordered above it // and below system windows if it is targeting an app window. assertWindowLayerGreaterThan(sImeWindow, imeAppTarget); assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, sImeWindow); assertWindowLayerGreaterThan(sImeWindow, imeAppTargetChildBelowWindow); assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow); assertWindowLayerGreaterThan(sImeWindow, sAppWindow); assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow); assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow); assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow); // And, IME dialogs should always have an higher layer than the IME. assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow); } @Test public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception { final WindowState appBelowImeTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appBelowImeTarget"); final WindowState imeAppTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget"); final WindowState appAboveImeTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appAboveImeTarget"); sWm.mInputMethodTarget = imeAppTarget; sLayersController.assignWindowLayers(sDisplayContent); // Ime should be above all app windows except for non-fullscreen app window above it and // below system windows if it is targeting an app window. assertWindowLayerGreaterThan(sImeWindow, imeAppTarget); assertWindowLayerGreaterThan(sImeWindow, appBelowImeTarget); assertWindowLayerGreaterThan(appAboveImeTarget, sImeWindow); assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow); assertWindowLayerGreaterThan(sImeWindow, sAppWindow); assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow); assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow); assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow); // And, IME dialogs should always have an higher layer than the IME. assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow); } @Test public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception { final WindowState imeSystemOverlayTarget = Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +2 −4 Original line number Diff line number Diff line Loading @@ -141,8 +141,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; /** * Utility class for keeping track of the WindowStates and other pertinent contents of a Loading Loading @@ -2546,7 +2544,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (!obscured) { final boolean isDisplayed = w.isDisplayedLw(); if (isDisplayed && w.isObscuringFullscreen(mDisplayInfo)) { if (isDisplayed && w.isObscuringDisplay()) { // This window completely covers everything behind it, so we want to leave all // of them as undimmed (for performance reasons). root.mObscuringWindow = w; Loading Loading @@ -2945,7 +2943,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo screenshotReady = true; } if (ws.isObscuringFullscreen(mDisplayInfo)){ if (ws.isObscuringDisplay()){ break; } } Loading
services/core/java/com/android/server/wm/WindowLayersController.java +24 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ class WindowLayersController { private boolean mAnyLayerChanged; private int mHighestLayerInImeTargetBaseLayer; private WindowState mImeTarget; private boolean mAboveImeTarget; private ArrayDeque<WindowState> mAboveImeTargetAppWindows = new ArrayDeque(); final void assignWindowLayers(DisplayContent dc) { if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based", Loading Loading @@ -143,6 +145,8 @@ class WindowLayersController { mImeTarget = mService.mInputMethodTarget; mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0; mAboveImeTarget = false; mAboveImeTargetAppWindows.clear(); } private void collectSpecialWindows(WindowState w) { Loading @@ -157,6 +161,20 @@ class WindowLayersController { mInputMethodWindows.add(w); return; } if (mImeTarget != null) { if (w.getParentWindow() == mImeTarget && w.mSubLayer > 0) { // Child windows of the ime target with a positive sub-layer should be placed above // the IME. mAboveImeTargetAppWindows.add(w); } else if (mAboveImeTarget && w.mAppToken != null) { // windows of apps above the IME target should be placed above the IME. mAboveImeTargetAppWindows.add(w); } if (w == mImeTarget) { mAboveImeTarget = true; } } final Task task = w.getTask(); if (task == null) { return; Loading Loading @@ -211,6 +229,12 @@ class WindowLayersController { while (!mInputMethodWindows.isEmpty()) { layer = assignAndIncreaseLayerIfNeeded(mInputMethodWindows.remove(), layer); } // Adjust app windows the should be displayed above the IME since they are above the IME // target. while (!mAboveImeTargetAppWindows.isEmpty()) { layer = assignAndIncreaseLayerIfNeeded(mAboveImeTargetAppWindows.remove(), layer); } } } Loading
services/core/java/com/android/server/wm/WindowState.java +4 −9 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedList; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import static android.app.ActivityManager.StackId; Loading Loading @@ -91,7 +89,6 @@ import static android.view.WindowManager.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; Loading Loading @@ -1654,18 +1651,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP && (!mIsChildWindow || !getParentWindow().hasMoved()); } boolean isObscuringFullscreen(final DisplayInfo displayInfo) { boolean isObscuringDisplay() { Task task = getTask(); if (task != null && task.mStack != null && !task.mStack.fillsParent()) { return false; } if (!isOpaqueDrawn() || !isFrameFullscreen(displayInfo)) { return false; } return true; return isOpaqueDrawn() && fillsDisplay(); } boolean isFrameFullscreen(final DisplayInfo displayInfo) { boolean fillsDisplay() { final DisplayInfo displayInfo = getDisplayInfo(); return mFrame.left <= 0 && mFrame.top <= 0 && mFrame.right >= displayInfo.appWidth && mFrame.bottom >= displayInfo.appHeight; } Loading
services/core/java/com/android/server/wm/WindowStateAnimator.java +3 −6 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ import android.os.Trace; import android.util.Slog; import android.view.DisplayInfo; import android.view.MagnificationSpec; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.WindowManager; Loading Loading @@ -1108,10 +1107,9 @@ class WindowStateAnimator { /** * Calculate the window-space crop rect and fill clipRect. * @return true if clipRect has been filled otherwise, no window space * crop should be applied. * @return true if clipRect has been filled otherwise, no window space crop should be applied. */ boolean calculateCrop(Rect clipRect) { private boolean calculateCrop(Rect clipRect) { final WindowState w = mWin; final DisplayContent displayContent = w.getDisplayContent(); clipRect.setEmpty(); Loading @@ -1130,7 +1128,6 @@ class WindowStateAnimator { return false; } final DisplayInfo displayInfo = displayContent.getDisplayInfo(); if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Updating crop win=" + w + " mLastCrop=" + mLastClipRect); Loading @@ -1139,7 +1136,7 @@ class WindowStateAnimator { if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame=" + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect); final boolean fullscreen = w.isFrameFullscreen(displayInfo); final boolean fullscreen = w.fillsDisplay(); final boolean isFreeformResizing = w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM; Loading
services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java +57 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; Loading Loading @@ -120,6 +121,62 @@ public class WindowLayersControllerTests extends WindowTestsBase { assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow); } @Test public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception { final WindowState imeAppTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget"); final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget, TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken, "imeAppTargetChildAboveWindow"); final WindowState imeAppTargetChildBelowWindow = createWindow(imeAppTarget, TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken, "imeAppTargetChildBelowWindow"); sWm.mInputMethodTarget = imeAppTarget; sLayersController.assignWindowLayers(sDisplayContent); // Ime should be above all app windows except for child windows that are z-ordered above it // and below system windows if it is targeting an app window. assertWindowLayerGreaterThan(sImeWindow, imeAppTarget); assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, sImeWindow); assertWindowLayerGreaterThan(sImeWindow, imeAppTargetChildBelowWindow); assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow); assertWindowLayerGreaterThan(sImeWindow, sAppWindow); assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow); assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow); assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow); // And, IME dialogs should always have an higher layer than the IME. assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow); } @Test public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception { final WindowState appBelowImeTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appBelowImeTarget"); final WindowState imeAppTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget"); final WindowState appAboveImeTarget = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appAboveImeTarget"); sWm.mInputMethodTarget = imeAppTarget; sLayersController.assignWindowLayers(sDisplayContent); // Ime should be above all app windows except for non-fullscreen app window above it and // below system windows if it is targeting an app window. assertWindowLayerGreaterThan(sImeWindow, imeAppTarget); assertWindowLayerGreaterThan(sImeWindow, appBelowImeTarget); assertWindowLayerGreaterThan(appAboveImeTarget, sImeWindow); assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow); assertWindowLayerGreaterThan(sImeWindow, sAppWindow); assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow); assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow); assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow); // And, IME dialogs should always have an higher layer than the IME. assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow); } @Test public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception { final WindowState imeSystemOverlayTarget = Loading