Merge changes Ic966923a,I92c6dfac,Id370d798 into rvc-dev
* changes: Clear fixed rotation if display config does not change Polish fixed rotated recents animation Extensive handling of fixed rotation launching app
This commit is contained in:
@@ -494,10 +494,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
* The launching activity which is using fixed rotation transformation.
|
||||
*
|
||||
* @see #handleTopActivityLaunchingInDifferentOrientation
|
||||
* @see #setFixedRotationLaunchingApp
|
||||
* @see DisplayRotation#shouldRotateSeamlessly
|
||||
*/
|
||||
ActivityRecord mFixedRotationLaunchingApp;
|
||||
|
||||
final FixedRotationTransitionListener mFixedRotationTransitionListener =
|
||||
new FixedRotationTransitionListener();
|
||||
|
||||
/** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
|
||||
final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
|
||||
|
||||
@@ -928,6 +932,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
|
||||
mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
|
||||
mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier);
|
||||
mAppTransition.registerListenerLocked(mFixedRotationTransitionListener);
|
||||
mAppTransitionController = new AppTransitionController(mWmService, this);
|
||||
mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);
|
||||
|
||||
@@ -1266,6 +1271,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
if (configUpdated) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The display configuration doesn't change. If there is a launching transformed app, that
|
||||
// means its request to change display configuration has been discarded, then it should
|
||||
// respect to the current configuration of display.
|
||||
clearFixedRotationLaunchingApp();
|
||||
|
||||
// Something changed (E.g. device rotation), but no configuration update is needed.
|
||||
// E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to
|
||||
// unfreeze the display since we froze it when the rotation was updated in
|
||||
@@ -1383,7 +1394,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
orientationSource != null ? orientationSource.asActivityRecord() : null;
|
||||
// Currently there is no use case from non-activity.
|
||||
if (r != null && handleTopActivityLaunchingInDifferentOrientation(r)) {
|
||||
mFixedRotationLaunchingApp = r;
|
||||
// Display orientation should be deferred until the top fixed rotation is finished.
|
||||
return false;
|
||||
}
|
||||
@@ -1448,47 +1458,66 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
return false;
|
||||
}
|
||||
|
||||
startFixedRotationTransform(r, rotation);
|
||||
mAppTransition.registerListenerLocked(new WindowManagerInternal.AppTransitionListener() {
|
||||
void done() {
|
||||
r.finishFixedRotationTransform();
|
||||
mAppTransition.unregisterListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppTransitionFinishedLocked(IBinder token) {
|
||||
if (token == r.token) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppTransitionCancelledLocked(int transit) {
|
||||
done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppTransitionTimeoutLocked() {
|
||||
done();
|
||||
}
|
||||
});
|
||||
setFixedRotationLaunchingApp(r, rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @return {@code true} if the display orientation will be changed. */
|
||||
boolean continueUpdateOrientationForDiffOrienLaunchingApp(WindowToken token) {
|
||||
if (token != mFixedRotationLaunchingApp) {
|
||||
return false;
|
||||
/**
|
||||
* Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed
|
||||
* rotation transform to it and indicate that the display may be rotated after it is launched.
|
||||
*/
|
||||
void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Surface.Rotation int rotation) {
|
||||
final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
|
||||
if (prevRotatedLaunchingApp != null
|
||||
&& prevRotatedLaunchingApp.getWindowConfiguration().getRotation() == rotation
|
||||
// It is animating so we can expect there will have a transition callback.
|
||||
&& prevRotatedLaunchingApp.isAnimating(TRANSITION | PARENTS)) {
|
||||
// It may be the case that multiple activities launch consecutively. Because their
|
||||
// rotation are the same, the transformed state can be shared to avoid duplicating
|
||||
// the heavy operations. This also benefits that the states of multiple activities
|
||||
// are handled together.
|
||||
r.linkFixedRotationTransform(prevRotatedLaunchingApp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!r.hasFixedRotationTransform()) {
|
||||
startFixedRotationTransform(r, rotation);
|
||||
}
|
||||
mFixedRotationLaunchingApp = r;
|
||||
if (prevRotatedLaunchingApp != null) {
|
||||
prevRotatedLaunchingApp.finishFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue updating the orientation change of display if it was deferred by a top activity
|
||||
* launched in a different orientation.
|
||||
*/
|
||||
void continueUpdateOrientationForDiffOrienLaunchingApp() {
|
||||
if (mFixedRotationLaunchingApp == null) {
|
||||
return;
|
||||
}
|
||||
// Update directly because the app which will change the orientation of display is ready.
|
||||
if (mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */)) {
|
||||
sendNewConfiguration();
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
// The display won't rotate (e.g. the orientation from sensor has updated again before
|
||||
// applying rotation to display), so clear it to stop using seamless rotation.
|
||||
// The orientation of display is not changed.
|
||||
clearFixedRotationLaunchingApp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is
|
||||
* used when the display won't rotate (e.g. the orientation from sensor has updated again before
|
||||
* applying rotation to display) but the launching app has been transformed. So the record need
|
||||
* to be cleared and restored to stop using seamless rotation and rotated configuration.
|
||||
*/
|
||||
private void clearFixedRotationLaunchingApp() {
|
||||
if (mFixedRotationLaunchingApp == null) {
|
||||
return;
|
||||
}
|
||||
mFixedRotationLaunchingApp.finishFixedRotationTransform();
|
||||
mFixedRotationLaunchingApp = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void startFixedRotationTransform(WindowToken token, int rotation) {
|
||||
@@ -2858,6 +2887,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
pw.print(" mLastStatusBarVisibility=0x");
|
||||
pw.println(Integer.toHexString(mLastStatusBarVisibility));
|
||||
}
|
||||
if (mFixedRotationLaunchingApp != null) {
|
||||
pw.println(" mFixedRotationLaunchingApp=" + mFixedRotationLaunchingApp);
|
||||
}
|
||||
|
||||
pw.println();
|
||||
mWallpaperController.dump(pw, " ");
|
||||
@@ -5184,7 +5216,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
final int currRotation = currOverrideConfig.windowConfiguration.getRotation();
|
||||
final int overrideRotation = overrideConfiguration.windowConfiguration.getRotation();
|
||||
if (currRotation != ROTATION_UNDEFINED && currRotation != overrideRotation) {
|
||||
applyRotationAndClearFixedRotation(currRotation, overrideRotation);
|
||||
applyRotationAndFinishFixedRotation(currRotation, overrideRotation);
|
||||
}
|
||||
mCurrentOverrideConfigurationChanges = currOverrideConfig.diff(overrideConfiguration);
|
||||
super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
|
||||
@@ -5200,7 +5232,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
* fixed rotation transform also needs to be cleared to make sure the rotated activity fits
|
||||
* the display naturally.
|
||||
*/
|
||||
private void applyRotationAndClearFixedRotation(int oldRotation, int newRotation) {
|
||||
private void applyRotationAndFinishFixedRotation(int oldRotation, int newRotation) {
|
||||
if (mFixedRotationLaunchingApp == null) {
|
||||
applyRotation(oldRotation, newRotation);
|
||||
return;
|
||||
@@ -5219,7 +5251,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
});
|
||||
|
||||
mFixedRotationLaunchingApp.clearFixedRotationTransform(
|
||||
mFixedRotationLaunchingApp.finishFixedRotationTransform(
|
||||
() -> applyRotation(oldRotation, newRotation));
|
||||
mFixedRotationLaunchingApp = null;
|
||||
}
|
||||
@@ -5494,6 +5526,75 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
});
|
||||
}
|
||||
|
||||
/** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
|
||||
class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
|
||||
|
||||
/**
|
||||
* The animating activity which shows the recents task list. It is set between
|
||||
* {@link RecentsAnimationController#initialize} and
|
||||
* {@link RecentsAnimationController#cancelAnimation}.
|
||||
*/
|
||||
private ActivityRecord mAnimatingRecents;
|
||||
|
||||
/**
|
||||
* If the recents activity has a fixed orientation which is different from the current top
|
||||
* activity, it will be rotated before being shown so we avoid a screen rotation animation
|
||||
* when showing the Recents view.
|
||||
*/
|
||||
void onStartRecentsAnimation(@NonNull ActivityRecord r) {
|
||||
mAnimatingRecents = r;
|
||||
rotateInDifferentOrientationIfNeeded(r);
|
||||
if (r.hasFixedRotationTransform()) {
|
||||
// Set the record so we can recognize it to continue to update display orientation
|
||||
// if the recents activity becomes the top later.
|
||||
setFixedRotationLaunchingApp(r, r.getWindowConfiguration().getRotation());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link #mAnimatingRecents} still has fixed rotation, it should be moved to top so we
|
||||
* don't clear {@link #mFixedRotationLaunchingApp} that will be handled by transition.
|
||||
*/
|
||||
void onFinishRecentsAnimation() {
|
||||
final ActivityRecord animatingRecents = mAnimatingRecents;
|
||||
mAnimatingRecents = null;
|
||||
if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp
|
||||
&& !animatingRecents.hasFixedRotationTransform()) {
|
||||
// The recents activity won't be the top, such as giving up the swipe up gesture
|
||||
// and return to the original top.
|
||||
mFixedRotationLaunchingApp = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppTransitionFinishedLocked(IBinder token) {
|
||||
final ActivityRecord r = getActivityRecord(token);
|
||||
// Ignore the animating recents so the fixed rotation transform won't be switched twice
|
||||
// by finishing the recents animation and moving it to top. That also avoids flickering
|
||||
// due to wait for previous activity to be paused if it supports PiP that ignores the
|
||||
// effect of resume-while-pausing.
|
||||
if (r == null || r == mAnimatingRecents) {
|
||||
return;
|
||||
}
|
||||
if (mFixedRotationLaunchingApp != null
|
||||
&& mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) {
|
||||
continueUpdateOrientationForDiffOrienLaunchingApp();
|
||||
} else {
|
||||
r.finishFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppTransitionCancelledLocked(int transit) {
|
||||
continueUpdateOrientationForDiffOrienLaunchingApp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppTransitionTimeoutLocked() {
|
||||
continueUpdateOrientationForDiffOrienLaunchingApp();
|
||||
}
|
||||
}
|
||||
|
||||
class RemoteInsetsControlTarget implements InsetsControlTarget {
|
||||
private final IDisplayWindowInsetsController mRemoteInsetsController;
|
||||
|
||||
|
||||
@@ -411,10 +411,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
mService.mWindowPlacerLocked.performSurfacePlacement();
|
||||
|
||||
// If the target activity has a fixed orientation which is different from the current top
|
||||
// activity, it will be rotated before being shown so we avoid a screen rotation
|
||||
// animation when showing the Recents view.
|
||||
mDisplayContent.rotateInDifferentOrientationIfNeeded(mTargetActivityRecord);
|
||||
mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(targetActivity);
|
||||
|
||||
// Notify that the animation has started
|
||||
if (mStatusBar != null) {
|
||||
@@ -736,11 +733,13 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
|
||||
mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(
|
||||
mTargetActivityRecord.token);
|
||||
}
|
||||
if (mTargetActivityRecord.hasFixedRotationTransform()) {
|
||||
} else {
|
||||
// The target activity will be moved to original position (non-top). Since it won't
|
||||
// affect display orientation, just finish the transform.
|
||||
mTargetActivityRecord.finishFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation();
|
||||
|
||||
// Notify that the animation has ended
|
||||
if (mStatusBar != null) {
|
||||
|
||||
@@ -119,7 +119,6 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
* rotated by the given rotated display info, frames and insets.
|
||||
*/
|
||||
private static class FixedRotationTransformState {
|
||||
final WindowToken mOwner;
|
||||
final DisplayInfo mDisplayInfo;
|
||||
final DisplayFrames mDisplayFrames;
|
||||
final InsetsState mInsetsState;
|
||||
@@ -133,10 +132,9 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3);
|
||||
boolean mIsTransforming = true;
|
||||
|
||||
FixedRotationTransformState(WindowToken owner, DisplayInfo rotatedDisplayInfo,
|
||||
FixedRotationTransformState(DisplayInfo rotatedDisplayInfo,
|
||||
DisplayFrames rotatedDisplayFrames, InsetsState rotatedInsetsState,
|
||||
Configuration rotatedConfig, int currentRotation) {
|
||||
mOwner = owner;
|
||||
mDisplayInfo = rotatedDisplayInfo;
|
||||
mDisplayFrames = rotatedDisplayFrames;
|
||||
mInsetsState = rotatedInsetsState;
|
||||
@@ -482,6 +480,14 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
return mFixedRotationTransformState != null;
|
||||
}
|
||||
|
||||
/** Returns {@code true} if the given token shares the same transform. */
|
||||
boolean hasFixedRotationTransform(WindowToken token) {
|
||||
if (mFixedRotationTransformState == null || token == null) {
|
||||
return false;
|
||||
}
|
||||
return this == token || mFixedRotationTransformState == token.mFixedRotationTransformState;
|
||||
}
|
||||
|
||||
boolean isFinishingFixedRotationTransform() {
|
||||
return mFixedRotationTransformState != null
|
||||
&& !mFixedRotationTransformState.mIsTransforming;
|
||||
@@ -520,15 +526,14 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
final InsetsState insetsState = new InsetsState();
|
||||
mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames, insetsState,
|
||||
mDisplayContent.getConfiguration().uiMode);
|
||||
mFixedRotationTransformState = new FixedRotationTransformState(this, info, displayFrames,
|
||||
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
|
||||
insetsState, new Configuration(config), mDisplayContent.getRotation());
|
||||
onConfigurationChanged(getParent().getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reuses the {@link FixedRotationTransformState} (if any) from the other WindowToken to this
|
||||
* one. This takes the same effect as {@link #applyFixedRotationTransform}, but the linked state
|
||||
* can only be cleared by the state owner.
|
||||
* one. This takes the same effect as {@link #applyFixedRotationTransform}.
|
||||
*/
|
||||
void linkFixedRotationTransform(WindowToken other) {
|
||||
if (mFixedRotationTransformState != null) {
|
||||
@@ -543,28 +548,15 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
onConfigurationChanged(getParent().getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the transform and continue updating the orientation change of display. Only the
|
||||
* state owner can finish the transform state.
|
||||
*/
|
||||
void finishFixedRotationTransform() {
|
||||
if (mFixedRotationTransformState == null || mFixedRotationTransformState.mOwner != this) {
|
||||
return;
|
||||
}
|
||||
final boolean changed =
|
||||
mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(this);
|
||||
// If it is not the launching app or the display is not rotated, make sure the transform is
|
||||
// cleared and the configuration is restored from parent.
|
||||
if (!changed) {
|
||||
clearFixedRotationTransform(null /* applyDisplayRotation */);
|
||||
}
|
||||
finishFixedRotationTransform(null /* applyDisplayRotation */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the transform and apply display rotation if the action is given. If the display will
|
||||
* Finishes the transform and apply display rotation if the action is given. If the display will
|
||||
* not rotate, the transformed containers are restored to their original states.
|
||||
*/
|
||||
void clearFixedRotationTransform(Runnable applyDisplayRotation) {
|
||||
void finishFixedRotationTransform(Runnable applyDisplayRotation) {
|
||||
final FixedRotationTransformState state = mFixedRotationTransformState;
|
||||
if (state == null) {
|
||||
return;
|
||||
|
||||
@@ -66,6 +66,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.never;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
@@ -1402,6 +1403,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
||||
final DisplayInfo rotatedInfo = mActivity.getFixedRotationTransformDisplayInfo();
|
||||
mActivity.finishFixedRotationTransform();
|
||||
final ScreenRotationAnimation rotationAnim = display.getRotationAnimation();
|
||||
assertNotNull(rotationAnim);
|
||||
rotationAnim.setRotation(display.getPendingTransaction(), originalRotation);
|
||||
|
||||
// Because the display doesn't rotate, the rotated activity needs to cancel the fixed
|
||||
@@ -1409,8 +1411,18 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
||||
verify(mActivity).onCancelFixedRotationTransform(rotatedInfo.rotation);
|
||||
assertTrue(mActivity.isFreezingScreen());
|
||||
assertFalse(displayRotation.isRotatingSeamlessly());
|
||||
assertNotNull(rotationAnim);
|
||||
assertTrue(rotationAnim.isRotating());
|
||||
|
||||
// Simulate the remote rotation has completed and the configuration doesn't change, then
|
||||
// the rotated activity should also be restored by clearing the transform.
|
||||
displayRotation.updateRotationUnchecked(true /* forceUpdate */);
|
||||
doReturn(false).when(displayRotation).isWaitingForRemoteRotation();
|
||||
clearInvocations(mActivity);
|
||||
display.mFixedRotationLaunchingApp = mActivity;
|
||||
display.sendNewConfiguration();
|
||||
|
||||
assertNull(display.mFixedRotationLaunchingApp);
|
||||
assertFalse(mActivity.hasFixedRotationTransform());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -790,9 +790,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.getDisplayRotation().setFixedToUserRotation(
|
||||
IWindowManager.FIXED_TO_USER_ROTATION_DISABLED);
|
||||
final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
|
||||
? SCREEN_ORIENTATION_PORTRAIT
|
||||
: SCREEN_ORIENTATION_LANDSCAPE;
|
||||
final int newOrientation = getRotatedOrientation(dc);
|
||||
|
||||
final ActivityStack stack =
|
||||
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
|
||||
@@ -812,9 +810,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
dc.getDisplayRotation().setFixedToUserRotation(
|
||||
IWindowManager.FIXED_TO_USER_ROTATION_ENABLED);
|
||||
final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
|
||||
? SCREEN_ORIENTATION_PORTRAIT
|
||||
: SCREEN_ORIENTATION_LANDSCAPE;
|
||||
final int newOrientation = getRotatedOrientation(dc);
|
||||
|
||||
final ActivityStack stack =
|
||||
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer)
|
||||
@@ -1083,7 +1079,8 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
|
||||
false /* alwaysKeepCurrent */);
|
||||
mDisplayContent.mOpeningApps.add(app);
|
||||
app.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
|
||||
final int newOrientation = getRotatedOrientation(mDisplayContent);
|
||||
app.setRequestedOrientation(newOrientation);
|
||||
|
||||
assertTrue(app.isFixedRotationTransforming());
|
||||
assertTrue(mDisplayContent.getDisplayRotation().shouldRotateSeamlessly(
|
||||
@@ -1124,12 +1121,25 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
mWallpaperWindow.mToken.onAnimationLeashCreated(t, null /* leash */);
|
||||
verify(t, never()).setPosition(any(), eq(0), eq(0));
|
||||
|
||||
// Launch another activity before the transition is finished.
|
||||
final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot)
|
||||
.setDisplay(mDisplayContent).build().getTopMostActivity();
|
||||
mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN,
|
||||
false /* alwaysKeepCurrent */);
|
||||
mDisplayContent.mOpeningApps.add(app2);
|
||||
app2.setRequestedOrientation(newOrientation);
|
||||
|
||||
// The activity should share the same transform state as the existing one.
|
||||
assertTrue(app.hasFixedRotationTransform(app2));
|
||||
|
||||
// The display should be rotated after the launch is finished.
|
||||
mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token);
|
||||
|
||||
// The animation in old rotation should be cancelled.
|
||||
assertFalse(closingApp.isAnimating());
|
||||
// The display should be rotated after the launch is finished.
|
||||
// The fixed rotation should be cleared and the new rotation is applied to display.
|
||||
assertFalse(app.hasFixedRotationTransform());
|
||||
assertFalse(app2.hasFixedRotationTransform());
|
||||
assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation);
|
||||
}
|
||||
|
||||
@@ -1292,6 +1302,12 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
|
||||
}
|
||||
|
||||
private static int getRotatedOrientation(DisplayContent dc) {
|
||||
return dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
|
||||
? SCREEN_ORIENTATION_PORTRAIT
|
||||
: SCREEN_ORIENTATION_LANDSCAPE;
|
||||
}
|
||||
|
||||
private static List<WindowState> reverseList(List<WindowState> list) {
|
||||
final ArrayList<WindowState> result = new ArrayList<>(list);
|
||||
Collections.reverse(result);
|
||||
|
||||
@@ -344,9 +344,17 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
||||
|
||||
mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
|
||||
|
||||
assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp);
|
||||
|
||||
// Check that the home app is in portrait
|
||||
assertEquals(Configuration.ORIENTATION_PORTRAIT,
|
||||
homeActivity.getConfiguration().orientation);
|
||||
|
||||
// Home activity won't become top (return to landActivity), so its fixed rotation and the
|
||||
// top rotated record should be cleared.
|
||||
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
|
||||
assertFalse(homeActivity.hasFixedRotationTransform());
|
||||
assertNull(mDefaultDisplay.mFixedRotationLaunchingApp);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -401,12 +409,16 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
||||
assertEquals(Configuration.ORIENTATION_PORTRAIT,
|
||||
wallpapers.get(0).getConfiguration().orientation);
|
||||
|
||||
// Wallpaper's transform state is controlled by home, so the invocation should be no-op.
|
||||
wallpaperWindowToken.finishFixedRotationTransform();
|
||||
assertTrue(wallpaperWindowToken.hasFixedRotationTransform());
|
||||
mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
|
||||
// The transform state should keep because we expect to listen the signal from the
|
||||
// transition executed by moving the task to front.
|
||||
assertTrue(homeActivity.hasFixedRotationTransform());
|
||||
assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp);
|
||||
|
||||
mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(
|
||||
homeActivity.token);
|
||||
// Wallpaper's transform state should be cleared with home.
|
||||
homeActivity.finishFixedRotationTransform();
|
||||
assertFalse(homeActivity.hasFixedRotationTransform());
|
||||
assertFalse(wallpaperWindowToken.hasFixedRotationTransform());
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ public class WindowTokenTests extends WindowTestsBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearFixedRotationTransform() {
|
||||
public void testFinishFixedRotationTransform() {
|
||||
final WindowToken appToken = mAppWindow.mToken;
|
||||
final WindowToken wallpaperToken = mWallpaperWindow.mToken;
|
||||
final Configuration config = new Configuration(mDisplayContent.getConfiguration());
|
||||
@@ -152,7 +152,7 @@ public class WindowTokenTests extends WindowTestsBase {
|
||||
assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation());
|
||||
|
||||
// The display doesn't rotate, the transformation will be canceled.
|
||||
mAppWindow.mToken.clearFixedRotationTransform(null /* applyDisplayRotation */);
|
||||
mAppWindow.mToken.finishFixedRotationTransform();
|
||||
|
||||
// The window tokens should restore to the original rotation.
|
||||
assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation());
|
||||
|
||||
Reference in New Issue
Block a user