Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +26 −22 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ParceledListSlice; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; Loading @@ -45,6 +44,7 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsHandler; Loading @@ -62,7 +62,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private static final String TAG = "PipController"; private Context mContext; private Handler mHandler = new Handler(); private ShellExecutor mMainExecutor; private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); private final Rect mTmpInsetBounds = new Rect(); Loading @@ -82,6 +82,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac protected PipMenuActivityController mMenuController; protected PipTaskOrganizer mPipTaskOrganizer; protected PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener = new PipControllerPinnedStackListener(); /** * Handler for display rotation changes. Loading Loading @@ -150,12 +152,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PinnedStackListenerForwarder.PinnedStackListener { @Override public void onListenerRegistered(IPinnedStackController controller) { mHandler.post(() -> mTouchHandler.setPinnedStackController(controller)); mMainExecutor.execute(() -> mTouchHandler.setPinnedStackController(controller)); } @Override public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight); mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight); }); Loading @@ -163,19 +165,19 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onMovementBoundsChanged(boolean fromImeAdjustment) { mHandler.post(() -> updateMovementBounds(null /* toBounds */, mMainExecutor.execute(() -> updateMovementBounds(null /* toBounds */, false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */, null /* windowContainerTransaction */)); } @Override public void onActionsChanged(ParceledListSlice<RemoteAction> actions) { mHandler.post(() -> mMenuController.setAppActions(actions)); mMainExecutor.execute(() -> mMenuController.setAppActions(actions)); } @Override public void onActivityHidden(ComponentName componentName) { mHandler.post(() -> { mMainExecutor.execute(() -> { if (componentName.equals(mPipBoundsState.getLastPipComponentName())) { // The activity was removed, we don't want to restore to the reentry state // saved for this component anymore. Loading @@ -186,12 +188,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onDisplayInfoChanged(DisplayInfo displayInfo) { mHandler.post(() -> mPipBoundsState.setDisplayInfo(displayInfo)); mMainExecutor.execute(() -> mPipBoundsState.setDisplayInfo(displayInfo)); } @Override public void onConfigurationChanged() { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsHandler.onConfigurationChanged(mContext); mTouchHandler.onConfigurationChanged(); }); Loading @@ -201,7 +203,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac public void onAspectRatioChanged(float aspectRatio) { // TODO(b/169373982): Remove this callback as it is redundant with PipTaskOrg params // change. mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsState.setAspectRatio(aspectRatio); mTouchHandler.onAspectRatioChanged(); }); Loading @@ -217,7 +219,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper WindowManagerShellWrapper windowManagerShellWrapper, ShellExecutor mainExecutor ) { // Ensure that we are the primary user's SystemUI. final int processUser = UserManager.get(context).getUserHandle(); Loading @@ -231,6 +234,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipBoundsHandler = pipBoundsHandler; mPipBoundsState = pipBoundsState; mPipTaskOrganizer = pipTaskOrganizer; mMainExecutor = mainExecutor; mPipTaskOrganizer.registerPipTransitionCallback(this); mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> { final DisplayInfo newDisplayInfo = new DisplayInfo(); Loading @@ -254,8 +258,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipBoundsState.setDisplayInfo(displayInfo); try { mWindowManagerShellWrapper.addPinnedStackListener( new PipControllerPinnedStackListener()); mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener); } catch (RemoteException e) { Slog.e(TAG, "Failed to register pinned stack listener", e); } Loading @@ -263,14 +266,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onDensityOrFontScaleChanged() { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext); }); } @Override public void onActivityPinned(String packageName) { mHandler.post(() -> { mMainExecutor.execute(() -> { mTouchHandler.onActivityPinned(); mMediaController.onActivityPinned(); mMenuController.onActivityPinned(); Loading @@ -280,7 +283,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onActivityUnpinned(ComponentName topActivity) { mHandler.post(() -> { mMainExecutor.execute(() -> { mMenuController.onActivityUnpinned(); mTouchHandler.onActivityUnpinned(topActivity); mAppOpsListener.onActivityUnpinned(); Loading @@ -299,7 +302,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onOverlayChanged() { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsState.setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay())); updateMovementBounds(null /* toBounds */, false /* fromRotation */, false /* fromImeAdjustment */, Loading Loading @@ -358,7 +361,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac */ @Override public void setShelfHeight(boolean visible, int height) { mHandler.post(() -> setShelfHeightLocked(visible, height)); mMainExecutor.execute(() -> setShelfHeightLocked(visible, height)); } private void setShelfHeightLocked(boolean visible, int height) { Loading @@ -374,12 +377,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void setPinnedStackAnimationType(int animationType) { mHandler.post(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType)); mMainExecutor.execute(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType)); } @Override public void setPinnedStackAnimationListener(Consumer<Boolean> callback) { mHandler.post(() -> mPinnedStackAnimationRecentsCallback = callback); mMainExecutor.execute(() -> mPinnedStackAnimationRecentsCallback = callback); } @Override Loading Loading @@ -476,7 +479,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipBoundsState pipBoundsState, PipMediaController pipMediaController, PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper) { WindowManagerShellWrapper windowManagerShellWrapper, ShellExecutor mainExecutor) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { Slog.w(TAG, "Device doesn't support Pip feature"); return null; Loading @@ -484,6 +488,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac return new PipController(context, displayController, pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper); pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper, mainExecutor); } } libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +36 −4 Original line number Diff line number Diff line Loading @@ -69,11 +69,13 @@ public class PipTaskOrganizerTest extends PipTestCase { private PipBoundsState mPipBoundsState; private ComponentName mComponent1; private ComponentName mComponent2; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); mComponent1 = new ComponentName(mContext, "component1"); mComponent2 = new ComponentName(mContext, "component2"); mPipBoundsState = new PipBoundsState(); mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState, mMockPipBoundsHandler, mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, Loading @@ -100,30 +102,58 @@ public class PipTaskOrganizerTest extends PipTestCase { assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void startSwipePipToHome_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, null); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); } @Test public void onTaskAppeared_updatesAspectRatio() { final Rational aspectRatio = new Rational(2, 1); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo( mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(aspectRatio)), null /* leash */); assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void onTaskAppeared_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), null /* leash */); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); } @Test public void onTaskInfoChanged_updatesAspectRatioIfChanged() { final Rational startAspectRatio = new Rational(2, 1); final Rational newAspectRatio = new Rational(1, 2); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo( mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(startAspectRatio)), null /* leash */); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(createPipParams(newAspectRatio))); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, createPipParams(newAspectRatio))); assertEquals(newAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void onTaskInfoChanged_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), null /* leash */); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, createPipParams(null))); assertEquals(mComponent2, mPipBoundsState.getLastPipComponentName()); } private void preparePipTaskOrg() { final DisplayInfo info = new DisplayInfo(); mPipBoundsState.setDisplayInfo(info); when(mMockPipBoundsHandler.getDestinationBounds(any(), any())).thenReturn(new Rect()); when(mMockPipBoundsHandler.getDestinationBounds(any(), any(), anyBoolean())) .thenReturn(new Rect()); Loading @@ -133,10 +163,12 @@ public class PipTaskOrganizerTest extends PipTestCase { doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any()); } private static ActivityManager.RunningTaskInfo createTaskInfo(PictureInPictureParams params) { private static ActivityManager.RunningTaskInfo createTaskInfo( ComponentName componentName, PictureInPictureParams params) { final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo(); info.token = mock(WindowContainerToken.class); info.pictureInPictureParams = params; info.topActivity = componentName; return info; } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +32 −2 Original line number Diff line number Diff line Loading @@ -20,11 +20,14 @@ import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.os.RemoteException; Loading @@ -34,6 +37,7 @@ import android.testing.TestableLooper; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipMediaController; Loading Loading @@ -64,6 +68,7 @@ public class PipControllerTest extends PipTestCase { @Mock private PipTouchHandler mMockPipTouchHandler; @Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper; @Mock private PipBoundsState mMockPipBoundsState; @Mock private ShellExecutor mMockExecutor; @Before public void setUp() throws RemoteException { Loading @@ -71,7 +76,11 @@ public class PipControllerTest extends PipTestCase { mPipController = new PipController(mContext, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState, mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer, mMockPipTouchHandler, mMockWindowManagerShellWrapper); mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor); doAnswer(invocation -> { ((Runnable) invocation.getArgument(0)).run(); return null; }).when(mMockExecutor).execute(any()); } @Test Loading Loading @@ -99,6 +108,27 @@ public class PipControllerTest extends PipTestCase { assertNull(PipController.create(spyContext, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState, mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer, mMockPipTouchHandler, mMockWindowManagerShellWrapper)); mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor)); } @Test public void onActivityHidden_isLastPipComponentName_clearLastPipComponent() { final ComponentName component1 = new ComponentName(mContext, "component1"); when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1); mPipController.mPinnedStackListener.onActivityHidden(component1); verify(mMockPipBoundsState).setLastPipComponentName(null); } @Test public void onActivityHidden_isNotLastPipComponentName_lastPipComponentNotCleared() { final ComponentName component1 = new ComponentName(mContext, "component1"); final ComponentName component2 = new ComponentName(mContext, "component2"); when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1); mPipController.mPinnedStackListener.onActivityHidden(component2); verify(mMockPipBoundsState, never()).setLastPipComponentName(null); } } packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +10 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.wm.shell.common.AnimationThread; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.HandlerExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; Loading Loading @@ -157,9 +158,9 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue, @Main Handler handler, TransactionPool transactionPool) { ShellExecutor mainExecutor, TransactionPool transactionPool) { return new ShellTaskOrganizer(syncQueue, transactionPool, new HandlerExecutor(handler), AnimationThread.instance().getExecutor()); mainExecutor, AnimationThread.instance().getExecutor()); } @BindsOptionalOf Loading @@ -174,4 +175,11 @@ public abstract class WMShellBaseModule { DisplayController displayController) { return Optional.ofNullable(OneHandedController.create(context, displayController)); } @WMSingleton @Provides static ShellExecutor provideMainShellExecutor(@Main Handler handler) { return new HandlerExecutor(handler); } } packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +4 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; Loading Loading @@ -82,11 +83,12 @@ public class WMShellModule { PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler, PipBoundsState pipBoundsState, PipMediaController pipMediaController, PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper) { PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper, ShellExecutor mainExecutor) { return Optional.ofNullable(PipController.create(context, displayController, pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper)); windowManagerShellWrapper, mainExecutor)); } @WMSingleton Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +26 −22 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ParceledListSlice; import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; Loading @@ -45,6 +44,7 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipBoundsHandler; Loading @@ -62,7 +62,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private static final String TAG = "PipController"; private Context mContext; private Handler mHandler = new Handler(); private ShellExecutor mMainExecutor; private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); private final Rect mTmpInsetBounds = new Rect(); Loading @@ -82,6 +82,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac protected PipMenuActivityController mMenuController; protected PipTaskOrganizer mPipTaskOrganizer; protected PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener = new PipControllerPinnedStackListener(); /** * Handler for display rotation changes. Loading Loading @@ -150,12 +152,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PinnedStackListenerForwarder.PinnedStackListener { @Override public void onListenerRegistered(IPinnedStackController controller) { mHandler.post(() -> mTouchHandler.setPinnedStackController(controller)); mMainExecutor.execute(() -> mTouchHandler.setPinnedStackController(controller)); } @Override public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight); mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight); }); Loading @@ -163,19 +165,19 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onMovementBoundsChanged(boolean fromImeAdjustment) { mHandler.post(() -> updateMovementBounds(null /* toBounds */, mMainExecutor.execute(() -> updateMovementBounds(null /* toBounds */, false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */, null /* windowContainerTransaction */)); } @Override public void onActionsChanged(ParceledListSlice<RemoteAction> actions) { mHandler.post(() -> mMenuController.setAppActions(actions)); mMainExecutor.execute(() -> mMenuController.setAppActions(actions)); } @Override public void onActivityHidden(ComponentName componentName) { mHandler.post(() -> { mMainExecutor.execute(() -> { if (componentName.equals(mPipBoundsState.getLastPipComponentName())) { // The activity was removed, we don't want to restore to the reentry state // saved for this component anymore. Loading @@ -186,12 +188,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onDisplayInfoChanged(DisplayInfo displayInfo) { mHandler.post(() -> mPipBoundsState.setDisplayInfo(displayInfo)); mMainExecutor.execute(() -> mPipBoundsState.setDisplayInfo(displayInfo)); } @Override public void onConfigurationChanged() { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsHandler.onConfigurationChanged(mContext); mTouchHandler.onConfigurationChanged(); }); Loading @@ -201,7 +203,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac public void onAspectRatioChanged(float aspectRatio) { // TODO(b/169373982): Remove this callback as it is redundant with PipTaskOrg params // change. mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsState.setAspectRatio(aspectRatio); mTouchHandler.onAspectRatioChanged(); }); Loading @@ -217,7 +219,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper WindowManagerShellWrapper windowManagerShellWrapper, ShellExecutor mainExecutor ) { // Ensure that we are the primary user's SystemUI. final int processUser = UserManager.get(context).getUserHandle(); Loading @@ -231,6 +234,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipBoundsHandler = pipBoundsHandler; mPipBoundsState = pipBoundsState; mPipTaskOrganizer = pipTaskOrganizer; mMainExecutor = mainExecutor; mPipTaskOrganizer.registerPipTransitionCallback(this); mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> { final DisplayInfo newDisplayInfo = new DisplayInfo(); Loading @@ -254,8 +258,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac mPipBoundsState.setDisplayInfo(displayInfo); try { mWindowManagerShellWrapper.addPinnedStackListener( new PipControllerPinnedStackListener()); mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener); } catch (RemoteException e) { Slog.e(TAG, "Failed to register pinned stack listener", e); } Loading @@ -263,14 +266,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onDensityOrFontScaleChanged() { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext); }); } @Override public void onActivityPinned(String packageName) { mHandler.post(() -> { mMainExecutor.execute(() -> { mTouchHandler.onActivityPinned(); mMediaController.onActivityPinned(); mMenuController.onActivityPinned(); Loading @@ -280,7 +283,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onActivityUnpinned(ComponentName topActivity) { mHandler.post(() -> { mMainExecutor.execute(() -> { mMenuController.onActivityUnpinned(); mTouchHandler.onActivityUnpinned(topActivity); mAppOpsListener.onActivityUnpinned(); Loading @@ -299,7 +302,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onOverlayChanged() { mHandler.post(() -> { mMainExecutor.execute(() -> { mPipBoundsState.setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay())); updateMovementBounds(null /* toBounds */, false /* fromRotation */, false /* fromImeAdjustment */, Loading Loading @@ -358,7 +361,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac */ @Override public void setShelfHeight(boolean visible, int height) { mHandler.post(() -> setShelfHeightLocked(visible, height)); mMainExecutor.execute(() -> setShelfHeightLocked(visible, height)); } private void setShelfHeightLocked(boolean visible, int height) { Loading @@ -374,12 +377,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void setPinnedStackAnimationType(int animationType) { mHandler.post(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType)); mMainExecutor.execute(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType)); } @Override public void setPinnedStackAnimationListener(Consumer<Boolean> callback) { mHandler.post(() -> mPinnedStackAnimationRecentsCallback = callback); mMainExecutor.execute(() -> mPinnedStackAnimationRecentsCallback = callback); } @Override Loading Loading @@ -476,7 +479,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac PipBoundsState pipBoundsState, PipMediaController pipMediaController, PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper) { WindowManagerShellWrapper windowManagerShellWrapper, ShellExecutor mainExecutor) { if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { Slog.w(TAG, "Device doesn't support Pip feature"); return null; Loading @@ -484,6 +488,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac return new PipController(context, displayController, pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper); pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper, mainExecutor); } }
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +36 −4 Original line number Diff line number Diff line Loading @@ -69,11 +69,13 @@ public class PipTaskOrganizerTest extends PipTestCase { private PipBoundsState mPipBoundsState; private ComponentName mComponent1; private ComponentName mComponent2; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); mComponent1 = new ComponentName(mContext, "component1"); mComponent2 = new ComponentName(mContext, "component2"); mPipBoundsState = new PipBoundsState(); mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState, mMockPipBoundsHandler, mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, Loading @@ -100,30 +102,58 @@ public class PipTaskOrganizerTest extends PipTestCase { assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void startSwipePipToHome_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, null); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); } @Test public void onTaskAppeared_updatesAspectRatio() { final Rational aspectRatio = new Rational(2, 1); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo( mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(aspectRatio)), null /* leash */); assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void onTaskAppeared_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), null /* leash */); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); } @Test public void onTaskInfoChanged_updatesAspectRatioIfChanged() { final Rational startAspectRatio = new Rational(2, 1); final Rational newAspectRatio = new Rational(1, 2); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo( mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(startAspectRatio)), null /* leash */); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(createPipParams(newAspectRatio))); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, createPipParams(newAspectRatio))); assertEquals(newAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void onTaskInfoChanged_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), null /* leash */); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, createPipParams(null))); assertEquals(mComponent2, mPipBoundsState.getLastPipComponentName()); } private void preparePipTaskOrg() { final DisplayInfo info = new DisplayInfo(); mPipBoundsState.setDisplayInfo(info); when(mMockPipBoundsHandler.getDestinationBounds(any(), any())).thenReturn(new Rect()); when(mMockPipBoundsHandler.getDestinationBounds(any(), any(), anyBoolean())) .thenReturn(new Rect()); Loading @@ -133,10 +163,12 @@ public class PipTaskOrganizerTest extends PipTestCase { doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any()); } private static ActivityManager.RunningTaskInfo createTaskInfo(PictureInPictureParams params) { private static ActivityManager.RunningTaskInfo createTaskInfo( ComponentName componentName, PictureInPictureParams params) { final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo(); info.token = mock(WindowContainerToken.class); info.pictureInPictureParams = params; info.topActivity = componentName; return info; } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +32 −2 Original line number Diff line number Diff line Loading @@ -20,11 +20,14 @@ import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.os.RemoteException; Loading @@ -34,6 +37,7 @@ import android.testing.TestableLooper; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PipBoundsHandler; import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipMediaController; Loading Loading @@ -64,6 +68,7 @@ public class PipControllerTest extends PipTestCase { @Mock private PipTouchHandler mMockPipTouchHandler; @Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper; @Mock private PipBoundsState mMockPipBoundsState; @Mock private ShellExecutor mMockExecutor; @Before public void setUp() throws RemoteException { Loading @@ -71,7 +76,11 @@ public class PipControllerTest extends PipTestCase { mPipController = new PipController(mContext, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState, mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer, mMockPipTouchHandler, mMockWindowManagerShellWrapper); mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor); doAnswer(invocation -> { ((Runnable) invocation.getArgument(0)).run(); return null; }).when(mMockExecutor).execute(any()); } @Test Loading Loading @@ -99,6 +108,27 @@ public class PipControllerTest extends PipTestCase { assertNull(PipController.create(spyContext, mMockDisplayController, mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState, mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer, mMockPipTouchHandler, mMockWindowManagerShellWrapper)); mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockExecutor)); } @Test public void onActivityHidden_isLastPipComponentName_clearLastPipComponent() { final ComponentName component1 = new ComponentName(mContext, "component1"); when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1); mPipController.mPinnedStackListener.onActivityHidden(component1); verify(mMockPipBoundsState).setLastPipComponentName(null); } @Test public void onActivityHidden_isNotLastPipComponentName_lastPipComponentNotCleared() { final ComponentName component1 = new ComponentName(mContext, "component1"); final ComponentName component2 = new ComponentName(mContext, "component2"); when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1); mPipController.mPinnedStackListener.onActivityHidden(component2); verify(mMockPipBoundsState, never()).setLastPipComponentName(null); } }
packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +10 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.wm.shell.common.AnimationThread; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.HandlerExecutor; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; Loading Loading @@ -157,9 +158,9 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue, @Main Handler handler, TransactionPool transactionPool) { ShellExecutor mainExecutor, TransactionPool transactionPool) { return new ShellTaskOrganizer(syncQueue, transactionPool, new HandlerExecutor(handler), AnimationThread.instance().getExecutor()); mainExecutor, AnimationThread.instance().getExecutor()); } @BindsOptionalOf Loading @@ -174,4 +175,11 @@ public abstract class WMShellBaseModule { DisplayController displayController) { return Optional.ofNullable(OneHandedController.create(context, displayController)); } @WMSingleton @Provides static ShellExecutor provideMainShellExecutor(@Main Handler handler) { return new HandlerExecutor(handler); } }
packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +4 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; Loading Loading @@ -82,11 +83,12 @@ public class WMShellModule { PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler, PipBoundsState pipBoundsState, PipMediaController pipMediaController, PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper) { PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper, ShellExecutor mainExecutor) { return Optional.ofNullable(PipController.create(context, displayController, pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer, pipTouchHandler, windowManagerShellWrapper)); windowManagerShellWrapper, mainExecutor)); } @WMSingleton Loading