diff options
| author | 2016-10-05 09:08:43 -0700 | |
|---|---|---|
| committer | 2016-10-05 16:57:47 -0700 | |
| commit | 02896ab71376aa3d9386c5e5abc51c97b69b10c5 (patch) | |
| tree | 249db5aa4553a3f289ff19005fd1478ae14761c4 | |
| parent | 4306608707ad24af2b9a7c5764412e429329eab3 (diff) | |
Fixed issue with screen rotation not working for landscape<->seascape
Problem as introduced in the refactor to change how configuration works
in activity manager in ag/1460784. With the new change we don't call back
into window manager to set new configuration if there are no changes.
The new change is correct, however window manager was relying on this to
unfreeze the display since the rotation changed.
We now have activity manager return if it updated the configuration to
window manager when the rotation changes do window manager can decide
if it needs to perform additional actions like unfreezing the display.
Bug: 31916697
Test: CTS and Manual testing.
CTS: cts-tradefed run commandAndExit cts-dev --module CtsServicesHostTestCases --test android.server.cts.ActivityManagerDockedStackTests
Manual: Launch an app that suports all orientations and rotate it from
landscape to seascape.
Change-Id: I36ddeff1ccc9f6089227147b117a865571b8571e
4 files changed, 82 insertions, 28 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index f798512092e4..d91472b6a1ba 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1229,8 +1229,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case UPDATE_CONFIGURATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Configuration config = Configuration.CREATOR.createFromParcel(data); - updateConfiguration(config); + final boolean updated = updateConfiguration(config); reply.writeNoException(); + reply.writeInt(updated ? 1 : 0); return true; } @@ -4593,7 +4594,7 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return res; } - public void updateConfiguration(Configuration values) throws RemoteException + public boolean updateConfiguration(Configuration values) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -4601,8 +4602,10 @@ class ActivityManagerProxy implements IActivityManager values.writeToParcel(data, 0); mRemote.transact(UPDATE_CONFIGURATION_TRANSACTION, data, reply, 0); reply.readException(); + boolean updated = reply.readInt() == 1; data.recycle(); reply.recycle(); + return updated; } public void setRequestedOrientation(IBinder token, int requestedOrientation) throws RemoteException { diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 096f0cb190e7..c9d3682405d1 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -276,8 +276,9 @@ public interface IActivityManager extends IInterface { * Updates global configuration and applies changes to the entire system. * @param values Update values for global configuration. * @throws RemoteException + * @return Returns true if the configuration was updated. */ - public void updateConfiguration(Configuration values) throws RemoteException; + public boolean updateConfiguration(Configuration values) throws RemoteException; public void setRequestedOrientation(IBinder token, int requestedOrientation) throws RemoteException; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c32cac8a1b37..9f2d44793f3f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1136,6 +1136,20 @@ public final class ActivityManagerService extends ActivityManagerNative */ private Configuration mTempGlobalConfig = new Configuration(); + private final UpdateConfigurationResult mTmpUpdateConfigurationResult = + new UpdateConfigurationResult(); + private static final class UpdateConfigurationResult { + // Configuration changes that were updated. + int changes; + // If the activity was relaunched to match the new configuration. + boolean activityRelaunched; + + void reset() { + changes = 0; + activityRelaunched = false; + } + } + boolean mSuppressResizeConfigChanges; /** @@ -18872,7 +18886,7 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void updateConfiguration(Configuration values) { + public boolean updateConfiguration(Configuration values) { enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()"); @@ -18887,11 +18901,18 @@ public final class ActivityManagerService extends ActivityManagerNative } final long origId = Binder.clearCallingIdentity(); - if (values != null) { - Settings.System.clearConfiguration(values); + + try { + if (values != null) { + Settings.System.clearConfiguration(values); + } + updateConfigurationLocked(values, null, false, false /* persistent */, + UserHandle.USER_NULL, false /* deferResume */, + mTmpUpdateConfigurationResult); + return mTmpUpdateConfigurationResult.changes != 0; + } finally { + Binder.restoreCallingIdentity(origId); } - updateConfigurationLocked(values, null, false); - Binder.restoreCallingIdentity(origId); } } @@ -18919,6 +18940,12 @@ public final class ActivityManagerService extends ActivityManagerNative // To cache the list of supported system locales private String[] mSupportedSystemLocales = null; + private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, + boolean initLocale, boolean persistent, int userId, boolean deferResume) { + return updateConfigurationLocked(values, starting, initLocale, persistent, userId, + deferResume, null /* result */); + } + /** * Do either or both things: (1) change the current configuration, and (2) * make sure the given activity is running with the (now) current @@ -18930,7 +18957,8 @@ public final class ActivityManagerService extends ActivityManagerNative * for that particular user */ private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, - boolean initLocale, boolean persistent, int userId, boolean deferResume) { + boolean initLocale, boolean persistent, int userId, boolean deferResume, + UpdateConfigurationResult result) { int changes = 0; boolean kept = true; @@ -18949,6 +18977,11 @@ public final class ActivityManagerService extends ActivityManagerNative mWindowManager.continueSurfaceLayout(); } } + + if (result != null) { + result.changes = changes; + result.activityRelaunched = !kept; + } return kept; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5970998247c1..33155cec6724 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -213,7 +213,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; @@ -222,12 +221,10 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; @@ -5441,25 +5438,30 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) { - if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked(" - + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")"); + private void updateRotationUnchecked(boolean alwaysSendConfiguration, + boolean forceRelayout) { + if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:" + + " alwaysSendConfiguration=" + alwaysSendConfiguration + + " forceRelayout=" + forceRelayout); long origId = Binder.clearCallingIdentity(); - boolean changed; - synchronized(mWindowMap) { - changed = updateRotationUncheckedLocked(false); - if (!changed || forceRelayout) { - getDefaultDisplayContentLocked().setLayoutNeeded(); - mWindowPlacerLocked.performSurfacePlacement(); + + try { + final boolean rotationChanged; + synchronized (mWindowMap) { + rotationChanged = updateRotationUncheckedLocked(false); + if (!rotationChanged || forceRelayout) { + getDefaultDisplayContentLocked().setLayoutNeeded(); + mWindowPlacerLocked.performSurfacePlacement(); + } } - } - if (changed || alwaysSendConfiguration) { - sendNewConfiguration(); + if (rotationChanged || alwaysSendConfiguration) { + sendNewConfiguration(); + } + } finally { + Binder.restoreCallingIdentity(origId); } - - Binder.restoreCallingIdentity(origId); } @@ -5470,7 +5472,7 @@ public class WindowManagerService extends IWindowManager.Stub * Returns true if the rotation has been changed. In this case YOU * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN. */ - public boolean updateRotationUncheckedLocked(boolean inTransaction) { + boolean updateRotationUncheckedLocked(boolean inTransaction) { if (mDeferredRotationPauseCount > 0) { // Rotation updates have been paused temporarily. Defer the update until // updates have been resumed. @@ -6121,10 +6123,25 @@ public class WindowManagerService extends IWindowManager.Stub /** * Instruct the Activity Manager to fetch new configurations, update global configuration * and broadcast changes to config-changed listeners if appropriate. + * NOTE: Can't be called with the window manager lock held since it call into activity manager. */ void sendNewConfiguration() { try { - mActivityManager.updateConfiguration(null); + final boolean configUpdated = mActivityManager.updateConfiguration(null); + if (!configUpdated) { + // 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 updateRotationUncheckedLocked. + synchronized (mWindowMap) { + if (mWaitingForConfig) { + mWaitingForConfig = false; + mLastFinishedFreezeSource = "config-unchanged"; + getDefaultDisplayContentLocked().setLayoutNeeded(); + mWindowPlacerLocked.performSurfacePlacement(); + } + } + } } catch (RemoteException e) { } } |