summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java67
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java24
3 files changed, 58 insertions, 35 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f18f2369f133..257d79d2c153 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1641,7 +1641,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
final Configuration config = mWindowManager.updateOrientationFromAppTokens(
getDisplayOverrideConfiguration(displayId),
r != null && r.mayFreezeScreenLocked(r.app) ? r.appToken : null,
- displayId);
+ displayId, true /* forceUpdate */);
if (r != null && markFrozenIfConfigChanged && config != null) {
r.frozenBeforeDestroy = true;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f3423c63e270..b59e728a721e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -944,33 +944,50 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
/**
* Update rotation of the display.
*
- * Returns true if the rotation has been changed. In this case YOU MUST CALL
- * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
+ * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
+ * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
*/
boolean updateRotationUnchecked() {
- if (mService.mDeferredRotationPauseCount > 0) {
- // Rotation updates have been paused temporarily. Defer the update until
- // updates have been resumed.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
- return false;
- }
+ return updateRotationUnchecked(false /* forceUpdate */);
+ }
- ScreenRotationAnimation screenRotationAnimation =
- mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
- if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
- // Rotation updates cannot be performed while the previous rotation change
- // animation is still in progress. Skip this update. We will try updating
- // again after the animation is finished and the display is unfrozen.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
- return false;
- }
- if (mService.mDisplayFrozen) {
- // Even if the screen rotation animation has finished (e.g. isAnimating
- // returns false), there is still some time where we haven't yet unfrozen
- // the display. We also need to abort rotation here.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "Deferring rotation, still finishing previous rotation");
- return false;
+ /**
+ * Update rotation of the display with an option to force the update.
+ * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
+ * orientation because we're waiting for some rotation to finish or display
+ * to unfreeze, which results in configuration of the previously visible
+ * activity being applied to a newly visible one. Forcing the rotation
+ * update allows to workaround this issue.
+ * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
+ * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
+ */
+ boolean updateRotationUnchecked(boolean forceUpdate) {
+ ScreenRotationAnimation screenRotationAnimation;
+ if (!forceUpdate) {
+ if (mService.mDeferredRotationPauseCount > 0) {
+ // Rotation updates have been paused temporarily. Defer the update until
+ // updates have been resumed.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
+ return false;
+ }
+
+ screenRotationAnimation =
+ mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
+ if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
+ // Rotation updates cannot be performed while the previous rotation change
+ // animation is still in progress. Skip this update. We will try updating
+ // again after the animation is finished and the display is unfrozen.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
+ return false;
+ }
+ if (mService.mDisplayFrozen) {
+ // Even if the screen rotation animation has finished (e.g. isAnimating
+ // returns false), there is still some time where we haven't yet unfrozen
+ // the display. We also need to abort rotation here.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+ "Deferring rotation, still finishing previous rotation");
+ return false;
+ }
}
if (!mService.mDisplayEnabled) {
@@ -992,7 +1009,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (mayRotateSeamlessly) {
final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
- if (seamlessRotated != null) {
+ if (seamlessRotated != null && !forceUpdate) {
// We can't rotate (seamlessly or not) while waiting for the last seamless rotation
// to complete (that is, waiting for windows to redraw). It's tempting to check
// w.mSeamlessRotationCount but that could be incorrect in the case of
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f42f855e7ac5..9c253fb949e1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2372,6 +2372,12 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
IBinder freezeThisOneIfNeeded, int displayId) {
+ return updateOrientationFromAppTokens(currentConfig, freezeThisOneIfNeeded, displayId,
+ false /* forceUpdate */);
+ }
+
+ public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
+ IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "updateOrientationFromAppTokens()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
@@ -2381,7 +2387,7 @@ public class WindowManagerService extends IWindowManager.Stub
try {
synchronized(mWindowMap) {
config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded,
- displayId);
+ displayId, forceUpdate);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2391,13 +2397,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig,
- IBinder freezeThisOneIfNeeded, int displayId) {
+ IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) {
if (!mDisplayReady) {
return null;
}
Configuration config = null;
- if (updateOrientationFromAppTokensLocked(displayId)) {
+ if (updateOrientationFromAppTokensLocked(displayId, forceUpdate)) {
// If we changed the orientation but mOrientationChangeComplete is already true,
// we used seamless rotation, and we don't need to freeze the screen.
if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) {
@@ -2445,11 +2451,15 @@ public class WindowManagerService extends IWindowManager.Stub
* @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int)
*/
boolean updateOrientationFromAppTokensLocked(int displayId) {
+ return updateOrientationFromAppTokensLocked(displayId, false /* forceUpdate */);
+ }
+
+ boolean updateOrientationFromAppTokensLocked(int displayId, boolean forceUpdate) {
long ident = Binder.clearCallingIdentity();
try {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
final int req = dc.getOrientation();
- if (req != dc.getLastOrientation()) {
+ if (req != dc.getLastOrientation() || forceUpdate) {
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
@@ -2457,12 +2467,8 @@ public class WindowManagerService extends IWindowManager.Stub
if (dc.isDefaultDisplay) {
mPolicy.setCurrentOrientationLw(req);
}
- if (dc.updateRotationUnchecked()) {
- // changed
- return true;
- }
+ return dc.updateRotationUnchecked(forceUpdate);
}
-
return false;
} finally {
Binder.restoreCallingIdentity(ident);