Loading services/core/java/com/android/server/wm/Transition.java +19 −4 Original line number Diff line number Diff line Loading @@ -1316,11 +1316,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } change.setMode(info.getTransitMode(target)); change.setStartAbsBounds(info.mAbsoluteBounds); change.setEndAbsBounds(target.getBounds()); change.setEndRelOffset(target.getBounds().left - target.getParent().getBounds().left, target.getBounds().top - target.getParent().getBounds().top); change.setFlags(info.getChangeFlags(target)); change.setRotation(info.mRotation, target.getWindowConfiguration().getRotation()); final Task task = target.asTask(); if (task != null) { final ActivityManager.RunningTaskInfo tinfo = new ActivityManager.RunningTaskInfo(); Loading Loading @@ -1348,13 +1344,32 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } else if ((info.mFlags & ChangeInfo.FLAG_SEAMLESS_ROTATION) != 0) { change.setRotationAnimation(ROTATION_ANIMATION_SEAMLESS); } final WindowContainer<?> parent = target.getParent(); final Rect bounds = target.getBounds(); final Rect parentBounds = parent.getBounds(); change.setEndRelOffset(bounds.left - parentBounds.left, bounds.top - parentBounds.top); int endRotation = target.getWindowConfiguration().getRotation(); final ActivityRecord activityRecord = target.asActivityRecord(); if (activityRecord != null) { final Task arTask = activityRecord.getTask(); final int backgroundColor = ColorUtils.setAlphaComponent( arTask.getTaskDescription().getBackgroundColor(), 255); change.setBackgroundColor(backgroundColor); // TODO(b/227427984): Shell needs to aware letterbox. // Always use parent bounds of activity because letterbox area (e.g. fixed aspect // ratio or size compat mode) should be included in the animation. change.setEndAbsBounds(parentBounds); if (activityRecord.getRelativeDisplayRotation() != 0 && !activityRecord.mTransitionController.useShellTransitionsRotation()) { // Use parent rotation because shell doesn't know the surface is rotated. endRotation = parent.getWindowConfiguration().getRotation(); } } else { change.setEndAbsBounds(bounds); } change.setRotation(info.mRotation, endRotation); out.addChange(change); } Loading services/core/java/com/android/server/wm/TransitionController.java +1 −1 Original line number Diff line number Diff line Loading @@ -430,7 +430,7 @@ class TransitionController { }, true /* traverseTopToBottom */); // Collect all visible non-app windows which need to be drawn before the animation starts. dc.forAllWindows(w -> { if (w.mActivityRecord == null && w.isVisible() && !inTransition(w.mToken) if (w.mActivityRecord == null && w.isVisible() && !isCollecting(w.mToken) && dc.shouldSyncRotationChange(w)) { transition.collect(w.mToken); } Loading services/core/java/com/android/server/wm/WindowToken.java +0 −1 Original line number Diff line number Diff line Loading @@ -580,7 +580,6 @@ class WindowToken extends WindowContainer<WindowState> { .setParent(getParentSurfaceControl()) .setName(getSurfaceControl() + " - rotation-leash") .setHidden(false) .setEffectLayer() .setCallsite("WindowToken.getOrCreateFixedRotationLeash") .build(); t.setPosition(leash, mLastSurfacePosition.x, mLastSurfacePosition.y); Loading services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +45 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; Loading @@ -73,6 +75,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Function; /** * Build/Install/Run: Loading Loading @@ -588,6 +591,48 @@ public class TransitionTests extends WindowTestsBase { assertTrue(awaitInWmLock(() -> latch.await(3, TimeUnit.SECONDS))); } @Test public void testTransitionBounds() { registerTestTransitionPlayer(); final int offset = 10; final Function<WindowContainer<?>, TransitionInfo.Change> test = wc -> { final Transition transition = wc.mTransitionController.createTransition(TRANSIT_OPEN); transition.collect(wc); final int nextRotation = (wc.getWindowConfiguration().getRotation() + 1) % 4; wc.getWindowConfiguration().setRotation(nextRotation); wc.getWindowConfiguration().setDisplayRotation(nextRotation); final Rect bounds = wc.getWindowConfiguration().getBounds(); // Flip the bounds with offset. wc.getWindowConfiguration().setBounds( new Rect(offset, offset, bounds.height(), bounds.width())); final int flags = 0; final TransitionInfo info = Transition.calculateTransitionInfo(transition.mType, flags, Transition.calculateTargets(transition.mParticipants, transition.mChanges), transition.mChanges); transition.abort(); return info.getChanges().get(0); }; final ActivityRecord app = createActivityRecord(mDisplayContent); final TransitionInfo.Change changeOfActivity = test.apply(app); // There will be letterbox if the activity bounds don't match parent, so always use its // parent bounds for animation. assertEquals(app.getParent().getBounds(), changeOfActivity.getEndAbsBounds()); final int endRotation = app.mTransitionController.useShellTransitionsRotation() ? app.getWindowConfiguration().getRotation() // Without shell rotation, fixed rotation is done by core so the info should not // contain rotation change. : app.getParent().getWindowConfiguration().getRotation(); assertEquals(endRotation, changeOfActivity.getEndRotation()); // Non-activity target always uses its configuration for end info. final Task task = app.getTask(); final TransitionInfo.Change changeOfTask = test.apply(task); assertEquals(task.getBounds(), changeOfTask.getEndAbsBounds()); assertEquals(new Point(offset, offset), changeOfTask.getEndRelOffset()); assertEquals(task.getWindowConfiguration().getRotation(), changeOfTask.getEndRotation()); } @Test public void testDisplayRotationChange() { final Task task = createActivityRecord(mDisplayContent).getTask(); Loading Loading
services/core/java/com/android/server/wm/Transition.java +19 −4 Original line number Diff line number Diff line Loading @@ -1316,11 +1316,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } change.setMode(info.getTransitMode(target)); change.setStartAbsBounds(info.mAbsoluteBounds); change.setEndAbsBounds(target.getBounds()); change.setEndRelOffset(target.getBounds().left - target.getParent().getBounds().left, target.getBounds().top - target.getParent().getBounds().top); change.setFlags(info.getChangeFlags(target)); change.setRotation(info.mRotation, target.getWindowConfiguration().getRotation()); final Task task = target.asTask(); if (task != null) { final ActivityManager.RunningTaskInfo tinfo = new ActivityManager.RunningTaskInfo(); Loading Loading @@ -1348,13 +1344,32 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } else if ((info.mFlags & ChangeInfo.FLAG_SEAMLESS_ROTATION) != 0) { change.setRotationAnimation(ROTATION_ANIMATION_SEAMLESS); } final WindowContainer<?> parent = target.getParent(); final Rect bounds = target.getBounds(); final Rect parentBounds = parent.getBounds(); change.setEndRelOffset(bounds.left - parentBounds.left, bounds.top - parentBounds.top); int endRotation = target.getWindowConfiguration().getRotation(); final ActivityRecord activityRecord = target.asActivityRecord(); if (activityRecord != null) { final Task arTask = activityRecord.getTask(); final int backgroundColor = ColorUtils.setAlphaComponent( arTask.getTaskDescription().getBackgroundColor(), 255); change.setBackgroundColor(backgroundColor); // TODO(b/227427984): Shell needs to aware letterbox. // Always use parent bounds of activity because letterbox area (e.g. fixed aspect // ratio or size compat mode) should be included in the animation. change.setEndAbsBounds(parentBounds); if (activityRecord.getRelativeDisplayRotation() != 0 && !activityRecord.mTransitionController.useShellTransitionsRotation()) { // Use parent rotation because shell doesn't know the surface is rotated. endRotation = parent.getWindowConfiguration().getRotation(); } } else { change.setEndAbsBounds(bounds); } change.setRotation(info.mRotation, endRotation); out.addChange(change); } Loading
services/core/java/com/android/server/wm/TransitionController.java +1 −1 Original line number Diff line number Diff line Loading @@ -430,7 +430,7 @@ class TransitionController { }, true /* traverseTopToBottom */); // Collect all visible non-app windows which need to be drawn before the animation starts. dc.forAllWindows(w -> { if (w.mActivityRecord == null && w.isVisible() && !inTransition(w.mToken) if (w.mActivityRecord == null && w.isVisible() && !isCollecting(w.mToken) && dc.shouldSyncRotationChange(w)) { transition.collect(w.mToken); } Loading
services/core/java/com/android/server/wm/WindowToken.java +0 −1 Original line number Diff line number Diff line Loading @@ -580,7 +580,6 @@ class WindowToken extends WindowContainer<WindowState> { .setParent(getParentSurfaceControl()) .setName(getSurfaceControl() + " - rotation-leash") .setHidden(false) .setEffectLayer() .setCallsite("WindowToken.getOrCreateFixedRotationLeash") .build(); t.setPosition(leash, mLastSurfacePosition.x, mLastSurfacePosition.y); Loading
services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +45 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; Loading @@ -73,6 +75,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Function; /** * Build/Install/Run: Loading Loading @@ -588,6 +591,48 @@ public class TransitionTests extends WindowTestsBase { assertTrue(awaitInWmLock(() -> latch.await(3, TimeUnit.SECONDS))); } @Test public void testTransitionBounds() { registerTestTransitionPlayer(); final int offset = 10; final Function<WindowContainer<?>, TransitionInfo.Change> test = wc -> { final Transition transition = wc.mTransitionController.createTransition(TRANSIT_OPEN); transition.collect(wc); final int nextRotation = (wc.getWindowConfiguration().getRotation() + 1) % 4; wc.getWindowConfiguration().setRotation(nextRotation); wc.getWindowConfiguration().setDisplayRotation(nextRotation); final Rect bounds = wc.getWindowConfiguration().getBounds(); // Flip the bounds with offset. wc.getWindowConfiguration().setBounds( new Rect(offset, offset, bounds.height(), bounds.width())); final int flags = 0; final TransitionInfo info = Transition.calculateTransitionInfo(transition.mType, flags, Transition.calculateTargets(transition.mParticipants, transition.mChanges), transition.mChanges); transition.abort(); return info.getChanges().get(0); }; final ActivityRecord app = createActivityRecord(mDisplayContent); final TransitionInfo.Change changeOfActivity = test.apply(app); // There will be letterbox if the activity bounds don't match parent, so always use its // parent bounds for animation. assertEquals(app.getParent().getBounds(), changeOfActivity.getEndAbsBounds()); final int endRotation = app.mTransitionController.useShellTransitionsRotation() ? app.getWindowConfiguration().getRotation() // Without shell rotation, fixed rotation is done by core so the info should not // contain rotation change. : app.getParent().getWindowConfiguration().getRotation(); assertEquals(endRotation, changeOfActivity.getEndRotation()); // Non-activity target always uses its configuration for end info. final Task task = app.getTask(); final TransitionInfo.Change changeOfTask = test.apply(task); assertEquals(task.getBounds(), changeOfTask.getEndAbsBounds()); assertEquals(new Point(offset, offset), changeOfTask.getEndRelOffset()); assertEquals(task.getWindowConfiguration().getRotation(), changeOfTask.getEndRotation()); } @Test public void testDisplayRotationChange() { final Task task = createActivityRecord(mDisplayContent).getTask(); Loading