Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ea4da95 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Dave Burke
Browse files

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
parent d908b40d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.IRemoteCallback;
import android.view.IApplicationToken;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
@@ -220,7 +221,7 @@ interface IWindowManager
    void setPointerSpeed(int speed);

    /**
     * Block until all windows the window manager knows about have been drawn.
     * Block until the given window has been drawn to the screen.
     */
    void waitForAllDrawn();
    void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
}
+8 −2
Original line number Diff line number Diff line
@@ -772,10 +772,16 @@ public interface WindowManagerPolicy {
     */
    public void screenTurnedOff(int why);

    public interface ScreenOnListener {
        void onScreenOn();
    };

    /**
     * Called after the screen turns on.
     * Called when the power manager would like to turn the screen on.
     * Must call back on the listener to tell it when the higher-level system
     * is ready for the screen to go on (i.e. the lock screen is shown).
     */
    public void screenTurnedOn();
    public void screenTurningOn(ScreenOnListener screenOnListener);

    /**
     * Return whether the screen is currently on.
+27 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Canvas;
import android.os.IBinder;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
@@ -59,6 +60,10 @@ public class KeyguardViewManager implements KeyguardWindowController {

    private boolean mScreenOn = false;

    public interface ShowListener {
        void onShown(IBinder windowToken);
    };

    /**
     * @param context Used to create views.
     * @param viewManager Keyguard will be attached to this.
@@ -206,7 +211,8 @@ public class KeyguardViewManager implements KeyguardWindowController {
        }
    }

    public synchronized void onScreenTurnedOn() {
    public synchronized void onScreenTurnedOn(
            final KeyguardViewManager.ShowListener showListener) {
        if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
        mScreenOn = true;
        if (mKeyguardView != null) {
@@ -214,6 +220,26 @@ public class KeyguardViewManager implements KeyguardWindowController {

            // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
            mKeyguardView.bindToFaceLock();

            // Caller should wait for this window to be shown before turning
            // on the screen.
            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
                // Keyguard may be in the process of being shown, but not yet
                // updated with the window manager...  give it a chance to do so.
                mKeyguardHost.post(new Runnable() {
                    @Override public void run() {
                        if (mKeyguardHost.getVisibility() == View.VISIBLE) {
                            showListener.onShown(mKeyguardHost.getWindowToken());
                        } else {
                            showListener.onShown(null);
                        }
                    }
                });
            } else {
                showListener.onShown(null);
            }
        } else {
            showListener.onShown(null);
        }
    }

+14 −42
Original line number Diff line number Diff line
@@ -116,7 +116,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
    private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
    private static final int SET_HIDDEN = 12;
    private static final int KEYGUARD_TIMEOUT = 13;
    private static final int REPORT_SHOW_DONE = 14;

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

    private boolean mScreenOn = false;

    private boolean mShowPending = false;

    // last known state of the cellular connection
    private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;

@@ -383,19 +380,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
                // Do not enable the keyguard if the prox sensor forced the screen off.
            } else {
                if (!doKeyguardLocked() && why == WindowManagerPolicy.OFF_BECAUSE_OF_USER) {
                    // The user has explicitly turned off the screen, causing it
                    // to lock.  We want to block here until the keyguard window
                    // has shown, so the power manager won't complete the screen
                    // off flow until that point, so we know it won't turn *on*
                    // the screen until this is done.
                    while (mShowPending) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                        }
                    }
                }
                doKeyguardLocked();
            }
        }
    }
@@ -403,12 +388,12 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
    /**
     * Let's us know the screen was turned on.
     */
    public void onScreenTurnedOn() {
    public void onScreenTurnedOn(KeyguardViewManager.ShowListener showListener) {
        synchronized (this) {
            mScreenOn = true;
            mDelayedShowingSequence++;
            if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
            notifyScreenOnLocked();
            notifyScreenOnLocked(showListener);
        }
    }

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

        // if the keyguard is already showing, don't bother
        if (mKeyguardViewManager.isShowing()) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
            return true;
            return;
        }

        // if the setup wizard hasn't run yet, don't show
@@ -609,18 +594,16 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
        if (!lockedOrMissing && !provisioned) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
                    + " and the sim is not locked or missing");
            return true;
            return;
        }

        if (mLockPatternUtils.isLockScreenDisabled()) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
            return true;
            return;
        }

        if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
        mShowPending = true;
        showLocked();
        return false;
    }

    /**
@@ -658,9 +641,10 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
     * @see #onScreenTurnedOn()
     * @see #handleNotifyScreenOn
     */
    private void notifyScreenOnLocked() {
    private void notifyScreenOnLocked(KeyguardViewManager.ShowListener showListener) {
        if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
        mHandler.sendEmptyMessage(NOTIFY_SCREEN_ON);
        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, showListener);
        mHandler.sendMessage(msg);
    }

    /**
@@ -974,7 +958,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
                    handleNotifyScreenOff();
                    return;
                case NOTIFY_SCREEN_ON:
                    handleNotifyScreenOn();
                    handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);
                    return;
                case WAKE_WHEN_READY:
                    handleWakeWhenReady(msg.arg1);
@@ -996,12 +980,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
                        doKeyguardLocked();
                    }
                    break;
                case REPORT_SHOW_DONE:
                    synchronized (KeyguardViewMediator.this) {
                        mShowPending = false;
                        KeyguardViewMediator.this.notifyAll();
                    }
                    break;
            }
        }
    };
@@ -1113,12 +1091,6 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
            playSounds(true);

            mShowKeyguardWakeLock.release();

            // We won't say the show is done yet because the view hierarchy
            // still needs to do the traversal.  Posting this message allows
            // us to hold off until that is done.
            Message msg = mHandler.obtainMessage(REPORT_SHOW_DONE);
            mHandler.sendMessage(msg);
        }
    }

@@ -1284,10 +1256,10 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
     * Handle message sent by {@link #notifyScreenOnLocked()}
     * @see #NOTIFY_SCREEN_ON
     */
    private void handleNotifyScreenOn() {
    private void handleNotifyScreenOn(KeyguardViewManager.ShowListener showListener) {
        synchronized (KeyguardViewMediator.this) {
            if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
            mKeyguardViewManager.onScreenTurnedOn();
            mKeyguardViewManager.onScreenTurnedOn(showListener);
        }
    }

+23 −13
Original line number Diff line number Diff line
@@ -40,8 +40,10 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.LocalPowerManager;
import android.os.Message;
import android.os.Messenger;
@@ -125,6 +127,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
import android.view.KeyCharacterMap.FallbackAction;
import android.view.WindowManagerPolicy.ScreenOnListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -2814,23 +2817,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            updateLockScreenTimeout();
            updateScreenSaverTimeoutLocked();
        }
    }

    /** {@inheritDoc} */
    public void screenTurningOn(final ScreenOnListener screenOnListener) {
        EventLog.writeEvent(70000, 1);
        //Slog.i(TAG, "Screen turning on...");
        mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
            @Override public void onShown(IBinder windowToken) {
                if (windowToken != null) {
                    try {
            mWindowManager.waitForAllDrawn();
                        mWindowManager.waitForWindowDrawn(windowToken, new IRemoteCallback.Stub() {
                            @Override public void sendResult(Bundle data) {
                                Slog.i(TAG, "Lock screen displayed!");
                                screenOnListener.onScreenOn();
                            }
                        });
                    } catch (RemoteException e) {
                    }
        // Wait for one frame to give surface flinger time to do its
        // compositing.  Yes this is a hack, but I am really not up right now for
        // implementing some mechanism to block until SF is done. :p
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
                } else {
                    Slog.i(TAG, "No lock screen!");
                    screenOnListener.onScreenOn();
                }
            }

    /** {@inheritDoc} */
    public void screenTurnedOn() {
        EventLog.writeEvent(70000, 1);
        mKeyguardMediator.onScreenTurnedOn();
        });
        synchronized (mLock) {
            mScreenOn = true;
            updateOrientationListenerLp();
Loading