diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java index bf0e10f993ad7..55aed529037df 100644 --- a/core/java/android/view/WindowManagerInternal.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -225,6 +225,9 @@ public abstract class WindowManagerInternal { */ public abstract boolean isKeyguardLocked(); + /** @return {@code true} if the keyguard is going away. */ + public abstract boolean isKeyguardGoingAway(); + /** * Gets the frame of a window given its token. * diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java index 144eb11cbf854..2e0ec0b361e2b 100644 --- a/services/core/java/com/android/server/am/KeyguardController.java +++ b/services/core/java/com/android/server/am/KeyguardController.java @@ -97,7 +97,7 @@ class KeyguardController { mKeyguardShowing = showing; dismissDockedStackIfNeeded(); if (showing) { - mKeyguardGoingAway = false; + setKeyguardGoingAway(false); mDismissalRequested = false; } mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); @@ -114,7 +114,7 @@ class KeyguardController { if (mKeyguardShowing) { mWindowManager.deferSurfaceLayout(); try { - mKeyguardGoingAway = true; + setKeyguardGoingAway(true); mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */, convertTransitFlags(flags), false /* forceOverride */); @@ -139,6 +139,11 @@ class KeyguardController { mWindowManager.dismissKeyguard(callback); } + private void setKeyguardGoingAway(boolean keyguardGoingAway) { + mKeyguardGoingAway = keyguardGoingAway; + mWindowManager.setKeyguardGoingAway(keyguardGoingAway); + } + private void failCallback(IKeyguardDismissCallback callback) { try { callback.onDismissError(); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 908e51711b113..e3bc91971b06e 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -60,7 +60,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_ST import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT; @@ -1128,16 +1127,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); + final boolean keyguardGoingAway = mWindowManagerInternal.isKeyguardGoingAway(); + boolean disable = true; // Note: We postpone the rotating of the screen until the keyguard as well as the - // window manager have reported a draw complete. - if (mScreenOnEarly && mAwake && - mKeyguardDrawComplete && mWindowManagerDrawComplete) { + // window manager have reported a draw complete or the keyguard is going away in dismiss + // mode. + if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete) + || keyguardGoingAway)) { if (needSensorRunningLp()) { disable = false; //enable listener if not already enabled if (!mOrientationSensorEnabled) { - mOrientationListener.enable(); + // Don't clear the current sensor orientation if the keyguard is going away in + // dismiss mode. This allows window manager to use the last sensor reading to + // determine the orientation vs. falling back to the last known orientation if + // the sensor reading was cleared which can cause it to relaunch the app that + // will show in the wrong orientation first before correcting leading to app + // launch delays. + mOrientationListener.enable(!keyguardGoingAway /* clearCurrentRotation */); if(localLOGV) Slog.v(TAG, "Enabling listeners"); mOrientationSensorEnabled = true; } diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java index 8ef0acbd38080..64f64c0d45d61 100644 --- a/services/core/java/com/android/server/policy/WindowOrientationListener.java +++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java @@ -109,24 +109,37 @@ public abstract class WindowOrientationListener { * {@link #onProposedRotationChanged(int)} when the device orientation changes. */ public void enable() { + enable(true /* clearCurrentRotation */); + } + + /** + * Enables the WindowOrientationListener so it will monitor the sensor and call + * {@link #onProposedRotationChanged(int)} when the device orientation changes. + * + * @param clearCurrentRotation True if the current proposed sensor rotation should be cleared as + * part of the reset. + */ + public void enable(boolean clearCurrentRotation) { synchronized (mLock) { if (mSensor == null) { Slog.w(TAG, "Cannot detect sensors. Not enabled"); return; } - if (mEnabled == false) { - if (LOG) { - Slog.d(TAG, "WindowOrientationListener enabled"); - } - mOrientationJudge.resetLocked(); - if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) { - mSensorManager.registerListener( - mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler); - } else { - mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler); - } - mEnabled = true; + if (mEnabled) { + return; } + if (LOG) { + Slog.d(TAG, "WindowOrientationListener enabled clearCurrentRotation=" + + clearCurrentRotation); + } + mOrientationJudge.resetLocked(clearCurrentRotation); + if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) { + mSensorManager.registerListener( + mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler); + } else { + mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler); + } + mEnabled = true; } } @@ -278,8 +291,11 @@ public abstract class WindowOrientationListener { * Resets the state of the judge. * * Should only be called when holding WindowOrientationListener lock. + * + * @param clearCurrentRotation True if the current proposed sensor rotation should be + * cleared as part of the reset. */ - public abstract void resetLocked(); + public abstract void resetLocked(boolean clearCurrentRotation); /** * Dumps internal state of the orientation judge. @@ -602,7 +618,7 @@ public abstract class WindowOrientationListener { if (LOG) { Slog.v(TAG, "Resetting orientation listener."); } - resetLocked(); + resetLocked(true /* clearCurrentRotation */); skipSample = true; } else { final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS + timeDeltaMS); @@ -778,9 +794,11 @@ public abstract class WindowOrientationListener { } @Override - public void resetLocked() { + public void resetLocked(boolean clearCurrentRotation) { mLastFilteredTimestampNanos = Long.MIN_VALUE; - mProposedRotation = -1; + if (clearCurrentRotation) { + mProposedRotation = -1; + } mFlatTimestampNanos = Long.MIN_VALUE; mFlat = false; mSwingTimestampNanos = Long.MIN_VALUE; @@ -1015,9 +1033,11 @@ public abstract class WindowOrientationListener { } @Override - public void resetLocked() { - mProposedRotation = -1; - mDesiredRotation = -1; + public void resetLocked(boolean clearCurrentRotation) { + if (clearCurrentRotation) { + mProposedRotation = -1; + mDesiredRotation = -1; + } mTouching = false; mTouchEndedTimestampNanos = Long.MIN_VALUE; unscheduleRotationEvaluationLocked(); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 221e7957ef352..b5476d7e056b4 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3492,10 +3492,15 @@ class DisplayContent extends WindowContainer implements WindowManagerP pw.print(prefix); pw.print("mOrientationChanging="); pw.print(mOrientationChanging); pw.print(" mAppFreezing="); pw.print(mAppFreezing); - pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); + pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen); pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged); } if (mLastFreezeDuration != 0) {