summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2020-07-25 01:44:51 +0800
committer Riddle Hsu <riddlehsu@google.com> 2020-08-27 12:52:55 +0000
commit1f27ebfa55605dcdbda2e511d5829bdb6f686924 (patch)
tree5c11f55d9f6575e29f6fe1197a80cbd1ef17cca6
parent5a5734bbbaa96e4c2647eaed655ffac128ea3d5f (diff)
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 Merged-In: Ic134c4326db836e35385f290f996f0d841da693d
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java18
3 files changed, 34 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ed1f221576d9..0363ea0e7512 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1573,7 +1573,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// the heavy operations. This also benefits that the states of multiple activities
// are handled together.
r.linkFixedRotationTransform(prevRotatedLaunchingApp);
- setFixedRotationLaunchingAppUnchecked(r, rotation);
+ 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);
+ }
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 86aacf308068..1716dcd5ee16 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -531,7 +531,7 @@ class WindowToken extends WindowContainer<WindowState> {
void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
Configuration config) {
if (mFixedRotationTransformState != null) {
- return;
+ cleanUpFixedRotationTransformState(true /* replacing */);
}
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
new Configuration(config), mDisplayContent.getRotation());
@@ -548,13 +548,13 @@ class WindowToken extends WindowContainer<WindowState> {
* one. This takes the same effect as {@link #applyFixedRotationTransform}.
*/
void linkFixedRotationTransform(WindowToken other) {
- if (mFixedRotationTransformState != null) {
- return;
- }
final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
- if (fixedRotationState == null) {
+ if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) {
return;
}
+ if (mFixedRotationTransformState != null) {
+ cleanUpFixedRotationTransformState(true /* replacing */);
+ }
mFixedRotationTransformState = fixedRotationState;
fixedRotationState.mAssociatedTokens.add(this);
onConfigurationChanged(getParent().getConfiguration());
@@ -609,11 +609,17 @@ class WindowToken extends WindowContainer<WindowState> {
// 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.
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;
notifyFixedRotationTransform(false /* enabled */);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 23a097eb0c7c..0896db4b5532 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -139,6 +140,8 @@ public class WindowTokenTests extends WindowTestsBase {
public void testFinishFixedRotationTransform() {
final WindowToken appToken = mAppWindow.mToken;
final WindowToken wallpaperToken = mWallpaperWindow.mToken;
+ final WindowToken testToken =
+ WindowTestUtils.createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
final Configuration config = new Configuration(mDisplayContent.getConfiguration());
final int originalRotation = config.windowConfiguration.getRotation();
final int targetRotation = (originalRotation + 1) % 4;
@@ -151,11 +154,20 @@ public class WindowTokenTests extends WindowTestsBase {
assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation());
assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation());
- // The display doesn't rotate, the transformation will be canceled.
- mAppWindow.mToken.finishFixedRotationTransform();
+ testToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
+ // The wallpaperToken was linked to appToken, this should make it link to testToken.
+ wallpaperToken.linkFixedRotationTransform(testToken);
- // The window tokens should restore to the original rotation.
+ // Assume the display doesn't rotate, the transformation will be canceled.
+ appToken.finishFixedRotationTransform();
+
+ // The appToken should restore to the original rotation.
assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation());
+ // The wallpaperToken is linked to testToken, it should keep the target rotation.
+ assertNotEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation());
+
+ testToken.finishFixedRotationTransform();
+ // The rotation of wallpaperToken should be restored because its linked state is finished.
assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation());
}