Skip to content

Commit 1fd6c33

Browse files
Dianne HackbornDave Burke
authored andcommitted
Fix issue #5312624: Lock screen very flickery
The key thing was to fix isVisibleOrBehindKeyguardLw() so that it wouldn't count a window as not visible if it was just currently in the process of drawing due to an orientation change. Also improve logic in deciding when to turn screen on to better ensure the screen is in a stable state, in particular treating screen off as a frozen screen and not allowing it to turn on until the update of the screen due to any config change is done. Change-Id: If82199f3773270b2d07f9c7de9da2dad8c7b28d7
1 parent 6ea4da9 commit 1fd6c33

File tree

5 files changed

+74
-42
lines changed

5 files changed

+74
-42
lines changed

core/java/android/view/WindowManagerPolicy.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,9 +784,14 @@ public interface ScreenOnListener {
784784
public void screenTurningOn(ScreenOnListener screenOnListener);
785785

786786
/**
787-
* Return whether the screen is currently on.
787+
* Return whether the screen is about to turn on or is currently on.
788788
*/
789-
public boolean isScreenOn();
789+
public boolean isScreenOnEarly();
790+
791+
/**
792+
* Return whether the screen is fully turned on.
793+
*/
794+
public boolean isScreenOnFully();
790795

791796
/**
792797
* Tell the policy that the lid switch has changed state.

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@
127127
import android.view.WindowManagerImpl;
128128
import android.view.WindowManagerPolicy;
129129
import android.view.KeyCharacterMap.FallbackAction;
130-
import android.view.WindowManagerPolicy.ScreenOnListener;
131130
import android.view.accessibility.AccessibilityEvent;
132131
import android.view.animation.Animation;
133132
import android.view.animation.AnimationUtils;
@@ -287,7 +286,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
287286
int mLidKeyboardAccessibility;
288287
int mLidNavigationAccessibility;
289288
int mLongPressOnPowerBehavior = -1;
290-
boolean mScreenOn = false;
289+
boolean mScreenOnEarly = false;
290+
boolean mScreenOnFully = false;
291291
boolean mOrientationSensorEnabled = false;
292292
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
293293
static final int DEFAULT_ACCELEROMETER_ROTATION = 0;
@@ -547,11 +547,11 @@ void updateOrientationListenerLp() {
547547
}
548548
//Could have been invoked due to screen turning on or off or
549549
//change of the currently visible window's orientation
550-
if (localLOGV) Log.v(TAG, "Screen status="+mScreenOn+
550+
if (localLOGV) Log.v(TAG, "Screen status="+mScreenOnEarly+
551551
", current orientation="+mCurrentAppOrientation+
552552
", SensorEnabled="+mOrientationSensorEnabled);
553553
boolean disable = true;
554-
if (mScreenOn) {
554+
if (mScreenOnEarly) {
555555
if (needSensorRunningLp()) {
556556
disable = false;
557557
//enable listener if not already enabled
@@ -2094,11 +2094,13 @@ public void beginAnimationLw(int displayWidth, int displayHeight) {
20942094
/** {@inheritDoc} */
20952095
public void animatingWindowLw(WindowState win,
20962096
WindowManager.LayoutParams attrs) {
2097+
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
2098+
+ win.isVisibleOrBehindKeyguardLw());
20972099
if (mTopFullscreenOpaqueWindowState == null &&
20982100
win.isVisibleOrBehindKeyguardLw()) {
20992101
if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
21002102
mForceStatusBar = true;
2101-
}
2103+
}
21022104
if (attrs.type >= FIRST_APPLICATION_WINDOW
21032105
&& attrs.type <= LAST_APPLICATION_WINDOW
21042106
&& attrs.x == 0 && attrs.y == 0
@@ -2137,10 +2139,10 @@ public int finishAnimationLw() {
21372139
: null;
21382140

21392141
if (mStatusBar != null) {
2140-
if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar
2142+
if (DEBUG_LAYOUT) Log.i(TAG, "force=" + mForceStatusBar
21412143
+ " top=" + mTopFullscreenOpaqueWindowState);
21422144
if (mForceStatusBar) {
2143-
if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
2145+
if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: forced");
21442146
if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
21452147
} else if (mTopFullscreenOpaqueWindowState != null) {
21462148
if (localLOGV) {
@@ -2168,11 +2170,11 @@ public int finishAnimationLw() {
21682170
}
21692171
}});
21702172
}
2171-
} else if (localLOGV) {
2173+
} else if (DEBUG_LAYOUT) {
21722174
Log.v(TAG, "Preventing status bar from hiding by policy");
21732175
}
21742176
} else {
2175-
if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
2177+
if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: top is not fullscreen");
21762178
if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
21772179
}
21782180
}
@@ -2809,7 +2811,8 @@ public void onReceive(Context context, Intent intent) {
28092811
public void screenTurnedOff(int why) {
28102812
EventLog.writeEvent(70000, 0);
28112813
synchronized (mLock) {
2812-
mScreenOn = false;
2814+
mScreenOnEarly = false;
2815+
mScreenOnFully = false;
28132816
}
28142817
mKeyguardMediator.onScreenTurnedOff(why);
28152818
synchronized (mLock) {
@@ -2831,27 +2834,38 @@ public void screenTurningOn(final ScreenOnListener screenOnListener) {
28312834
@Override public void sendResult(Bundle data) {
28322835
Slog.i(TAG, "Lock screen displayed!");
28332836
screenOnListener.onScreenOn();
2837+
synchronized (mLock) {
2838+
mScreenOnFully = true;
2839+
}
28342840
}
28352841
});
28362842
} catch (RemoteException e) {
28372843
}
28382844
} else {
28392845
Slog.i(TAG, "No lock screen!");
28402846
screenOnListener.onScreenOn();
2847+
synchronized (mLock) {
2848+
mScreenOnFully = true;
2849+
}
28412850
}
28422851
}
28432852
});
28442853
synchronized (mLock) {
2845-
mScreenOn = true;
2854+
mScreenOnEarly = true;
28462855
updateOrientationListenerLp();
28472856
updateLockScreenTimeout();
28482857
updateScreenSaverTimeoutLocked();
28492858
}
28502859
}
28512860

