Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -481,6 +481,10 @@ public class PipTransitionState { // - there is no drag-to-desktop gesture in progress; otherwise the PiP resize // - there is no drag-to-desktop gesture in progress; otherwise the PiP resize // transition will block the drag-to-desktop transitions from finishing // transition will block the drag-to-desktop transitions from finishing return isPipStateIdle() && !mPipDesktopState.isDragToDesktopInProgress(); return isPipStateIdle() && !mPipDesktopState.isDragToDesktopInProgress(); case CHANGING_PIP_BOUNDS: return mState == SCHEDULED_BOUNDS_CHANGE; case CHANGED_PIP_BOUNDS: return mState == CHANGING_PIP_BOUNDS; default: default: return true; return true; } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipDisplayChangeObserver.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -88,7 +88,7 @@ public class PipDisplayChangeObserver implements Transitions.TransitionObserver private void onDisplayChangeStarting(@NonNull TransitionInfo info) { private void onDisplayChangeStarting(@NonNull TransitionInfo info) { final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); if (pipChange == null) return; if (pipChange == null || !mPipTransitionState.isPipStateIdle()) return; // We do not care about the extras in this case - just make sure to send a non-empty one; // We do not care about the extras in this case - just make sure to send a non-empty one; // since otherwise PipTransitionState might throw an exception. // since otherwise PipTransitionState might throw an exception. Loading @@ -103,7 +103,7 @@ public class PipDisplayChangeObserver implements Transitions.TransitionObserver private void onDisplayChangeFinished(@NonNull TransitionInfo info) { private void onDisplayChangeFinished(@NonNull TransitionInfo info) { final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); if (pipChange == null) return; if (pipChange == null || !mPipTransitionState.isInPip()) return; final Rect endBounds = pipChange.getEndAbsBounds(); final Rect endBounds = pipChange.getEndAbsBounds(); mPipBoundsState.setBounds(endBounds); mPipBoundsState.setBounds(endBounds); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java +26 −0 Original line number Original line Diff line number Diff line Loading @@ -173,10 +173,31 @@ public class PipTransitionStateTest extends ShellTestCase { PipTransitionState.SCHEDULED_BOUNDS_CHANGE)); PipTransitionState.SCHEDULED_BOUNDS_CHANGE)); } } @Test public void testShouldTransitionToState_changingPipBounds_afterScheduling_returnsTrue() { Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); Assert.assertTrue(mPipTransitionState.shouldTransitionToState( PipTransitionState.CHANGING_PIP_BOUNDS)); } @Test public void testShouldTransitionToState_changingPipBounds_withoutScheduling_returnsFalse() { mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); Assert.assertFalse(mPipTransitionState.shouldTransitionToState( PipTransitionState.CHANGING_PIP_BOUNDS)); } @Test @Test public void shouldTransitionToState_scheduledBoundsChangeWhileChangingBounds_returnsFalse() { public void shouldTransitionToState_scheduledBoundsChangeWhileChangingBounds_returnsFalse() { Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); Assert.assertFalse(mPipTransitionState.shouldTransitionToState( Assert.assertFalse(mPipTransitionState.shouldTransitionToState( Loading @@ -187,6 +208,7 @@ public class PipTransitionStateTest extends ShellTestCase { public void testResetSameState_scheduledBoundsChange_doNotDispatchStateChanged() { public void testResetSameState_scheduledBoundsChange_doNotDispatchStateChanged() { Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mStateChangedListener = mock(PipTransitionState.PipTransitionStateChangedListener.class); mStateChangedListener = mock(PipTransitionState.PipTransitionStateChangedListener.class); Loading @@ -202,6 +224,8 @@ public class PipTransitionStateTest extends ShellTestCase { // Choose an initial state. // Choose an initial state. Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); // Add the same PiP transition state changed listener twice. // Add the same PiP transition state changed listener twice. Loading Loading @@ -250,6 +274,8 @@ public class PipTransitionStateTest extends ShellTestCase { // pick a non-idle state // pick a non-idle state Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); final Runnable onIdleRunnable = () -> {}; final Runnable onIdleRunnable = () -> {}; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipDisplayChangeObserverTest.java +28 −0 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.mockito.kotlin.VerificationKt.clearInvocations; import static org.mockito.kotlin.VerificationKt.clearInvocations; import static org.mockito.kotlin.VerificationKt.never; import static org.mockito.kotlin.VerificationKt.never; import static org.mockito.kotlin.VerificationKt.verify; import static org.mockito.kotlin.VerificationKt.verify; Loading Loading @@ -105,6 +106,8 @@ public class PipDisplayChangeObserverTest { @Test @Test public void onTransitionStarting_withPipChange_updatesPipState() { public void onTransitionStarting_withPipChange_updatesPipState() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(true); final IBinder transition = new Binder(); final IBinder transition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); Loading @@ -120,8 +123,30 @@ public class PipDisplayChangeObserverTest { mPipDisplayChangeObserver.getDisplayChangeTransitions().get(transition)); mPipDisplayChangeObserver.getDisplayChangeTransitions().get(transition)); } } @Test public void onTransitionStarting_withNonIdlePipChange_updatesPipState() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(false); final IBinder transition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); mPipDisplayChangeObserver.onTransitionStarting(transition); verify(mMockPipTransitionState).setIsDisplayChangeScheduled(false); // Can't have state advancements when in a non-idle PiP state. verify(mMockPipTransitionState, never()).setState(anyInt(), any()); assertNotNull("Transition should remain cached during animation", mPipDisplayChangeObserver.getDisplayChangeTransitions().get(transition)); } @Test @Test public void onTransitionFinished_withPipChange_updatesPipStateAndCleansUp() { public void onTransitionFinished_withPipChange_updatesPipStateAndCleansUp() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(true); when(mMockPipTransitionState.isInPip()).thenReturn(true); final IBinder transition = new Binder(); final IBinder transition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); Loading @@ -138,6 +163,9 @@ public class PipDisplayChangeObserverTest { @Test @Test public void onTransitionMerged_withPipChange_updatesPipStateAndCleansUp() { public void onTransitionMerged_withPipChange_updatesPipStateAndCleansUp() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(true); when(mMockPipTransitionState.isInPip()).thenReturn(true); final IBinder mergedTransition = new Binder(); final IBinder mergedTransition = new Binder(); final IBinder playingTransition = new Binder(); final IBinder playingTransition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -481,6 +481,10 @@ public class PipTransitionState { // - there is no drag-to-desktop gesture in progress; otherwise the PiP resize // - there is no drag-to-desktop gesture in progress; otherwise the PiP resize // transition will block the drag-to-desktop transitions from finishing // transition will block the drag-to-desktop transitions from finishing return isPipStateIdle() && !mPipDesktopState.isDragToDesktopInProgress(); return isPipStateIdle() && !mPipDesktopState.isDragToDesktopInProgress(); case CHANGING_PIP_BOUNDS: return mState == SCHEDULED_BOUNDS_CHANGE; case CHANGED_PIP_BOUNDS: return mState == CHANGING_PIP_BOUNDS; default: default: return true; return true; } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipDisplayChangeObserver.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -88,7 +88,7 @@ public class PipDisplayChangeObserver implements Transitions.TransitionObserver private void onDisplayChangeStarting(@NonNull TransitionInfo info) { private void onDisplayChangeStarting(@NonNull TransitionInfo info) { final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); if (pipChange == null) return; if (pipChange == null || !mPipTransitionState.isPipStateIdle()) return; // We do not care about the extras in this case - just make sure to send a non-empty one; // We do not care about the extras in this case - just make sure to send a non-empty one; // since otherwise PipTransitionState might throw an exception. // since otherwise PipTransitionState might throw an exception. Loading @@ -103,7 +103,7 @@ public class PipDisplayChangeObserver implements Transitions.TransitionObserver private void onDisplayChangeFinished(@NonNull TransitionInfo info) { private void onDisplayChangeFinished(@NonNull TransitionInfo info) { final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); final TransitionInfo.Change pipChange = PipTransitionUtils.getPipChange(info); if (pipChange == null) return; if (pipChange == null || !mPipTransitionState.isInPip()) return; final Rect endBounds = pipChange.getEndAbsBounds(); final Rect endBounds = pipChange.getEndAbsBounds(); mPipBoundsState.setBounds(endBounds); mPipBoundsState.setBounds(endBounds); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTransitionStateTest.java +26 −0 Original line number Original line Diff line number Diff line Loading @@ -173,10 +173,31 @@ public class PipTransitionStateTest extends ShellTestCase { PipTransitionState.SCHEDULED_BOUNDS_CHANGE)); PipTransitionState.SCHEDULED_BOUNDS_CHANGE)); } } @Test public void testShouldTransitionToState_changingPipBounds_afterScheduling_returnsTrue() { Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); Assert.assertTrue(mPipTransitionState.shouldTransitionToState( PipTransitionState.CHANGING_PIP_BOUNDS)); } @Test public void testShouldTransitionToState_changingPipBounds_withoutScheduling_returnsFalse() { mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); Assert.assertFalse(mPipTransitionState.shouldTransitionToState( PipTransitionState.CHANGING_PIP_BOUNDS)); } @Test @Test public void shouldTransitionToState_scheduledBoundsChangeWhileChangingBounds_returnsFalse() { public void shouldTransitionToState_scheduledBoundsChangeWhileChangingBounds_returnsFalse() { Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); Assert.assertFalse(mPipTransitionState.shouldTransitionToState( Assert.assertFalse(mPipTransitionState.shouldTransitionToState( Loading @@ -187,6 +208,7 @@ public class PipTransitionStateTest extends ShellTestCase { public void testResetSameState_scheduledBoundsChange_doNotDispatchStateChanged() { public void testResetSameState_scheduledBoundsChange_doNotDispatchStateChanged() { Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mStateChangedListener = mock(PipTransitionState.PipTransitionStateChangedListener.class); mStateChangedListener = mock(PipTransitionState.PipTransitionStateChangedListener.class); Loading @@ -202,6 +224,8 @@ public class PipTransitionStateTest extends ShellTestCase { // Choose an initial state. // Choose an initial state. Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); // Add the same PiP transition state changed listener twice. // Add the same PiP transition state changed listener twice. Loading Loading @@ -250,6 +274,8 @@ public class PipTransitionStateTest extends ShellTestCase { // pick a non-idle state // pick a non-idle state Bundle extra = new Bundle(); Bundle extra = new Bundle(); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); extra.putParcelable(EXTRA_ENTRY_KEY, mEmptyParcelable); mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); final Runnable onIdleRunnable = () -> {}; final Runnable onIdleRunnable = () -> {}; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/transition/PipDisplayChangeObserverTest.java +28 −0 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.mockito.kotlin.VerificationKt.clearInvocations; import static org.mockito.kotlin.VerificationKt.clearInvocations; import static org.mockito.kotlin.VerificationKt.never; import static org.mockito.kotlin.VerificationKt.never; import static org.mockito.kotlin.VerificationKt.verify; import static org.mockito.kotlin.VerificationKt.verify; Loading Loading @@ -105,6 +106,8 @@ public class PipDisplayChangeObserverTest { @Test @Test public void onTransitionStarting_withPipChange_updatesPipState() { public void onTransitionStarting_withPipChange_updatesPipState() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(true); final IBinder transition = new Binder(); final IBinder transition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); Loading @@ -120,8 +123,30 @@ public class PipDisplayChangeObserverTest { mPipDisplayChangeObserver.getDisplayChangeTransitions().get(transition)); mPipDisplayChangeObserver.getDisplayChangeTransitions().get(transition)); } } @Test public void onTransitionStarting_withNonIdlePipChange_updatesPipState() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(false); final IBinder transition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); mPipDisplayChangeObserver.onTransitionStarting(transition); verify(mMockPipTransitionState).setIsDisplayChangeScheduled(false); // Can't have state advancements when in a non-idle PiP state. verify(mMockPipTransitionState, never()).setState(anyInt(), any()); assertNotNull("Transition should remain cached during animation", mPipDisplayChangeObserver.getDisplayChangeTransitions().get(transition)); } @Test @Test public void onTransitionFinished_withPipChange_updatesPipStateAndCleansUp() { public void onTransitionFinished_withPipChange_updatesPipStateAndCleansUp() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(true); when(mMockPipTransitionState.isInPip()).thenReturn(true); final IBinder transition = new Binder(); final IBinder transition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); mPipDisplayChangeObserver.onTransitionReady(transition, info, mStartTx, mFinishTx); Loading @@ -138,6 +163,9 @@ public class PipDisplayChangeObserverTest { @Test @Test public void onTransitionMerged_withPipChange_updatesPipStateAndCleansUp() { public void onTransitionMerged_withPipChange_updatesPipStateAndCleansUp() { when(mMockPipTransitionState.isPipStateIdle()).thenReturn(true); when(mMockPipTransitionState.isInPip()).thenReturn(true); final IBinder mergedTransition = new Binder(); final IBinder mergedTransition = new Binder(); final IBinder playingTransition = new Binder(); final IBinder playingTransition = new Binder(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); final TransitionInfo info = createPipBoundsChangingWithDisplayInfo(); Loading