Allow to replace fixed rotation state
Assume there are 2 activities with different fixed rotation states A and B. And wallpaper was associated with A. When the wallpaper target is changed to B, wallpaper should be able to change the association to B so their rotation transform can be updated at the same time. This also avoids that if the previous associated token is somehow inactive, wallpaper won't in a dangling rotated state. Also add a check of updating rotated launching app for the case: launching a portrait app from a landscape app and trigger recents animation immediately before the animation of portrait app is done. And then finish recents animation by keeping the portrait app as the top activity. The expected result should be that the display is rotated from landscape to portrait seamlessly. But if the recents activity is set to the rotated launching app, the display rotation will be unable to update because when receiving animation done of the portrait app, the recents animation is still active that skips the rotation change. Then the portrait app will be updated to landscape temporally. Fixes: 161056612 Test: atest WindowTokenTests#testFinishFixedRotationTransform Change-Id: Ic134c4326db836e35385f290f996f0d841da693d
This commit is contained in:
@@ -1557,7 +1557,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
// the heavy operations. This also benefits that the states of multiple activities
|
// the heavy operations. This also benefits that the states of multiple activities
|
||||||
// are handled together.
|
// are handled together.
|
||||||
r.linkFixedRotationTransform(prevRotatedLaunchingApp);
|
r.linkFixedRotationTransform(prevRotatedLaunchingApp);
|
||||||
|
if (r != mFixedRotationTransitionListener.mAnimatingRecents) {
|
||||||
|
// Only update the record for normal activity so the display orientation can be
|
||||||
|
// updated when the transition is done if it becomes the top. And the case of
|
||||||
|
// recents can be handled when the recents animation is finished.
|
||||||
setFixedRotationLaunchingAppUnchecked(r, rotation);
|
setFixedRotationLaunchingAppUnchecked(r, rotation);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -548,7 +548,7 @@ class WindowToken extends WindowContainer<WindowState> {
|
|||||||
void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
|
void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
|
||||||
Configuration config) {
|
Configuration config) {
|
||||||
if (mFixedRotationTransformState != null) {
|
if (mFixedRotationTransformState != null) {
|
||||||
return;
|
cleanUpFixedRotationTransformState(true /* replacing */);
|
||||||
}
|
}
|
||||||
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
|
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
|
||||||
new Configuration(config), mDisplayContent.getRotation());
|
new Configuration(config), mDisplayContent.getRotation());
|
||||||
@@ -565,12 +565,12 @@ class WindowToken extends WindowContainer<WindowState> {
|
|||||||
* one. This takes the same effect as {@link #applyFixedRotationTransform}.
|
* one. This takes the same effect as {@link #applyFixedRotationTransform}.
|
||||||
*/
|
*/
|
||||||
void linkFixedRotationTransform(WindowToken other) {
|
void linkFixedRotationTransform(WindowToken other) {
|
||||||
if (mFixedRotationTransformState != null) {
|
final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
|
||||||
|
if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
|
if (mFixedRotationTransformState != null) {
|
||||||
if (fixedRotationState == null) {
|
cleanUpFixedRotationTransformState(true /* replacing */);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
mFixedRotationTransformState = fixedRotationState;
|
mFixedRotationTransformState = fixedRotationState;
|
||||||
fixedRotationState.mAssociatedTokens.add(this);
|
fixedRotationState.mAssociatedTokens.add(this);
|
||||||
@@ -626,11 +626,17 @@ class WindowToken extends WindowContainer<WindowState> {
|
|||||||
// The state is cleared at the end, because it is used to indicate that other windows can
|
// The state is cleared at the end, because it is used to indicate that other windows can
|
||||||
// use seamless rotation when applying rotation to display.
|
// use seamless rotation when applying rotation to display.
|
||||||
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
|
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
|
||||||
state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState();
|
state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState(
|
||||||
|
false /* replacing */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanUpFixedRotationTransformState() {
|
private void cleanUpFixedRotationTransformState(boolean replacing) {
|
||||||
|
if (replacing && mFixedRotationTransformState.mAssociatedTokens.size() > 1) {
|
||||||
|
// The state is not only used by self. Make sure to leave the influence by others.
|
||||||
|
mFixedRotationTransformState.mAssociatedTokens.remove(this);
|
||||||
|
mFixedRotationTransformState.mRotatedContainers.remove(this);
|
||||||
|
}
|
||||||
mFixedRotationTransformState = null;
|
mFixedRotationTransformState = null;
|
||||||
notifyFixedRotationTransform(false /* enabled */);
|
notifyFixedRotationTransform(false /* enabled */);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -145,29 +146,40 @@ public class WindowTokenTests extends WindowTestsBase {
|
|||||||
assertEquals(0, token.getWindowsCount());
|
assertEquals(0, token.getWindowsCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER })
|
|
||||||
@Test
|
@Test
|
||||||
public void testFinishFixedRotationTransform() {
|
public void testFinishFixedRotationTransform() {
|
||||||
final WindowToken appToken = mAppWindow.mToken;
|
final WindowToken[] tokens = new WindowToken[3];
|
||||||
final WindowToken wallpaperToken = mWallpaperWindow.mToken;
|
for (int i = 0; i < tokens.length; i++) {
|
||||||
|
tokens[i] = createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
|
||||||
|
}
|
||||||
|
|
||||||
final Configuration config = new Configuration(mDisplayContent.getConfiguration());
|
final Configuration config = new Configuration(mDisplayContent.getConfiguration());
|
||||||
final int originalRotation = config.windowConfiguration.getRotation();
|
final int originalRotation = config.windowConfiguration.getRotation();
|
||||||
final int targetRotation = (originalRotation + 1) % 4;
|
final int targetRotation = (originalRotation + 1) % 4;
|
||||||
|
|
||||||
config.windowConfiguration.setRotation(targetRotation);
|
config.windowConfiguration.setRotation(targetRotation);
|
||||||
appToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
|
tokens[0].applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
|
||||||
wallpaperToken.linkFixedRotationTransform(appToken);
|
tokens[1].linkFixedRotationTransform(tokens[0]);
|
||||||
|
|
||||||
// The window tokens should apply the rotation by the transformation.
|
// The window tokens should apply the rotation by the transformation.
|
||||||
assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation());
|
assertEquals(targetRotation, tokens[0].getWindowConfiguration().getRotation());
|
||||||
assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation());
|
assertEquals(targetRotation, tokens[1].getWindowConfiguration().getRotation());
|
||||||
|
|
||||||
// The display doesn't rotate, the transformation will be canceled.
|
tokens[2].applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
|
||||||
mAppWindow.mToken.finishFixedRotationTransform();
|
// The tokens[1] was linked to tokens[0], this should make tokens[1] link to tokens[2].
|
||||||
|
tokens[1].linkFixedRotationTransform(tokens[2]);
|
||||||
|
|
||||||
// The window tokens should restore to the original rotation.
|
// Assume the display doesn't rotate, the transformation will be canceled.
|
||||||
assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation());
|
tokens[0].finishFixedRotationTransform();
|
||||||
assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation());
|
|
||||||
|
// The tokens[0] should restore to the original rotation.
|
||||||
|
assertEquals(originalRotation, tokens[0].getWindowConfiguration().getRotation());
|
||||||
|
// The tokens[1] is linked to tokens[2], it should keep the target rotation.
|
||||||
|
assertNotEquals(originalRotation, tokens[1].getWindowConfiguration().getRotation());
|
||||||
|
|
||||||
|
tokens[2].finishFixedRotationTransform();
|
||||||
|
// The rotation of tokens[1] should be restored because its linked state is finished.
|
||||||
|
assertEquals(originalRotation, tokens[1].getWindowConfiguration().getRotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user