Fix "incall in landscape sometimes" bug #2523942
The problem turns out to have been a deep weirdness in the way that keyguard and incall interact. Incall gets relaunched when the keyboard is opened/closed, which transiently exposes keyguard with its nosensor orientation demands, and that plus the long keyguard-hide animation was leaving incall in a bad state from which the window manager didn't try to recover. We now disregard animating-towards-hidden windows [i.e. keyguard] when running through the app tokens to determine what orientation should be, and do not do configuration calculations at all while the display is frozen. There can still be a transient state in which incall is drawn in landscape, but things proceed from there to relaunch it back into the proper portrait orientation, and it ends up in the right state in the end. Change-Id: I0d74ee19064b6d7f65600976f1b5b16b7ec36f31
This commit is contained in:
@ -367,6 +367,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
boolean mSafeMode;
|
||||
boolean mDisplayEnabled = false;
|
||||
boolean mSystemBooted = false;
|
||||
int mInitialDisplayWidth = 0;
|
||||
int mInitialDisplayHeight = 0;
|
||||
int mRotation = 0;
|
||||
int mRequestedRotation = 0;
|
||||
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
@ -1842,6 +1844,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (mDisplay == null) {
|
||||
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
mDisplay = wm.getDefaultDisplay();
|
||||
mInitialDisplayWidth = mDisplay.getWidth();
|
||||
mInitialDisplayHeight = mDisplay.getHeight();
|
||||
mQueue.setDisplay(mDisplay);
|
||||
reportNewConfig = true;
|
||||
}
|
||||
@ -3025,7 +3029,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
// app window. No point in continuing further.
|
||||
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
}
|
||||
if (!wtoken.isVisibleLw()) {
|
||||
if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
|
||||
continue;
|
||||
}
|
||||
int req = wtoken.mAttrs.screenOrientation;
|
||||
@ -3154,6 +3158,15 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
* android.os.IBinder)
|
||||
*/
|
||||
boolean updateOrientationFromAppTokensLocked() {
|
||||
if (mDisplayFrozen) {
|
||||
// If the display is frozen, some activities may be in the middle
|
||||
// of restarting, and thus have removed their old window. If the
|
||||
// window has the flag to hide the lock screen, then the lock screen
|
||||
// can re-appear and inflict its own orientation on us. Keep the
|
||||
// orientation stable until this all settles down.
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@ -4843,8 +4856,13 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return false;
|
||||
}
|
||||
mQueue.getInputConfiguration(config);
|
||||
final int dw = mDisplay.getWidth();
|
||||
final int dh = mDisplay.getHeight();
|
||||
|
||||
// Use the effective "visual" dimensions based on current rotation
|
||||
final boolean rotated = (mRotation == Surface.ROTATION_90
|
||||
|| mRotation == Surface.ROTATION_270);
|
||||
final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
|
||||
final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
|
||||
|
||||
int orientation = Configuration.ORIENTATION_SQUARE;
|
||||
if (dw < dh) {
|
||||
orientation = Configuration.ORIENTATION_PORTRAIT;
|
||||
@ -10998,6 +11016,14 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mKeyWaiter.notifyAll();
|
||||
}
|
||||
|
||||
// While the display is frozen we don't re-compute the orientation
|
||||
// to avoid inconsistent states. However, something interesting
|
||||
// could have actually changed during that time so re-evaluate it
|
||||
// now to catch that.
|
||||
if (updateOrientationFromAppTokensLocked()) {
|
||||
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
|
||||
}
|
||||
|
||||
// A little kludge: a lot could have happened while the
|
||||
// display was frozen, so now that we are coming back we
|
||||
// do a gc so that any remote references the system
|
||||
|
Reference in New Issue
Block a user