From f03bad79ea8128779e0c67bd5a9cc3fefd393614 Mon Sep 17 00:00:00 2001 From: Maryam Dehaini Date: Fri, 31 Mar 2023 11:19:34 -0700 Subject: [PATCH] Add shadow to view in sync with the handle menu appearing When we add the shadow right after running SurfaceControlViewHost#setView, the shadow become visible on the screen before the view which causes a flashing affect. This change uses a SyncSurfaceGroup to sync set view and the application of our transaction. Bug: 276356641 Test: Manual Testing Change-Id: Iecbcb0e9f7736bddfd3054f8e91c69bce41e3e78 --- .../android/view/SurfaceControlViewHost.java | 1 + .../DesktopModeWindowDecoration.java | 26 +++++++++---------- .../shell/windowdecor/WindowDecoration.java | 25 ++++++++++-------- .../windowdecor/WindowDecorationTests.java | 5 +++- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index cd89a561074cb..e9984daaf3895 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -303,6 +303,7 @@ public class SurfaceControlViewHost { /** @hide */ public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d, @NonNull WindowlessWindowManager wwm, @NonNull String callsite) { + mSurfaceControl = wwm.mRootSurface; mWm = wwm; mViewRoot = new ViewRootImpl(c, d, mWm, new WindowlessWindowLayout()); mCloseGuard.openWithCallSite("release", callsite); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index a004e37c63456..67e99d73b8116 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -42,6 +42,7 @@ import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; +import android.window.SurfaceSyncGroup; import android.window.WindowContainerTransaction; import com.android.launcher3.icons.IconProvider; @@ -311,51 +312,50 @@ public class DesktopModeWindowDecoration extends WindowDecoration { - transaction.merge(t); - t.close(); - }); + ssg.addTransaction(t); + ssg.markSyncReady(); setupHandleMenu(shouldShowWindowingPill); } - private void createAppInfoPill(SurfaceControl.Transaction t) { + private void createAppInfoPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) { final int x = (int) mHandleMenuAppInfoPillPosition.x; final int y = (int) mHandleMenuAppInfoPillPosition.y; mHandleMenuAppInfoPill = addWindow( R.layout.desktop_mode_window_decor_handle_menu_app_info_pill, "Menu's app info pill", - t, x, y, mMenuWidth, mAppInfoPillHeight, mShadowRadius, mCornerRadius); + t, ssg, x, y, mMenuWidth, mAppInfoPillHeight, mShadowRadius, mCornerRadius); } - private void createWindowingPill(SurfaceControl.Transaction t) { + private void createWindowingPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) { final int x = (int) mHandleMenuWindowingPillPosition.x; final int y = (int) mHandleMenuWindowingPillPosition.y; mHandleMenuWindowingPill = addWindow( R.layout.desktop_mode_window_decor_handle_menu_windowing_pill, "Menu's windowing pill", - t, x, y, mMenuWidth, mWindowingPillHeight, mShadowRadius, mCornerRadius); + t, ssg, x, y, mMenuWidth, mWindowingPillHeight, mShadowRadius, mCornerRadius); } - private void createMoreActionsPill(SurfaceControl.Transaction t) { + private void createMoreActionsPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) { final int x = (int) mHandleMenuMoreActionsPillPosition.x; final int y = (int) mHandleMenuMoreActionsPillPosition.y; mHandleMenuMoreActionsPill = addWindow( R.layout.desktop_mode_window_decor_handle_menu_more_actions_pill, "Menu's more actions pill", - t, x, y, mMenuWidth, mMoreActionsPillHeight, mShadowRadius, mCornerRadius); + t, ssg, x, y, mMenuWidth, mMoreActionsPillHeight, mShadowRadius, mCornerRadius); } private void setupHandleMenu(boolean windowingPillShown) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index bc5fd4dcbdc82..19a31822aabb8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -34,6 +34,7 @@ import android.view.ViewRootImpl; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowlessWindowManager; +import android.window.SurfaceSyncGroup; import android.window.TaskConstants; import android.window.WindowContainerTransaction; @@ -192,13 +193,13 @@ public abstract class WindowDecoration mDecorWindowContext = mContext.createConfigurationContext(taskConfig); if (params.mLayoutResId != 0) { outResult.mRootView = (T) LayoutInflater.from(mDecorWindowContext) - .inflate(params.mLayoutResId, null); + .inflate(params.mLayoutResId, null); } } if (outResult.mRootView == null) { outResult.mRootView = (T) LayoutInflater.from(mDecorWindowContext) - .inflate(params.mLayoutResId , null); + .inflate(params.mLayoutResId, null); } // DecorationContainerSurface @@ -382,18 +383,20 @@ public abstract class WindowDecoration /** * Create a window associated with this WindowDecoration. * Note that subclass must dispose of this when the task is hidden/closed. - * @param layoutId layout to make the window from - * @param t the transaction to apply - * @param xPos x position of new window - * @param yPos y position of new window - * @param width width of new window - * @param height height of new window + * + * @param layoutId layout to make the window from + * @param t the transaction to apply + * @param xPos x position of new window + * @param yPos y position of new window + * @param width width of new window + * @param height height of new window * @param shadowRadius radius of the shadow of the new window * @param cornerRadius radius of the corners of the new window * @return the {@link AdditionalWindow} that was added. */ AdditionalWindow addWindow(int layoutId, String namePrefix, SurfaceControl.Transaction t, - int xPos, int yPos, int width, int height, int shadowRadius, int cornerRadius) { + SurfaceSyncGroup ssg, int xPos, int yPos, int width, int height, int shadowRadius, + int cornerRadius) { final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get(); SurfaceControl windowSurfaceControl = builder .setName(namePrefix + " of Task=" + mTaskInfo.taskId) @@ -417,12 +420,12 @@ public abstract class WindowDecoration windowSurfaceControl, null /* hostInputToken */); SurfaceControlViewHost viewHost = mSurfaceControlViewHostFactory .create(mDecorWindowContext, mDisplay, windowManager); - viewHost.setView(v, lp); + ssg.add(viewHost.getSurfacePackage(), () -> viewHost.setView(v, lp)); return new AdditionalWindow(windowSurfaceControl, viewHost, mSurfaceControlTransactionSupplier); } - static class RelayoutParams{ + static class RelayoutParams { RunningTaskInfo mRunningTaskInfo; int mLayoutResId; int mCaptionHeightId; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java index e8147ff264ccd..38a519af934be 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java @@ -49,6 +49,7 @@ import android.view.View; import android.view.ViewRootImpl; import android.view.WindowInsets; import android.view.WindowManager.LayoutParams; +import android.window.SurfaceSyncGroup; import android.window.TaskConstants; import android.window.WindowContainerTransaction; @@ -100,6 +101,8 @@ public class WindowDecorationTests extends ShellTestCase { private TestView mMockView; @Mock private WindowContainerTransaction mMockWindowContainerTransaction; + @Mock + private SurfaceSyncGroup mMockSurfaceSyncGroup; private final List mMockSurfaceControlTransactions = new ArrayList<>(); @@ -553,7 +556,7 @@ public class WindowDecorationTests extends ShellTestCase { String name = "Test Window"; WindowDecoration.AdditionalWindow additionalWindow = addWindow(R.layout.desktop_mode_window_decor_handle_menu_app_info_pill, name, - mMockSurfaceControlAddWindowT, x, y, + mMockSurfaceControlAddWindowT, mMockSurfaceSyncGroup, x, y, width, height, shadowRadius, cornerRadius); return additionalWindow; }