28522861
/** {@inheritDoc} */
2853-
public boolean isScreenOn() {
2854-
return mScreenOn;
2862+
public boolean isScreenOnEarly() {
2863+
return mScreenOnEarly;
2864+
}
2865+
2866+
/** {@inheritDoc} */
2867+
public boolean isScreenOnFully() {
2868+
return mScreenOnFully;
28552869
}
28562870

28572871
/** {@inheritDoc} */
@@ -3238,15 +3252,15 @@ private void updateScreenSaverTimeoutLocked() {
32383252

32393253
synchronized (mScreenSaverActivator) {
32403254
mHandler.removeCallbacks(mScreenSaverActivator);
3241-
if (mScreenSaverEnabled && mScreenOn && mScreenSaverTimeout > 0) {
3255+
if (mScreenSaverEnabled && mScreenOnEarly && mScreenSaverTimeout > 0) {
32423256
if (localLOGV)
32433257
Log.v(TAG, "scheduling screensaver for " + mScreenSaverTimeout + "ms from now");
32443258
mHandler.postDelayed(mScreenSaverActivator, mScreenSaverTimeout);
32453259
} else {
32463260
if (localLOGV) {
32473261
if (mScreenSaverTimeout == 0)
32483262
Log.v(TAG, "screen saver disabled by user");
3249-
else if (!mScreenOn)
3263+
else if (!mScreenOnEarly)
32503264
Log.v(TAG, "screen saver disabled while screen off");
32513265
else
32523266
Log.v(TAG, "screen saver disabled by wakelock");
@@ -3267,7 +3281,7 @@ public void run() {
32673281

32683282
private void updateLockScreenTimeout() {
32693283
synchronized (mScreenLockTimeout) {
3270-
boolean enable = (mAllowLockscreenWhenOn && mScreenOn && mKeyguardMediator.isSecure());
3284+
boolean enable = (mAllowLockscreenWhenOn && mScreenOnEarly && mKeyguardMediator.isSecure());
32713285
if (mLockScreenTimerActive != enable) {
32723286
if (enable) {
32733287
if (localLOGV) Log.v(TAG, "setting lockscreen timer");
@@ -3476,7 +3490,7 @@ public void screenOnStoppedLw() {
34763490

34773491
public boolean allowKeyRepeat() {
34783492
// disable key repeat when screen is off
3479-
return mScreenOn;
3493+
return mScreenOnEarly;
34803494
}
34813495

34823496
private void updateSystemUiVisibility() {
@@ -3532,7 +3546,8 @@ public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args
35323546
pw.print(mLidKeyboardAccessibility);
35333547
pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
35343548
pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
3535-
pw.print(prefix); pw.print("mScreenOn="); pw.print(mScreenOn);
3549+
pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
3550+
pw.print(" mScreenOnFully="); pw.print(mScreenOnFully);
35363551
pw.print(" mOrientationSensorEnabled="); pw.print(mOrientationSensorEnabled);
35373552
pw.print(" mHasSoftInput="); pw.println(mHasSoftInput);
35383553
pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft);

services/java/com/android/server/wm/AppWindowToken.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ void showAllWindowsLocked() {
194194

195195
// This must be called while inside a transaction.
196196
boolean stepAnimationLocked(long currentTime, int dw, int dh) {
197-
if (!service.mDisplayFrozen && service.mPolicy.isScreenOn()) {
197+
if (!service.mDisplayFrozen && service.mPolicy.isScreenOnFully()) {
198198
// We will run animations as long as the display isn't frozen.
199199

200200
if (animation == WindowManagerService.sDummyAnimation) {

services/java/com/android/server/wm/WindowManagerService.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,8 @@ public void removeWindowLocked(Session session, WindowState win) {
21992199
// to hold off on removing the window until the animation is done.
22002200
// If the display is frozen, just remove immediately, since the
22012201
// animation wouldn't be seen.
2202-
if (win.mSurface != null && !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
2202+
if (win.mSurface != null && !mDisplayFrozen && mDisplayEnabled
2203+
&& mPolicy.isScreenOnFully()) {
22032204
// If we are not currently running the exit animation, we
22042205
// need to see about starting one.
22052206
if (wasVisible=win.isWinVisibleLw()) {
@@ -2577,7 +2578,7 @@ public int relayoutWindow(Session session, IWindow client,
25772578
if (displayed) {
25782579
if (win.mSurface != null && !win.mDrawPending
25792580
&& !win.mCommitDrawPending && !mDisplayFrozen
2580-
&& mDisplayEnabled && mPolicy.isScreenOn()) {
2581+
&& mDisplayEnabled && mPolicy.isScreenOnFully()) {
25812582
applyEnterAnimationLocked(win);
25822583
}
25832584
if ((win.mAttrs.flags
@@ -2870,7 +2871,7 @@ boolean applyAnimationLocked(WindowState win,
28702871
// frozen, there is no reason to animate and it can cause strange
28712872
// artifacts when we unfreeze the display if some different animation
28722873
// is running.
2873-
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
2874+
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
28742875
int anim = mPolicy.selectAnimationLw(win, transit);
28752876
int attr = -1;
28762877
Animation a = null;
@@ -2956,7 +2957,7 @@ private boolean applyAnimationLocked(AppWindowToken wtoken,
29562957
// frozen, there is no reason to animate and it can cause strange
29572958
// artifacts when we unfreeze the display if some different animation
29582959
// is running.
2959-
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
2960+
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
29602961
Animation a;
29612962
if (mNextAppTransitionPackage != null) {
29622963
a = loadAnimation(mNextAppTransitionPackage, enter ?
@@ -3522,7 +3523,7 @@ public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
35223523
if (DEBUG_APP_TRANSITIONS) Slog.v(
35233524
TAG, "Prepare app transition: transit=" + transit
35243525
+ " mNextAppTransition=" + mNextAppTransition);
3525-
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
3526+
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
35263527
if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
35273528
|| mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
35283529
mNextAppTransition = transit;
@@ -3606,7 +3607,7 @@ public void setAppStartingWindow(IBinder token, String pkg,
36063607
// If the display is frozen, we won't do anything until the
36073608
// actual window is displayed so there is no reason to put in
36083609
// the starting window.
3609-
if (mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOn()) {
3610+
if (mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOnFully()) {
36103611
return;
36113612
}
36123613

@@ -3888,7 +3889,7 @@ public void setAppVisibility(IBinder token, boolean visible) {
38883889

38893890
// If we are preparing an app transition, then delay changing
38903891
// the visibility of this token until we execute that transition.
3891-
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()
3892+
if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()
38923893
&& mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
38933894
// Already in requested state, don't do anything more.
38943895
if (wtoken.hiddenRequested != visible) {
@@ -4016,7 +4017,7 @@ public void startAppFreezingScreen(IBinder token, int configChanges) {
40164017
}
40174018

40184019
synchronized(mWindowMap) {
4019-
if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
4020+
if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOnFully()) {
40204021
if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
40214022
return;
40224023
}
@@ -8137,10 +8138,10 @@ private final void performLayoutAndPlaceSurfacesLockedInner(
81378138

81388139
w.mLastContentInsets.set(w.mContentInsets);
81398140
w.mLastVisibleInsets.set(w.mVisibleInsets);
8140-
// If the screen is currently frozen, then keep
8141-
// it frozen until this window draws at its new
8141+
// If the screen is currently frozen or off, then keep
8142+
// it frozen/off until this window draws at its new
81428143
// orientation.
8143-
if (mDisplayFrozen) {
8144+
if (mDisplayFrozen || !mPolicy.isScreenOnFully()) {
81448145
if (DEBUG_ORIENTATION) Slog.v(TAG,
81458146
"Resizing while display frozen: " + w);
81468147
w.mOrientationChanging = true;
@@ -8408,7 +8409,7 @@ private final void performLayoutAndPlaceSurfacesLockedInner(
84088409

84098410
if (mDimAnimator != null && mDimAnimator.mDimShown) {
84108411
animating |= mDimAnimator.updateSurface(dimming, currentTime,
8411-
mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOn());
8412+
mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOnFully());
84128413
}
84138414

84148415
if (!blurring && mBlurShown) {
@@ -8604,10 +8605,14 @@ private final void performLayoutAndPlaceSurfacesLockedInner(
86048605
WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
86058606
if (changed) {
86068607
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
8608+
} else {
8609+
updateRotation = false;
86078610
}
86088611
}
86098612

8610-
checkDrawnWindowsLocked();
8613+
if (orientationChangeComplete && !needRelayout && !updateRotation) {
8614+
checkDrawnWindowsLocked();
8615+
}
86118616

86128617
// Check to see if we are now in a state where the screen should
86138618
// be enabled, because the window obscured flags have changed.
@@ -8925,7 +8930,7 @@ private void startFreezingDisplayLocked(boolean inTransaction) {
89258930
return;
89268931
}
89278932

8928-
if (mDisplay == null || !mPolicy.isScreenOn()) {
8933+
if (mDisplay == null || !mPolicy.isScreenOnFully()) {
89298934
// No need to freeze the screen before the system is ready or if
89308935
// the screen is off.
89318936
return;

services/java/com/android/server/wm/WindowState.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ boolean performShowLocked() {
870870
// This must be called while inside a transaction. Returns true if
871871
// there is more animation to run.
872872
boolean stepAnimationLocked(long currentTime, int dw, int dh) {
873-
if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOn()) {
873+
if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
874874
// We will run animations as long as the display isn't frozen.
875875

876876
if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
@@ -1204,11 +1204,18 @@ public boolean isVisibleLw() {
12041204
* mPolicyVisibility. Ungh.
12051205
*/
12061206
public boolean isVisibleOrBehindKeyguardLw() {
1207+
if (mRootToken.waitingToShow &&
1208+
mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
1209+
return false;
1210+
}
12071211
final AppWindowToken atoken = mAppToken;
1208-
return mSurface != null && !mAttachedHidden
1212+
final boolean animating = atoken != null
1213+
? (atoken.animation != null) : false;
1214+
return mSurface != null && !mDestroying && !mExiting
12091215
&& (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
1210-
&& !mDrawPending && !mCommitDrawPending
1211-
&& !mExiting && !mDestroying;
1216+
&& ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1217+
&& !mRootToken.hidden)
1218+
|| mAnimation != null || animating);
12121219
}
12131220

12141221
/**
@@ -1351,7 +1358,7 @@ boolean shouldAnimateMove() {
13511358
&& (mFrame.top != mLastFrame.top
13521359
|| mFrame.left != mLastFrame.left)
13531360
&& (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
1354-
&& mService.mPolicy.isScreenOn();
1361+
&& mService.mPolicy.isScreenOnFully();
13551362
}
13561363

13571364
boolean isFullscreen(int screenWidth, int screenHeight) {
@@ -1436,7 +1443,7 @@ boolean showLw(boolean doAnimation, boolean requestAnim) {
14361443
if (doAnimation) {
14371444
if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
14381445
+ mPolicyVisibility + " mAnimation=" + mAnimation);
1439-
if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
1446+
if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOnFully()) {
14401447
doAnimation = false;
14411448
} else if (mPolicyVisibility && mAnimation == null) {
14421449
// Check for the case where we are currently visible and
@@ -1462,7 +1469,7 @@ public boolean hideLw(boolean doAnimation) {
14621469

14631470
boolean hideLw(boolean doAnimation, boolean requestAnim) {
14641471
if (doAnimation) {
1465-
if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
1472+
if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOnFully()) {
14661473
doAnimation = false;
14671474
}
14681475
}

0 commit comments

Comments
 (0)