Loading services/core/java/com/android/server/wm/DisplayContent.java +51 −29 Original line number Diff line number Diff line Loading @@ -181,8 +181,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final TaskStackContainers mTaskStackContainers = new TaskStackContainers(); // Contains all non-app window containers that should be displayed above the app containers // (e.g. Status bar) private final NonAppWindowContainers mAboveAppWindowsContainers = new NonAppWindowContainers("mAboveAppWindowsContainers"); private final AboveAppWindowContainers mAboveAppWindowsContainers = new AboveAppWindowContainers("mAboveAppWindowsContainers"); // Contains all non-app window containers that should be displayed below the app containers // (e.g. Wallpaper). private final NonAppWindowContainers mBelowAppWindowsContainers = Loading Loading @@ -356,7 +356,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** * We organize all top-level Surfaces in to the following layers. * mOverlayLayer contains a few Surfaces which are always on top of others * and omitted from Screen-Magnification ({@link WindowState#isScreenOverlay}) * and omitted from Screen-Magnification, for example the strict mode flash or * the magnification overlay itself. * {@link #mWindowingLayer} contains everything else. */ private SurfaceControl mOverlayLayer; Loading Loading @@ -3746,11 +3747,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } private final class AboveAppWindowContainers extends NonAppWindowContainers { AboveAppWindowContainers(String name) { super(name); } void assignChildLayers(SurfaceControl.Transaction t, WindowContainer imeContainer) { boolean needAssignIme = imeContainer != null && imeContainer.getSurfaceControl() != null; for (int j = 0; j < mChildren.size(); ++j) { final WindowToken wt = mChildren.get(j); wt.assignLayer(t, j); wt.assignChildLayers(t); int layer = mService.mPolicy.getWindowLayerFromTypeLw( wt.windowType, wt.mOwnerCanManageAppTokens); if (needAssignIme && layer >= TYPE_INPUT_METHOD_DIALOG) { t.setRelativeLayer(imeContainer.getSurfaceControl(), wt.getSurfaceControl(), -1); needAssignIme = false; } } if (needAssignIme) { t.setRelativeLayer(imeContainer.getSurfaceControl(), getSurfaceControl(), Integer.MIN_VALUE); } } } /** * Window container class that contains all containers on this display that are not related to * Apps. E.g. status bar. */ private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> { private class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> { /** * Compares two child window tokens returns -1 if the first is lesser than the second in * terms of z-order and 1 otherwise. Loading Loading @@ -3848,12 +3877,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return b; } b.setName(child.getName()); if (child.isScreenOverlay()) { return b.setParent(mOverlayLayer); } else { return b.setParent(mWindowingLayer); } return b.setName(child.getName()) .setParent(mWindowingLayer); } /** Loading Loading @@ -3891,39 +3916,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mAboveAppWindowsContainers.assignLayer(t, 2); WindowState imeTarget = mService.mInputMethodTarget; boolean needAssignIme = true; // A brief summary of IME layer assignment: // // In case we have no IME target but we have an IME we are typically in // a transition state and keeping the IME on top of everything except overlays // seems to work best. // In the case where we have an IME target that is not in split-screen // mode IME assignment is easy. We just need the IME to go directly above // the target. This way children of the target will naturally go above the IME // and everyone is happy. // // In split-screen windowing mode we can't layer the // IME relative to the IME target because it needs to // go over the docked divider, so instead we place it on top // of everything and use relative layering of windows which need // to go above it (see special logic in WindowState#assignLayer) // In the case of split-screen windowing mode, we need to elevate the IME above the // docked divider while keeping the app itself below the docked divider, so instead // we use relative layering of the IME targets child windows, and place the // IME in the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}). // // There is a third case, where the IME target has no SurfaceControl, for // example if Layer assignment were triggered due to removal of the // IME target while it was still the IME target. if (imeTarget == null || imeTarget.inSplitScreenWindowingMode() || imeTarget.getSurfaceControl() == null) { mImeWindowsContainers.assignLayer(t, 3); } else { // In the case where we have no IME target we assign it where it's base layer would // place it in the AboveAppWindowContainers. if (imeTarget != null && !imeTarget.inSplitScreenWindowingMode() && (imeTarget.getSurfaceControl() != null)) { t.setRelativeLayer(mImeWindowsContainers.getSurfaceControl(), imeTarget.getSurfaceControl(), // TODO: We need to use an extra level on the app surface to ensure // this is always above SurfaceView but always below attached window. 1); needAssignIme = false; } // Above we have assigned layers to our children, now we ask them to assign // layers to their children. mBelowAppWindowsContainers.assignChildLayers(t); mTaskStackContainers.assignChildLayers(t); mAboveAppWindowsContainers.assignChildLayers(t); mAboveAppWindowsContainers.assignChildLayers(t, needAssignIme == true ? mImeWindowsContainers : null); mImeWindowsContainers.assignChildLayers(t); } Loading services/core/java/com/android/server/wm/WindowContainer.java +2 −23 Original line number Diff line number Diff line Loading @@ -731,29 +731,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final WindowContainer p = getParent(); // Give the parent a chance to set properties. In hierarchy v1 we rely // on this to set full-screen dimensions on all our Surface-less Layers. final SurfaceControl.Builder b = p.makeChildSurface(child); if (child != null && child.isScreenOverlay()) { // If it's a screen overlay it's been promoted in the hierarchy (wrt to the // WindowContainer hierarchy vs the SurfaceControl hierarchy) // and we shouldn't set ourselves as the parent. return b; } else { return b.setParent(mSurfaceControl); } } /** * There are various layers which require promotion from the WindowContainer * hierarchy to the Overlay layer described in {@link DisplayContent}. See {@link WindowState} * for the particular usage. * * TODO: Perhaps this should be eliminated, either through modifying * the window container hierarchy or through modifying the way we express these overlay * Surfaces (for example, the Magnification Overlay could be implemented like the Strict-mode * Flash and not actually use a WindowState). */ boolean isScreenOverlay() { return false; return p.makeChildSurface(child) .setParent(mSurfaceControl); } /** Loading services/core/java/com/android/server/wm/WindowState.java +8 −15 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; Loading Loading @@ -4346,25 +4347,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override boolean shouldMagnify() { if (mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG) { return false; } else if (isScreenOverlay()) { return false; } return true; } @Override boolean isScreenOverlay() { // It's tempting to wonder: Have we forgotten the rounded corners overlay? // worry not: it's a fake TYPE_NAVIGATION_BAR. if (mAttrs.type == TYPE_MAGNIFICATION_OVERLAY || mAttrs.type == TYPE_INPUT_METHOD_DIALOG || mAttrs.type == TYPE_MAGNIFICATION_OVERLAY || mAttrs.type == TYPE_NAVIGATION_BAR || // It's tempting to wonder: Have we forgotten the rounded corners overlay? // worry not: it's a fake TYPE_NAVIGATION_BAR_PANEL mAttrs.type == TYPE_NAVIGATION_BAR_PANEL || mAttrs.type == TYPE_STATUS_BAR) { return true; } return false; } return true; } @Override SurfaceSession getSession() { Loading services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java +0 −1 Original line number Diff line number Diff line Loading @@ -185,7 +185,6 @@ public class ZOrderingTests extends WindowTestsBase { // target. assertWindowLayerGreaterThan(mTransaction, mImeWindow, mChildAppWindowAbove); assertWindowLayerGreaterThan(mTransaction, mImeWindow, mAppWindow); assertWindowLayerGreaterThan(mTransaction, mImeWindow, mDockedDividerWindow); assertWindowLayerGreaterThan(mTransaction, mNavBarWindow, mImeWindow); assertWindowLayerGreaterThan(mTransaction, mStatusBarWindow, mImeWindow); Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +51 −29 Original line number Diff line number Diff line Loading @@ -181,8 +181,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final TaskStackContainers mTaskStackContainers = new TaskStackContainers(); // Contains all non-app window containers that should be displayed above the app containers // (e.g. Status bar) private final NonAppWindowContainers mAboveAppWindowsContainers = new NonAppWindowContainers("mAboveAppWindowsContainers"); private final AboveAppWindowContainers mAboveAppWindowsContainers = new AboveAppWindowContainers("mAboveAppWindowsContainers"); // Contains all non-app window containers that should be displayed below the app containers // (e.g. Wallpaper). private final NonAppWindowContainers mBelowAppWindowsContainers = Loading Loading @@ -356,7 +356,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** * We organize all top-level Surfaces in to the following layers. * mOverlayLayer contains a few Surfaces which are always on top of others * and omitted from Screen-Magnification ({@link WindowState#isScreenOverlay}) * and omitted from Screen-Magnification, for example the strict mode flash or * the magnification overlay itself. * {@link #mWindowingLayer} contains everything else. */ private SurfaceControl mOverlayLayer; Loading Loading @@ -3746,11 +3747,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } private final class AboveAppWindowContainers extends NonAppWindowContainers { AboveAppWindowContainers(String name) { super(name); } void assignChildLayers(SurfaceControl.Transaction t, WindowContainer imeContainer) { boolean needAssignIme = imeContainer != null && imeContainer.getSurfaceControl() != null; for (int j = 0; j < mChildren.size(); ++j) { final WindowToken wt = mChildren.get(j); wt.assignLayer(t, j); wt.assignChildLayers(t); int layer = mService.mPolicy.getWindowLayerFromTypeLw( wt.windowType, wt.mOwnerCanManageAppTokens); if (needAssignIme && layer >= TYPE_INPUT_METHOD_DIALOG) { t.setRelativeLayer(imeContainer.getSurfaceControl(), wt.getSurfaceControl(), -1); needAssignIme = false; } } if (needAssignIme) { t.setRelativeLayer(imeContainer.getSurfaceControl(), getSurfaceControl(), Integer.MIN_VALUE); } } } /** * Window container class that contains all containers on this display that are not related to * Apps. E.g. status bar. */ private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> { private class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> { /** * Compares two child window tokens returns -1 if the first is lesser than the second in * terms of z-order and 1 otherwise. Loading Loading @@ -3848,12 +3877,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return b; } b.setName(child.getName()); if (child.isScreenOverlay()) { return b.setParent(mOverlayLayer); } else { return b.setParent(mWindowingLayer); } return b.setName(child.getName()) .setParent(mWindowingLayer); } /** Loading Loading @@ -3891,39 +3916,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mAboveAppWindowsContainers.assignLayer(t, 2); WindowState imeTarget = mService.mInputMethodTarget; boolean needAssignIme = true; // A brief summary of IME layer assignment: // // In case we have no IME target but we have an IME we are typically in // a transition state and keeping the IME on top of everything except overlays // seems to work best. // In the case where we have an IME target that is not in split-screen // mode IME assignment is easy. We just need the IME to go directly above // the target. This way children of the target will naturally go above the IME // and everyone is happy. // // In split-screen windowing mode we can't layer the // IME relative to the IME target because it needs to // go over the docked divider, so instead we place it on top // of everything and use relative layering of windows which need // to go above it (see special logic in WindowState#assignLayer) // In the case of split-screen windowing mode, we need to elevate the IME above the // docked divider while keeping the app itself below the docked divider, so instead // we use relative layering of the IME targets child windows, and place the // IME in the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}). // // There is a third case, where the IME target has no SurfaceControl, for // example if Layer assignment were triggered due to removal of the // IME target while it was still the IME target. if (imeTarget == null || imeTarget.inSplitScreenWindowingMode() || imeTarget.getSurfaceControl() == null) { mImeWindowsContainers.assignLayer(t, 3); } else { // In the case where we have no IME target we assign it where it's base layer would // place it in the AboveAppWindowContainers. if (imeTarget != null && !imeTarget.inSplitScreenWindowingMode() && (imeTarget.getSurfaceControl() != null)) { t.setRelativeLayer(mImeWindowsContainers.getSurfaceControl(), imeTarget.getSurfaceControl(), // TODO: We need to use an extra level on the app surface to ensure // this is always above SurfaceView but always below attached window. 1); needAssignIme = false; } // Above we have assigned layers to our children, now we ask them to assign // layers to their children. mBelowAppWindowsContainers.assignChildLayers(t); mTaskStackContainers.assignChildLayers(t); mAboveAppWindowsContainers.assignChildLayers(t); mAboveAppWindowsContainers.assignChildLayers(t, needAssignIme == true ? mImeWindowsContainers : null); mImeWindowsContainers.assignChildLayers(t); } Loading
services/core/java/com/android/server/wm/WindowContainer.java +2 −23 Original line number Diff line number Diff line Loading @@ -731,29 +731,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final WindowContainer p = getParent(); // Give the parent a chance to set properties. In hierarchy v1 we rely // on this to set full-screen dimensions on all our Surface-less Layers. final SurfaceControl.Builder b = p.makeChildSurface(child); if (child != null && child.isScreenOverlay()) { // If it's a screen overlay it's been promoted in the hierarchy (wrt to the // WindowContainer hierarchy vs the SurfaceControl hierarchy) // and we shouldn't set ourselves as the parent. return b; } else { return b.setParent(mSurfaceControl); } } /** * There are various layers which require promotion from the WindowContainer * hierarchy to the Overlay layer described in {@link DisplayContent}. See {@link WindowState} * for the particular usage. * * TODO: Perhaps this should be eliminated, either through modifying * the window container hierarchy or through modifying the way we express these overlay * Surfaces (for example, the Magnification Overlay could be implemented like the Strict-mode * Flash and not actually use a WindowState). */ boolean isScreenOverlay() { return false; return p.makeChildSurface(child) .setParent(mSurfaceControl); } /** Loading
services/core/java/com/android/server/wm/WindowState.java +8 −15 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; Loading Loading @@ -4346,25 +4347,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override boolean shouldMagnify() { if (mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG) { return false; } else if (isScreenOverlay()) { return false; } return true; } @Override boolean isScreenOverlay() { // It's tempting to wonder: Have we forgotten the rounded corners overlay? // worry not: it's a fake TYPE_NAVIGATION_BAR. if (mAttrs.type == TYPE_MAGNIFICATION_OVERLAY || mAttrs.type == TYPE_INPUT_METHOD_DIALOG || mAttrs.type == TYPE_MAGNIFICATION_OVERLAY || mAttrs.type == TYPE_NAVIGATION_BAR || // It's tempting to wonder: Have we forgotten the rounded corners overlay? // worry not: it's a fake TYPE_NAVIGATION_BAR_PANEL mAttrs.type == TYPE_NAVIGATION_BAR_PANEL || mAttrs.type == TYPE_STATUS_BAR) { return true; } return false; } return true; } @Override SurfaceSession getSession() { Loading
services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java +0 −1 Original line number Diff line number Diff line Loading @@ -185,7 +185,6 @@ public class ZOrderingTests extends WindowTestsBase { // target. assertWindowLayerGreaterThan(mTransaction, mImeWindow, mChildAppWindowAbove); assertWindowLayerGreaterThan(mTransaction, mImeWindow, mAppWindow); assertWindowLayerGreaterThan(mTransaction, mImeWindow, mDockedDividerWindow); assertWindowLayerGreaterThan(mTransaction, mNavBarWindow, mImeWindow); assertWindowLayerGreaterThan(mTransaction, mStatusBarWindow, mImeWindow); Loading