Skip to content

Commit 6ea4da9

Browse files
Dianne HackbornDave Burke
authored andcommitted
Fix issue #5242779: Device not responding to touch on unlock screen
Rework how we decide when it is okay to turn on the screen by having the policy call back to the power manager when it knows the lock screen has been drawn. Change-Id: Ie8f3f72111dcf7f168723e6dce24e0343b4afe5d
1 parent d908b40 commit 6ea4da9

File tree

7 files changed

+187
-106
lines changed

7 files changed

+187
-106
lines changed

core/java/android/view/IWindowManager.aidl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import android.content.res.CompatibilityInfo;
2323
import android.content.res.Configuration;
2424
import android.graphics.Bitmap;
2525
import android.graphics.Point;
26+
import android.os.IRemoteCallback;
2627
import android.view.IApplicationToken;
2728
import android.view.IOnKeyguardExitResult;
2829
import android.view.IRotationWatcher;
@@ -220,7 +221,7 @@ interface IWindowManager
220221
void setPointerSpeed(int speed);
221222

222223
/**
223-
* Block until all windows the window manager knows about have been drawn.
224+
* Block until the given window has been drawn to the screen.
224225
*/
225-
void waitForAllDrawn();
226+
void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
226227
}

core/java/android/view/WindowManagerPolicy.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,10 +772,16 @@ public void animatingWindowLw(WindowState win,
772772
*/
773773
public void screenTurnedOff(int why);
774774

775+
public interface ScreenOnListener {
776+
void onScreenOn();
777+
};
778+
775779
/**
776-
* Called after the screen turns on.
780+
* Called when the power manager would like to turn the screen on.
781+
* Must call back on the listener to tell it when the higher-level system
782+
* is ready for the screen to go on (i.e. the lock screen is shown).
777783
*/
778-
public void screenTurnedOn();
784+
public void screenTurningOn(ScreenOnListener screenOnListener);
779785

780786
/**
781787
* Return whether the screen is currently on.

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import android.content.res.Resources;
2525
import android.graphics.PixelFormat;
2626
import android.graphics.Canvas;
27+
import android.os.IBinder;
2728
import android.os.SystemProperties;
2829
import android.util.Log;
2930
import android.view.View;
@@ -59,6 +60,10 @@ public class KeyguardViewManager implements KeyguardWindowController {
5960

6061
private boolean mScreenOn = false;
6162

63+
public interface ShowListener {
64+
void onShown(IBinder windowToken);
65+
};
66+
6267
/**
6368
* @param context Used to create views.
6469
* @param viewManager Keyguard will be attached to this.
@@ -206,14 +211,35 @@ public synchronized void onScreenTurnedOff() {
206211
}
207212
}
208213

209-
public synchronized void onScreenTurnedOn() {
214+
public synchronized void onScreenTurnedOn(
215+
final KeyguardViewManager.ShowListener showListener) {
210216
if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
211217
mScreenOn = true;
212218
if (mKeyguardView != null) {
213219
mKeyguardView.onScreenTurnedOn();
214220

215221
// When screen is turned on, need to bind to FaceLock service if we are using FaceLock
216222
mKeyguardView.bindToFaceLock();
223+
224+
// Caller should wait for this window to be shown before turning
225+
// on the screen.
226+
if (mKeyguardHost.getVisibility() == View.VISIBLE) {
227+
// Keyguard may be in the process of being shown, but not yet
228+
// updated with the window manager... give it a chance to do so.
229+
mKeyguardHost.post(new Runnable() {
230+
@Override public void run() {
231+
if (mKeyguardHost.getVisibility() == View.VISIBLE) {
232+
showListener.onShown(mKeyguardHost.getWindowToken());
233+
} else {
234+
showListener.onShown(null);
235+
}
236+
}
237+
});
238+
} else {
239+
showListener.onShown(null);
240+
}
241+
} else {
242+
showListener.onShown(null);
217243
}
218244
}
219245

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

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
116116
private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
117117
private static final int SET_HIDDEN = 12;
118118
private static final int KEYGUARD_TIMEOUT = 13;
119-
private static final int REPORT_SHOW_DONE = 14;
120119

121120
/**
122121
* The default amount of time we stay awake (used for all key input)
@@ -239,8 +238,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
239238

240239
private boolean mScreenOn = false;
241240

242-
private boolean mShowPending = false;
243-
244241
// last known state of the cellular connection
245242
private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
246243

@@ -383,32 +380,20 @@ public void onScreenTurnedOff(int why) {
383380
} else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
384381
// Do not enable the keyguard if the prox sensor forced the screen off.
385382
} else {
386-
if (!doKeyguardLocked() && why == WindowManagerPolicy.OFF_BECAUSE_OF_USER) {
387-
// The user has explicitly turned off the screen, causing it
388-
// to lock. We want to block here until the keyguard window
389-
// has shown, so the power manager won't complete the screen
390-
// off flow until that point, so we know it won't turn *on*
391-
// the screen until this is done.
392-
while (mShowPending) {
393-
try {
394-
wait();
395-
} catch (InterruptedException e) {
396-
}
397-
}
398-
}
383+
doKeyguardLocked();
399384
}
400385
}
401386
}
402387

403388
/**
404389
* Let's us know the screen was turned on.
405390
*/
406-
public void onScreenTurnedOn() {
391+
public void onScreenTurnedOn(KeyguardViewManager.ShowListener showListener) {
407392
synchronized (this) {
408393
mScreenOn = true;
409394
mDelayedShowingSequence++;
410395
if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
411-
notifyScreenOnLocked();
396+
notifyScreenOnLocked(showListener);
412397
}
413398
}
414399

@@ -573,7 +558,7 @@ public boolean doLidChangeTq(boolean isLidOpen) {
573558
* work that will happen is done; returns false if the caller can wait for
574559
* the keyguard to be shown.
575560
*/
576-
private boolean doKeyguardLocked() {
561+
private void doKeyguardLocked() {
577562
// if another app is disabling us, don't show
578563
if (!mExternallyEnabled) {
579564
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
@@ -587,13 +572,13 @@ private boolean doKeyguardLocked() {
587572
// ends (see the broadcast receiver below)
588573
// TODO: clean this up when we have better support at the window manager level
589574
// for apps that wish to be on top of the keyguard
590-
return true;
575+
return;
591576
}
592577

593578
// if the keyguard is already showing, don't bother
594579
if (mKeyguardViewManager.isShowing()) {
595580
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
596-
return true;
581+
return;
597582
}
598583

599584
// if the setup wizard hasn't run yet, don't show
@@ -609,18 +594,16 @@ private boolean doKeyguardLocked() {
609594
if (!lockedOrMissing && !provisioned) {
610595
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
611596
+ " and the sim is not locked or missing");
612-
return true;
597+
return;
613598
}
614599

615600
if (mLockPatternUtils.isLockScreenDisabled()) {
616601
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
617-
return true;
602+
return;
618603
}
619604

620605
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
621-
mShowPending = true;
622606
showLocked();
623-
return false;
624607
}
625608

626609
/**
@@ -658,9 +641,10 @@ private void notifyScreenOffLocked() {
658641
* @see #onScreenTurnedOn()
659642
* @see #handleNotifyScreenOn
660643
*/
661-
private void notifyScreenOnLocked() {
644+
private void notifyScreenOnLocked(KeyguardViewManager.ShowListener showListener) {
662645
if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
663-
mHandler.sendEmptyMessage(NOTIFY_SCREEN_ON);
646+
Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, showListener);
647+
mHandler.sendMessage(msg);
664648
}
665649

666650
/**
@@ -974,7 +958,7 @@ public void handleMessage(Message msg) {
974958
handleNotifyScreenOff();
975959
return;
976960
case NOTIFY_SCREEN_ON:
977-
handleNotifyScreenOn();
961+
handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);
978962
return;
979963
case WAKE_WHEN_READY:
980964
handleWakeWhenReady(msg.arg1);
@@ -996,12 +980,6 @@ public void handleMessage(Message msg) {
996980
doKeyguardLocked();
997981
}
998982
break;
999-
case REPORT_SHOW_DONE:
1000-
synchronized (KeyguardViewMediator.this) {
1001-
mShowPending = false;
1002-
KeyguardViewMediator.this.notifyAll();
1003-
}
1004-
break;
1005983
}
1006984
}
1007985
};
@@ -1113,12 +1091,6 @@ private void handleShow() {
11131091
playSounds(true);
11141092

11151093
mShowKeyguardWakeLock.release();
1116-
1117-
// We won't say the show is done yet because the view hierarchy
1118-
// still needs to do the traversal. Posting this message allows
1119-
// us to hold off until that is done.
1120-
Message msg = mHandler.obtainMessage(REPORT_SHOW_DONE);
1121-
mHandler.sendMessage(msg);
11221094
}
11231095
}
11241096

@@ -1284,10 +1256,10 @@ private void handleNotifyScreenOff() {
12841256
* Handle message sent by {@link #notifyScreenOnLocked()}
12851257
* @see #NOTIFY_SCREEN_ON
12861258
*/
1287-
private void handleNotifyScreenOn() {
1259+
private void handleNotifyScreenOn(KeyguardViewManager.ShowListener showListener) {
12881260
synchronized (KeyguardViewMediator.this) {
12891261
if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
1290-
mKeyguardViewManager.onScreenTurnedOn();
1262+
mKeyguardViewManager.onScreenTurnedOn(showListener);
12911263
}
12921264
}
12931265

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

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@
4040
import android.graphics.Rect;
4141
import android.graphics.RectF;
4242
import android.os.Binder;
43+
import android.os.Bundle;
4344
import android.os.Handler;
4445
import android.os.IBinder;
46+
import android.os.IRemoteCallback;
4547
import android.os.LocalPowerManager;
4648
import android.os.Message;
4749
import android.os.Messenger;
@@ -125,6 +127,7 @@
125127
import android.view.WindowManagerImpl;
126128
import android.view.WindowManagerPolicy;
127129
import android.view.KeyCharacterMap.FallbackAction;
130+
import android.view.WindowManagerPolicy.ScreenOnListener;
128131
import android.view.accessibility.AccessibilityEvent;
129132
import android.view.animation.Animation;
130133
import android.view.animation.AnimationUtils;
@@ -2814,23 +2817,30 @@ public void screenTurnedOff(int why) {
28142817
updateLockScreenTimeout();
28152818
updateScreenSaverTimeoutLocked();
28162819
}
2817-
try {
2818-
mWindowManager.waitForAllDrawn();
2819-
} catch (RemoteException e) {
2820-
}
2821-
// Wait for one frame to give surface flinger time to do its
2822-
// compositing. Yes this is a hack, but I am really not up right now for
2823-
// implementing some mechanism to block until SF is done. :p
2824-
try {
2825-
Thread.sleep(20);
2826-
} catch (InterruptedException e) {
2827-
}
28282820
}
28292821

28302822
/** {@inheritDoc} */
2831-
public void screenTurnedOn() {
2823+
public void screenTurningOn(final ScreenOnListener screenOnListener) {
28322824
EventLog.writeEvent(70000, 1);
2833-
mKeyguardMediator.onScreenTurnedOn();
2825+
//Slog.i(TAG, "Screen turning on...");
2826+
mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
2827+
@Override public void onShown(IBinder windowToken) {
2828+
if (windowToken != null) {
2829+
try {
2830+
mWindowManager.waitForWindowDrawn(windowToken, new IRemoteCallback.Stub() {
2831+
@Override public void sendResult(Bundle data) {
2832+
Slog.i(TAG, "Lock screen displayed!");
2833+
screenOnListener.onScreenOn();
2834+
}
2835+
});
2836+
} catch (RemoteException e) {
2837+
}
2838+
} else {
2839+
Slog.i(TAG, "No lock screen!");
2840+
screenOnListener.onScreenOn();
2841+
}
2842+
}
2843+
});
28342844
synchronized (mLock) {
28352845
mScreenOn = true;
28362846
updateOrientationListenerLp();

0 commit comments

Comments
 (0)