From c6467172e568dcd5a55b9c0470ef4587e59831e9 Mon Sep 17 00:00:00 2001 From: Ivan Podogov Date: Fri, 26 May 2017 17:42:15 +0100 Subject: [PATCH] Fix setRequestedOrientation() freeze on Android Wear. In ag/1460784 and ag/1551198, logic of ActivityManagerService.updateConfigurationLocked (now updateDisplayOverrideConfigurationLocked) was changed a bit: before those CL's, with (changes == 0) we were still calling mWindowManager.setNewConfiguration(mGlobalConfiguration) (which is now mWindowManager.setNewDisplayOverrideConfiguration). Now, when there was a call to Activity.setRequestedOrientation, the window becomes frozen and waiting for configuration, which is never sent since there are no changes detected (which we don't know in advance when freezing the window). This is important for watches, since they have "square" screens, and resources configuration for them doesn't change after requesting landscape orientation, i.e. display rotates 90 degrees, yet the layout stays portrait. As a result, device becomes frozen. This CL only moves mWindowManager.setNewDisplayOverrideConfiguration call outside of the (changes == 0) check to restore the old logic. Bug: 37684680 Test: go/wm-smoke (on Pixel), manual (on Wear) Change-Id: Idf1f5989173494d51437b9a66296b4cac82d15c2 --- .../server/am/ActivityManagerService.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 68c92a865f701..ba16409d7b891 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -20180,6 +20180,11 @@ public class ActivityManagerService extends IActivityManager.Stub mTempConfig.setTo(getGlobalConfiguration()); final int changes = mTempConfig.updateFrom(values); if (changes == 0) { + // Since calling to Activity.setRequestedOrientation leads to freezing the window with + // setting WindowManagerService.mWaitingForConfig to true, it is important that we call + // performDisplayOverrideConfigUpdate in order to send the new display configuration + // (even if there are no actual changes) to unfreeze the window. + performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); return 0; } @@ -20368,20 +20373,19 @@ public class ActivityManagerService extends IActivityManager.Stub int displayId) { mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); final int changes = mTempConfig.updateFrom(values); - if (changes == 0) { - return 0; - } + if (changes != 0) { + Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + + mTempConfig + " for displayId=" + displayId); + mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); - Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig - + " for displayId=" + displayId); - mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); + final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; + if (isDensityChange && displayId == DEFAULT_DISPLAY) { + // Reset the unsupported display size dialog. + mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); - final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; - if (isDensityChange && displayId == DEFAULT_DISPLAY) { - // Reset the unsupported display size dialog. - mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); - - killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + killAllBackgroundProcessesExcept(N, + ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + } } // Update the configuration with WM first and check if any of the stacks need to be resized