Loading services/core/java/com/android/server/wm/WindowContainer.java +8 −4 Original line number Diff line number Diff line Loading @@ -378,10 +378,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (mSurfaceControl == null) { // If we don't yet have a surface, but we now have a parent, we should // build a surface. setSurfaceControl(makeSurface().build()); getPendingTransaction().show(mSurfaceControl); onSurfaceShown(getPendingTransaction()); updateSurfacePosition(); createSurfaceControl(false /*force*/); } else { // If we have a surface but a new parent, we just need to perform a reparent. Go through // surface animator such that hierarchy is preserved when animating, i.e. Loading @@ -399,6 +396,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< scheduleAnimation(); } void createSurfaceControl(boolean force) { setSurfaceControl(makeSurface().build()); getPendingTransaction().show(mSurfaceControl); onSurfaceShown(getPendingTransaction()); updateSurfacePosition(); } /** * Called when the surface is shown for the first time. */ Loading services/core/java/com/android/server/wm/WindowToken.java +15 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,9 @@ class WindowToken extends WindowContainer<WindowState> { private Configuration mLastReportedConfig; private int mLastReportedDisplay = INVALID_DISPLAY; /** * When set to {@code true}, this window token is created from {@link android.app.WindowContext} */ @VisibleForTesting final boolean mFromClientToken; Loading Loading @@ -281,6 +284,11 @@ class WindowToken extends WindowContainer<WindowState> { // Child windows are added to their parent windows. return; } // This token is created from WindowContext and the client requests to addView now, create a // surface for this token. if (mSurfaceControl == null) { createSurfaceControl(true /* force */); } if (!mChildren.contains(win)) { ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this); addChild(win, mWindowComparator); Loading @@ -289,6 +297,13 @@ class WindowToken extends WindowContainer<WindowState> { } } @Override void createSurfaceControl(boolean force) { if (!mFromClientToken || force) { super.createSurfaceControl(force); } } /** Returns true if the token windows list is empty. */ boolean isEmpty() { return mChildren.isEmpty(); Loading services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +24 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static org.junit.Assert.assertEquals; Loading Loading @@ -155,4 +156,27 @@ public class WindowTokenTests extends WindowTestsBase { assertTrue(token.mRoundedCornerOverlay); assertTrue(token.mFromClientToken); } /** * Test that {@link android.view.SurfaceControl} should not be created for the * {@link WindowToken} which was created for {@link android.app.WindowContext} initially, the * surface should be create after addWindow for this token. */ @Test public void testSurfaceCreatedForWindowToken() { final WindowToken fromClientToken = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), TYPE_APPLICATION_OVERLAY, true /* persistOnEmpty */, mDisplayContent, true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, true /* fromClientToken */); assertNull(fromClientToken.mSurfaceControl); createWindow(null, TYPE_APPLICATION_OVERLAY, fromClientToken, "window"); assertNotNull(fromClientToken.mSurfaceControl); final WindowToken nonClientToken = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), TYPE_TOAST, true /* persistOnEmpty */, mDisplayContent, true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, false /* fromClientToken */); assertNotNull(nonClientToken.mSurfaceControl); } } Loading
services/core/java/com/android/server/wm/WindowContainer.java +8 −4 Original line number Diff line number Diff line Loading @@ -378,10 +378,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (mSurfaceControl == null) { // If we don't yet have a surface, but we now have a parent, we should // build a surface. setSurfaceControl(makeSurface().build()); getPendingTransaction().show(mSurfaceControl); onSurfaceShown(getPendingTransaction()); updateSurfacePosition(); createSurfaceControl(false /*force*/); } else { // If we have a surface but a new parent, we just need to perform a reparent. Go through // surface animator such that hierarchy is preserved when animating, i.e. Loading @@ -399,6 +396,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< scheduleAnimation(); } void createSurfaceControl(boolean force) { setSurfaceControl(makeSurface().build()); getPendingTransaction().show(mSurfaceControl); onSurfaceShown(getPendingTransaction()); updateSurfacePosition(); } /** * Called when the surface is shown for the first time. */ Loading
services/core/java/com/android/server/wm/WindowToken.java +15 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,9 @@ class WindowToken extends WindowContainer<WindowState> { private Configuration mLastReportedConfig; private int mLastReportedDisplay = INVALID_DISPLAY; /** * When set to {@code true}, this window token is created from {@link android.app.WindowContext} */ @VisibleForTesting final boolean mFromClientToken; Loading Loading @@ -281,6 +284,11 @@ class WindowToken extends WindowContainer<WindowState> { // Child windows are added to their parent windows. return; } // This token is created from WindowContext and the client requests to addView now, create a // surface for this token. if (mSurfaceControl == null) { createSurfaceControl(true /* force */); } if (!mChildren.contains(win)) { ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this); addChild(win, mWindowComparator); Loading @@ -289,6 +297,13 @@ class WindowToken extends WindowContainer<WindowState> { } } @Override void createSurfaceControl(boolean force) { if (!mFromClientToken || force) { super.createSurfaceControl(force); } } /** Returns true if the token windows list is empty. */ boolean isEmpty() { return mChildren.isEmpty(); Loading
services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +24 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static org.junit.Assert.assertEquals; Loading Loading @@ -155,4 +156,27 @@ public class WindowTokenTests extends WindowTestsBase { assertTrue(token.mRoundedCornerOverlay); assertTrue(token.mFromClientToken); } /** * Test that {@link android.view.SurfaceControl} should not be created for the * {@link WindowToken} which was created for {@link android.app.WindowContext} initially, the * surface should be create after addWindow for this token. */ @Test public void testSurfaceCreatedForWindowToken() { final WindowToken fromClientToken = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), TYPE_APPLICATION_OVERLAY, true /* persistOnEmpty */, mDisplayContent, true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, true /* fromClientToken */); assertNull(fromClientToken.mSurfaceControl); createWindow(null, TYPE_APPLICATION_OVERLAY, fromClientToken, "window"); assertNotNull(fromClientToken.mSurfaceControl); final WindowToken nonClientToken = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class), TYPE_TOAST, true /* persistOnEmpty */, mDisplayContent, true /* ownerCanManageAppTokens */, true /* roundedCornerOverlay */, false /* fromClientToken */); assertNotNull(nonClientToken.mSurfaceControl); } }