Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java +46 −1 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ package com.android.wm.shell.pip2; import android.content.Context; import android.graphics.Matrix; import android.graphics.Rect; import android.gui.BorderSettings; import android.gui.BoxShadowSettings; import android.view.Choreographer; import android.view.SurfaceControl; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.common.BoxShadowHelper; import com.android.wm.shell.common.pip.PipUtils; /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition. Loading @@ -36,12 +41,42 @@ public class PipSurfaceTransactionHelper { private final int mShadowRadius; private final float mMirrorOpacity; private BoxShadowSettings mBoxShadowSettings; private BorderSettings mBorderSettings; public PipSurfaceTransactionHelper(Context context) { mCornerRadius = context.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius); mShadowRadius = context.getResources().getDimensionPixelSize(R.dimen.pip_shadow_radius); mMirrorOpacity = context.getResources().getFloat( R.dimen.config_pipDraggingAcrossDisplaysOpacity); onThemeChanged(context); } /** * Called when theme changes. * * @param context the current context */ public void onThemeChanged(Context context) { if (Flags.enablePipBoxShadows()) { if (PipUtils.isDarkSystemTheme(context)) { mBoxShadowSettings = BoxShadowHelper.getBoxShadowSettings(context, new int[]{R.style.BoxShadowParamsPIPDark1, R.style.BoxShadowParamsPIPDark2}); mBorderSettings = BoxShadowHelper.getBorderSettings(context, R.style.BorderSettingsPIPDark); } else { mBoxShadowSettings = BoxShadowHelper.getBoxShadowSettings(context, new int[]{R.style.BoxShadowParamsPIPLight1, R.style.BoxShadowParamsPIPLight2}); mBorderSettings = BoxShadowHelper.getBorderSettings(context, R.style.BorderSettingsPIPLight); } } } /** * Gets corner radius which is loaded from resources. Loading Loading @@ -162,7 +197,17 @@ public class PipSurfaceTransactionHelper { */ public PipSurfaceTransactionHelper shadow(SurfaceControl.Transaction tx, SurfaceControl leash, boolean applyShadowRadius) { if (Flags.enablePipBoxShadows()) { if (applyShadowRadius) { tx.setBoxShadowSettings(leash, mBoxShadowSettings); tx.setBorderSettings(leash, mBorderSettings); } else { tx.setBoxShadowSettings(leash, new BoxShadowSettings()); tx.setBorderSettings(leash, new BorderSettings()); } } else { tx.setShadowRadius(leash, applyShadowRadius ? mShadowRadius : 0); } return this; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +14 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayChangeController; Loading Loading @@ -122,6 +123,8 @@ public class PipController implements ConfigurationChangeListener, // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. @Nullable private PipAnimationListener mPipRecentsAnimationListener; private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private boolean mWaitingToPlayDisplayChangeBoundsUpdate; Loading Loading @@ -193,6 +196,8 @@ public class PipController implements ConfigurationChangeListener, mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper; mMainExecutor = mainExecutor; mImpl = new PipImpl(); mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); if (PipUtils.isPip2ExperimentEnabled()) { shellInit.addInitCallback(this::onInit, this); Loading Loading @@ -370,6 +375,15 @@ public class PipController implements ConfigurationChangeListener, @Override public void onThemeChanged() { setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay())); if (Flags.enablePipBoxShadows()) { if (mPipTransitionState.isInPip()) { SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash(); mPipSurfaceTransactionHelper.onThemeChanged(mContext); SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mPipSurfaceTransactionHelper.shadow(tx, pipLeash, true /* applyShadowRadius */); tx.apply(); } } } // Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelperTest.java +108 −1 Original line number Diff line number Diff line Loading @@ -16,25 +16,38 @@ package com.android.wm.shell.pip2; import static org.junit.Assert.assertEquals; import static org.mockito.AdditionalMatchers.aryEq; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; import android.gui.BorderSettings; import android.gui.BoxShadowSettings; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.SurfaceControl; import androidx.test.filters.SmallTest; import com.android.modules.utils.testing.ExtendedMockitoRule; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.common.BoxShadowHelper; import com.android.wm.shell.common.pip.PipUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading @@ -50,13 +63,34 @@ public class PipSurfaceTransactionHelperTest { private static final int SHADOW_RADIUS = 20; private static final float MIRROR_OPACITY = 0.5f; private final BoxShadowSettings mLightBoxShadowSettings = new BoxShadowSettings(); private final BorderSettings mLightBorderSettings = new BorderSettings(); private final BoxShadowSettings mDarkBoxShadowSettings = new BoxShadowSettings(); private final BorderSettings mDarkBorderSettings = new BorderSettings(); private static final int[] LIGHT_SHADOW_STYLES = { R.style.BoxShadowParamsPIPLight1, R.style.BoxShadowParamsPIPLight2}; private static final int[] DARK_SHADOW_STYLES = { R.style.BoxShadowParamsPIPDark1, R.style.BoxShadowParamsPIPDark2}; private static final int LIGHT_BORDER_STYLE = R.style.BorderSettingsPIPLight; private static final int DARK_BORDER_STYLE = R.style.BorderSettingsPIPDark; @Mock private Context mMockContext; @Mock private Resources mMockResources; @Mock private SurfaceControl.Transaction mMockTransaction; private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private SurfaceControl mTestLeash; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) .mockStatic(BoxShadowHelper.class) .mockStatic(PipUtils.class) .build(); @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading @@ -78,6 +112,30 @@ public class PipSurfaceTransactionHelperTest { .setName("PipSurfaceTransactionHelperTest") .setCallsite("PipSurfaceTransactionHelperTest") .build(); when(mMockTransaction.setCornerRadius(any(SurfaceControl.class), anyFloat())) .thenReturn(mMockTransaction); when(mMockTransaction.setShadowRadius(any(SurfaceControl.class), anyFloat())) .thenReturn(mMockTransaction); when(mMockTransaction.setBoxShadowSettings(any(SurfaceControl.class), any(BoxShadowSettings.class))) .thenReturn(mMockTransaction); when(mMockTransaction.setBorderSettings(any(SurfaceControl.class), any(BorderSettings.class))) .thenReturn(mMockTransaction); when(BoxShadowHelper.getBoxShadowSettings( eq(mMockContext), aryEq(LIGHT_SHADOW_STYLES))).thenReturn( mLightBoxShadowSettings); when(BoxShadowHelper.getBorderSettings( eq(mMockContext), eq(LIGHT_BORDER_STYLE))).thenReturn(mLightBorderSettings); when(BoxShadowHelper.getBoxShadowSettings( eq(mMockContext), aryEq(DARK_SHADOW_STYLES))).thenReturn(mDarkBoxShadowSettings); when(BoxShadowHelper.getBorderSettings( eq(mMockContext), eq(DARK_BORDER_STYLE))).thenReturn(mDarkBorderSettings); } @Test Loading Loading @@ -108,6 +166,55 @@ public class PipSurfaceTransactionHelperTest { verify(mMockTransaction).setShadowRadius(eq(mTestLeash), eq((float) SHADOW_RADIUS)); } @Test @EnableFlags(Flags.FLAG_ENABLE_PIP_BOX_SHADOWS) public void shadow_flagEnabled_applyFalse_setsEmptyBoxShadowAndBorder() { mPipSurfaceTransactionHelper.shadow(mMockTransaction, mTestLeash, false /* apply */); ArgumentCaptor<BoxShadowSettings> boxShadow = ArgumentCaptor.forClass( BoxShadowSettings.class); ArgumentCaptor<BorderSettings> border = ArgumentCaptor.forClass(BorderSettings.class); verify(mMockTransaction).setBoxShadowSettings(eq(mTestLeash), boxShadow.capture()); verify(mMockTransaction).setBorderSettings(eq(mTestLeash), border.capture()); verify(mMockTransaction, never()).setShadowRadius(any(), anyFloat()); assertEquals(0, boxShadow.getValue().boxShadows.length); assertEquals(0, border.getValue().strokeWidth, 0.0); assertEquals(0, border.getValue().color); } @Test @EnableFlags(Flags.FLAG_ENABLE_PIP_BOX_SHADOWS) public void onThemeChanged_switchToDarkTheme_usesDarkSettingsOnShadow() { when(PipUtils.isDarkSystemTheme(mMockContext)).thenReturn(true); mPipSurfaceTransactionHelper.onThemeChanged(mMockContext); mPipSurfaceTransactionHelper.shadow(mMockTransaction, mTestLeash, true /* apply */); verify(mMockTransaction).setBoxShadowSettings(eq(mTestLeash), eq(mDarkBoxShadowSettings)); verify(mMockTransaction).setBorderSettings(eq(mTestLeash), eq(mDarkBorderSettings)); verify(mMockTransaction, never()).setShadowRadius(any(), anyFloat()); } @Test @EnableFlags(Flags.FLAG_ENABLE_PIP_BOX_SHADOWS) public void onThemeChanged_switchToLightTheme_usesLightSettingsOnShadow() { when(PipUtils.isDarkSystemTheme(mMockContext)).thenReturn(false); mPipSurfaceTransactionHelper.onThemeChanged(mMockContext); mPipSurfaceTransactionHelper.shadow(mMockTransaction, mTestLeash, true /* apply */); verify(mMockTransaction).setBoxShadowSettings(eq(mTestLeash), eq(mLightBoxShadowSettings)); verify(mMockTransaction).setBorderSettings(eq(mTestLeash), eq(mLightBorderSettings)); verify(mMockTransaction, never()).setShadowRadius(any(), anyFloat()); } @Test public void setMirrorTransformations_setsAlphaAndLayer() { mPipSurfaceTransactionHelper.setMirrorTransformations(mMockTransaction, mTestLeash); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java +46 −1 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ package com.android.wm.shell.pip2; import android.content.Context; import android.graphics.Matrix; import android.graphics.Rect; import android.gui.BorderSettings; import android.gui.BoxShadowSettings; import android.view.Choreographer; import android.view.SurfaceControl; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.common.BoxShadowHelper; import com.android.wm.shell.common.pip.PipUtils; /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition. Loading @@ -36,12 +41,42 @@ public class PipSurfaceTransactionHelper { private final int mShadowRadius; private final float mMirrorOpacity; private BoxShadowSettings mBoxShadowSettings; private BorderSettings mBorderSettings; public PipSurfaceTransactionHelper(Context context) { mCornerRadius = context.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius); mShadowRadius = context.getResources().getDimensionPixelSize(R.dimen.pip_shadow_radius); mMirrorOpacity = context.getResources().getFloat( R.dimen.config_pipDraggingAcrossDisplaysOpacity); onThemeChanged(context); } /** * Called when theme changes. * * @param context the current context */ public void onThemeChanged(Context context) { if (Flags.enablePipBoxShadows()) { if (PipUtils.isDarkSystemTheme(context)) { mBoxShadowSettings = BoxShadowHelper.getBoxShadowSettings(context, new int[]{R.style.BoxShadowParamsPIPDark1, R.style.BoxShadowParamsPIPDark2}); mBorderSettings = BoxShadowHelper.getBorderSettings(context, R.style.BorderSettingsPIPDark); } else { mBoxShadowSettings = BoxShadowHelper.getBoxShadowSettings(context, new int[]{R.style.BoxShadowParamsPIPLight1, R.style.BoxShadowParamsPIPLight2}); mBorderSettings = BoxShadowHelper.getBorderSettings(context, R.style.BorderSettingsPIPLight); } } } /** * Gets corner radius which is loaded from resources. Loading Loading @@ -162,7 +197,17 @@ public class PipSurfaceTransactionHelper { */ public PipSurfaceTransactionHelper shadow(SurfaceControl.Transaction tx, SurfaceControl leash, boolean applyShadowRadius) { if (Flags.enablePipBoxShadows()) { if (applyShadowRadius) { tx.setBoxShadowSettings(leash, mBoxShadowSettings); tx.setBorderSettings(leash, mBorderSettings); } else { tx.setBoxShadowSettings(leash, new BoxShadowSettings()); tx.setBorderSettings(leash, new BorderSettings()); } } else { tx.setShadowRadius(leash, applyShadowRadius ? mShadowRadius : 0); } return this; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +14 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayChangeController; Loading Loading @@ -122,6 +123,8 @@ public class PipController implements ConfigurationChangeListener, // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. @Nullable private PipAnimationListener mPipRecentsAnimationListener; private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private boolean mWaitingToPlayDisplayChangeBoundsUpdate; Loading Loading @@ -193,6 +196,8 @@ public class PipController implements ConfigurationChangeListener, mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper; mMainExecutor = mainExecutor; mImpl = new PipImpl(); mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); if (PipUtils.isPip2ExperimentEnabled()) { shellInit.addInitCallback(this::onInit, this); Loading Loading @@ -370,6 +375,15 @@ public class PipController implements ConfigurationChangeListener, @Override public void onThemeChanged() { setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay())); if (Flags.enablePipBoxShadows()) { if (mPipTransitionState.isInPip()) { SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash(); mPipSurfaceTransactionHelper.onThemeChanged(mContext); SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mPipSurfaceTransactionHelper.shadow(tx, pipLeash, true /* applyShadowRadius */); tx.apply(); } } } // Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelperTest.java +108 −1 Original line number Diff line number Diff line Loading @@ -16,25 +16,38 @@ package com.android.wm.shell.pip2; import static org.junit.Assert.assertEquals; import static org.mockito.AdditionalMatchers.aryEq; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; import android.gui.BorderSettings; import android.gui.BoxShadowSettings; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.SurfaceControl; import androidx.test.filters.SmallTest; import com.android.modules.utils.testing.ExtendedMockitoRule; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.common.BoxShadowHelper; import com.android.wm.shell.common.pip.PipUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading @@ -50,13 +63,34 @@ public class PipSurfaceTransactionHelperTest { private static final int SHADOW_RADIUS = 20; private static final float MIRROR_OPACITY = 0.5f; private final BoxShadowSettings mLightBoxShadowSettings = new BoxShadowSettings(); private final BorderSettings mLightBorderSettings = new BorderSettings(); private final BoxShadowSettings mDarkBoxShadowSettings = new BoxShadowSettings(); private final BorderSettings mDarkBorderSettings = new BorderSettings(); private static final int[] LIGHT_SHADOW_STYLES = { R.style.BoxShadowParamsPIPLight1, R.style.BoxShadowParamsPIPLight2}; private static final int[] DARK_SHADOW_STYLES = { R.style.BoxShadowParamsPIPDark1, R.style.BoxShadowParamsPIPDark2}; private static final int LIGHT_BORDER_STYLE = R.style.BorderSettingsPIPLight; private static final int DARK_BORDER_STYLE = R.style.BorderSettingsPIPDark; @Mock private Context mMockContext; @Mock private Resources mMockResources; @Mock private SurfaceControl.Transaction mMockTransaction; private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private SurfaceControl mTestLeash; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) .mockStatic(BoxShadowHelper.class) .mockStatic(PipUtils.class) .build(); @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading @@ -78,6 +112,30 @@ public class PipSurfaceTransactionHelperTest { .setName("PipSurfaceTransactionHelperTest") .setCallsite("PipSurfaceTransactionHelperTest") .build(); when(mMockTransaction.setCornerRadius(any(SurfaceControl.class), anyFloat())) .thenReturn(mMockTransaction); when(mMockTransaction.setShadowRadius(any(SurfaceControl.class), anyFloat())) .thenReturn(mMockTransaction); when(mMockTransaction.setBoxShadowSettings(any(SurfaceControl.class), any(BoxShadowSettings.class))) .thenReturn(mMockTransaction); when(mMockTransaction.setBorderSettings(any(SurfaceControl.class), any(BorderSettings.class))) .thenReturn(mMockTransaction); when(BoxShadowHelper.getBoxShadowSettings( eq(mMockContext), aryEq(LIGHT_SHADOW_STYLES))).thenReturn( mLightBoxShadowSettings); when(BoxShadowHelper.getBorderSettings( eq(mMockContext), eq(LIGHT_BORDER_STYLE))).thenReturn(mLightBorderSettings); when(BoxShadowHelper.getBoxShadowSettings( eq(mMockContext), aryEq(DARK_SHADOW_STYLES))).thenReturn(mDarkBoxShadowSettings); when(BoxShadowHelper.getBorderSettings( eq(mMockContext), eq(DARK_BORDER_STYLE))).thenReturn(mDarkBorderSettings); } @Test Loading Loading @@ -108,6 +166,55 @@ public class PipSurfaceTransactionHelperTest { verify(mMockTransaction).setShadowRadius(eq(mTestLeash), eq((float) SHADOW_RADIUS)); } @Test @EnableFlags(Flags.FLAG_ENABLE_PIP_BOX_SHADOWS) public void shadow_flagEnabled_applyFalse_setsEmptyBoxShadowAndBorder() { mPipSurfaceTransactionHelper.shadow(mMockTransaction, mTestLeash, false /* apply */); ArgumentCaptor<BoxShadowSettings> boxShadow = ArgumentCaptor.forClass( BoxShadowSettings.class); ArgumentCaptor<BorderSettings> border = ArgumentCaptor.forClass(BorderSettings.class); verify(mMockTransaction).setBoxShadowSettings(eq(mTestLeash), boxShadow.capture()); verify(mMockTransaction).setBorderSettings(eq(mTestLeash), border.capture()); verify(mMockTransaction, never()).setShadowRadius(any(), anyFloat()); assertEquals(0, boxShadow.getValue().boxShadows.length); assertEquals(0, border.getValue().strokeWidth, 0.0); assertEquals(0, border.getValue().color); } @Test @EnableFlags(Flags.FLAG_ENABLE_PIP_BOX_SHADOWS) public void onThemeChanged_switchToDarkTheme_usesDarkSettingsOnShadow() { when(PipUtils.isDarkSystemTheme(mMockContext)).thenReturn(true); mPipSurfaceTransactionHelper.onThemeChanged(mMockContext); mPipSurfaceTransactionHelper.shadow(mMockTransaction, mTestLeash, true /* apply */); verify(mMockTransaction).setBoxShadowSettings(eq(mTestLeash), eq(mDarkBoxShadowSettings)); verify(mMockTransaction).setBorderSettings(eq(mTestLeash), eq(mDarkBorderSettings)); verify(mMockTransaction, never()).setShadowRadius(any(), anyFloat()); } @Test @EnableFlags(Flags.FLAG_ENABLE_PIP_BOX_SHADOWS) public void onThemeChanged_switchToLightTheme_usesLightSettingsOnShadow() { when(PipUtils.isDarkSystemTheme(mMockContext)).thenReturn(false); mPipSurfaceTransactionHelper.onThemeChanged(mMockContext); mPipSurfaceTransactionHelper.shadow(mMockTransaction, mTestLeash, true /* apply */); verify(mMockTransaction).setBoxShadowSettings(eq(mTestLeash), eq(mLightBoxShadowSettings)); verify(mMockTransaction).setBorderSettings(eq(mTestLeash), eq(mLightBorderSettings)); verify(mMockTransaction, never()).setShadowRadius(any(), anyFloat()); } @Test public void setMirrorTransformations_setsAlphaAndLayer() { mPipSurfaceTransactionHelper.setMirrorTransformations(mMockTransaction, mTestLeash); Loading