Loading core/java/android/view/WindowManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -591,6 +591,13 @@ public interface WindowManager extends ViewManager { */ int TRANSIT_FLAG_KEYGUARD_UNOCCLUDING = (1 << 13); // 0x2000 /** * Transition flag: Indicates that there is a physical display switch * TODO(b/316112906) remove after defer_display_updates flag roll out * @hide */ int TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH = (1 << 14); // 0x4000 /** * @hide */ Loading @@ -608,7 +615,8 @@ public interface WindowManager extends ViewManager { TRANSIT_FLAG_INVISIBLE, TRANSIT_FLAG_KEYGUARD_APPEARING, TRANSIT_FLAG_KEYGUARD_OCCLUDING, TRANSIT_FLAG_KEYGUARD_UNOCCLUDING TRANSIT_FLAG_KEYGUARD_UNOCCLUDING, TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH, }) @Retention(RetentionPolicy.SOURCE) @interface TransitionFlags {} Loading libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java +19 −12 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.wm.shell.unfold; import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS; Loading Loading @@ -245,15 +246,22 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene public boolean shouldPlayUnfoldAnimation(@NonNull TransitionInfo transitionInfo) { // Unfold animation won't play when animations are disabled if (!ValueAnimator.areAnimatorsEnabled()) return false; // Only handle transitions that are marked as physical display switch // See PhysicalDisplaySwitchTransitionLauncher for the conditions if ((transitionInfo.getFlags() & TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH) == 0) return false; for (int i = 0; i < transitionInfo.getChanges().size(); i++) { final TransitionInfo.Change change = transitionInfo.getChanges().get(i); if ((change.getFlags() & TransitionInfo.FLAG_IS_DISPLAY) != 0) { if (change.getEndAbsBounds() == null || change.getStartAbsBounds() == null) { // We are interested only in display container changes if ((change.getFlags() & TransitionInfo.FLAG_IS_DISPLAY) == 0) { continue; } // Handle only unfolding, currently we don't have an animation when folding if (change.getEndAbsBounds() == null || change.getStartAbsBounds() == null) { continue; } final int afterArea = change.getEndAbsBounds().width() * change.getEndAbsBounds().height(); final int beforeArea = change.getStartAbsBounds().width() Loading @@ -263,7 +271,6 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene return true; } } } return false; } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java +28 −24 Original line number Diff line number Diff line Loading @@ -18,12 +18,11 @@ package com.android.wm.shell.unfold; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH; import static android.view.WindowManager.TRANSIT_NONE; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; Loading @@ -40,22 +39,17 @@ import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; import com.android.window.flags.FakeFeatureFlagsImpl; import com.android.window.flags.FeatureFlags; import com.android.window.flags.Flags; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.transition.TransitionInfoBuilder; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.transition.Transitions.TransitionFinishCallback; import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator; import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.ArrayList; import java.util.List; Loading Loading @@ -195,6 +189,22 @@ public class UnfoldTransitionHandlerTest { assertThat(animationStarted).isTrue(); } @Test public void startAnimation_differentTransitionFromRequestWithResize_doesNotStartAnimation() { mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo()); TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class); boolean animationStarted = mUnfoldTransitionHandler.startAnimation( mTransition, createDisplayResizeTransitionInfo(), mock(SurfaceControl.Transaction.class), mock(SurfaceControl.Transaction.class), finishCallback ); assertThat(animationStarted).isFalse(); } @Test public void startAnimation_differentTransitionFromRequestWithoutUnfold_doesNotStart() { mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo()); Loading Loading @@ -403,24 +413,18 @@ public class UnfoldTransitionHandlerTest { } } static class TestCase { private final boolean mShouldHandleMixedUnfold; public TestCase(boolean shouldHandleMixedUnfold) { mShouldHandleMixedUnfold = shouldHandleMixedUnfold; } public boolean mixedUnfoldFlagEnabled() { return mShouldHandleMixedUnfold; } @Override public String toString() { return "shouldHandleMixedUnfold flag = " + mShouldHandleMixedUnfold; } private TransitionInfo createUnfoldTransitionInfo() { TransitionInfo transitionInfo = new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0); TransitionInfo.Change change = new TransitionInfo.Change(null, mock(SurfaceControl.class)); change.setStartAbsBounds(new Rect(0, 0, 10, 10)); change.setEndAbsBounds(new Rect(0, 0, 100, 100)); change.setFlags(TransitionInfo.FLAG_IS_DISPLAY); transitionInfo.addChange(change); transitionInfo.setFlags(TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH); return transitionInfo; } private TransitionInfo createUnfoldTransitionInfo() { private TransitionInfo createDisplayResizeTransitionInfo() { TransitionInfo transitionInfo = new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0); TransitionInfo.Change change = new TransitionInfo.Change(null, mock(SurfaceControl.class)); change.setStartAbsBounds(new Rect(0, 0, 10, 10)); Loading services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java +11 −9 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH; import static com.android.internal.R.bool.config_unfoldTransitionEnabled; import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY; Loading Loading @@ -110,15 +111,6 @@ public class PhysicalDisplaySwitchTransitionLauncher { return; } final TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(displayId); final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight); displayChange.setStartAbsBounds(startAbsBounds); final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight); displayChange.setEndAbsBounds(endAbsBounds); displayChange.setPhysicalDisplayChanged(true); mTransition = null; if (mTransitionController.isCollecting()) { Loading @@ -128,10 +120,20 @@ public class PhysicalDisplaySwitchTransitionLauncher { // Make sure that transition is not ready until we finish the remote display change mTransition.setReady(mDisplayContent, false); mTransition.addFlag(TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH); ProtoLog.d(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Adding display switch to existing collecting transition"); } else { final TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(displayId); final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight); displayChange.setStartAbsBounds(startAbsBounds); final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight); displayChange.setEndAbsBounds(endAbsBounds); displayChange.setPhysicalDisplayChanged(true); mTransition = mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE, 0 /* flags */, mDisplayContent, mDisplayContent, null /* remoteTransition */, Loading Loading
core/java/android/view/WindowManager.java +9 −1 Original line number Diff line number Diff line Loading @@ -591,6 +591,13 @@ public interface WindowManager extends ViewManager { */ int TRANSIT_FLAG_KEYGUARD_UNOCCLUDING = (1 << 13); // 0x2000 /** * Transition flag: Indicates that there is a physical display switch * TODO(b/316112906) remove after defer_display_updates flag roll out * @hide */ int TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH = (1 << 14); // 0x4000 /** * @hide */ Loading @@ -608,7 +615,8 @@ public interface WindowManager extends ViewManager { TRANSIT_FLAG_INVISIBLE, TRANSIT_FLAG_KEYGUARD_APPEARING, TRANSIT_FLAG_KEYGUARD_OCCLUDING, TRANSIT_FLAG_KEYGUARD_UNOCCLUDING TRANSIT_FLAG_KEYGUARD_UNOCCLUDING, TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH, }) @Retention(RetentionPolicy.SOURCE) @interface TransitionFlags {} Loading
libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java +19 −12 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.wm.shell.unfold; import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS; Loading Loading @@ -245,15 +246,22 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene public boolean shouldPlayUnfoldAnimation(@NonNull TransitionInfo transitionInfo) { // Unfold animation won't play when animations are disabled if (!ValueAnimator.areAnimatorsEnabled()) return false; // Only handle transitions that are marked as physical display switch // See PhysicalDisplaySwitchTransitionLauncher for the conditions if ((transitionInfo.getFlags() & TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH) == 0) return false; for (int i = 0; i < transitionInfo.getChanges().size(); i++) { final TransitionInfo.Change change = transitionInfo.getChanges().get(i); if ((change.getFlags() & TransitionInfo.FLAG_IS_DISPLAY) != 0) { if (change.getEndAbsBounds() == null || change.getStartAbsBounds() == null) { // We are interested only in display container changes if ((change.getFlags() & TransitionInfo.FLAG_IS_DISPLAY) == 0) { continue; } // Handle only unfolding, currently we don't have an animation when folding if (change.getEndAbsBounds() == null || change.getStartAbsBounds() == null) { continue; } final int afterArea = change.getEndAbsBounds().width() * change.getEndAbsBounds().height(); final int beforeArea = change.getStartAbsBounds().width() Loading @@ -263,7 +271,6 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene return true; } } } return false; } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java +28 −24 Original line number Diff line number Diff line Loading @@ -18,12 +18,11 @@ package com.android.wm.shell.unfold; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH; import static android.view.WindowManager.TRANSIT_NONE; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; Loading @@ -40,22 +39,17 @@ import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; import com.android.window.flags.FakeFeatureFlagsImpl; import com.android.window.flags.FeatureFlags; import com.android.window.flags.Flags; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.transition.TransitionInfoBuilder; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.transition.Transitions.TransitionFinishCallback; import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator; import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.ArrayList; import java.util.List; Loading Loading @@ -195,6 +189,22 @@ public class UnfoldTransitionHandlerTest { assertThat(animationStarted).isTrue(); } @Test public void startAnimation_differentTransitionFromRequestWithResize_doesNotStartAnimation() { mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo()); TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class); boolean animationStarted = mUnfoldTransitionHandler.startAnimation( mTransition, createDisplayResizeTransitionInfo(), mock(SurfaceControl.Transaction.class), mock(SurfaceControl.Transaction.class), finishCallback ); assertThat(animationStarted).isFalse(); } @Test public void startAnimation_differentTransitionFromRequestWithoutUnfold_doesNotStart() { mUnfoldTransitionHandler.handleRequest(new Binder(), createNoneTransitionInfo()); Loading Loading @@ -403,24 +413,18 @@ public class UnfoldTransitionHandlerTest { } } static class TestCase { private final boolean mShouldHandleMixedUnfold; public TestCase(boolean shouldHandleMixedUnfold) { mShouldHandleMixedUnfold = shouldHandleMixedUnfold; } public boolean mixedUnfoldFlagEnabled() { return mShouldHandleMixedUnfold; } @Override public String toString() { return "shouldHandleMixedUnfold flag = " + mShouldHandleMixedUnfold; } private TransitionInfo createUnfoldTransitionInfo() { TransitionInfo transitionInfo = new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0); TransitionInfo.Change change = new TransitionInfo.Change(null, mock(SurfaceControl.class)); change.setStartAbsBounds(new Rect(0, 0, 10, 10)); change.setEndAbsBounds(new Rect(0, 0, 100, 100)); change.setFlags(TransitionInfo.FLAG_IS_DISPLAY); transitionInfo.addChange(change); transitionInfo.setFlags(TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH); return transitionInfo; } private TransitionInfo createUnfoldTransitionInfo() { private TransitionInfo createDisplayResizeTransitionInfo() { TransitionInfo transitionInfo = new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0); TransitionInfo.Change change = new TransitionInfo.Change(null, mock(SurfaceControl.class)); change.setStartAbsBounds(new Rect(0, 0, 10, 10)); Loading
services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java +11 −9 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH; import static com.android.internal.R.bool.config_unfoldTransitionEnabled; import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY; Loading Loading @@ -110,15 +111,6 @@ public class PhysicalDisplaySwitchTransitionLauncher { return; } final TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(displayId); final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight); displayChange.setStartAbsBounds(startAbsBounds); final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight); displayChange.setEndAbsBounds(endAbsBounds); displayChange.setPhysicalDisplayChanged(true); mTransition = null; if (mTransitionController.isCollecting()) { Loading @@ -128,10 +120,20 @@ public class PhysicalDisplaySwitchTransitionLauncher { // Make sure that transition is not ready until we finish the remote display change mTransition.setReady(mDisplayContent, false); mTransition.addFlag(TRANSIT_FLAG_PHYSICAL_DISPLAY_SWITCH); ProtoLog.d(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Adding display switch to existing collecting transition"); } else { final TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(displayId); final Rect startAbsBounds = new Rect(0, 0, oldDisplayWidth, oldDisplayHeight); displayChange.setStartAbsBounds(startAbsBounds); final Rect endAbsBounds = new Rect(0, 0, newDisplayWidth, newDisplayHeight); displayChange.setEndAbsBounds(endAbsBounds); displayChange.setPhysicalDisplayChanged(true); mTransition = mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE, 0 /* flags */, mDisplayContent, mDisplayContent, null /* remoteTransition */, Loading