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

Commit c522d164 authored by Jim Miller's avatar Jim Miller
Browse files

Decouple critical policy power update from SCREEN_ON broadcast

This attempts to fix a bug where ordered broadcasts like
ACTION_SCREEN_ON are substantially delayed by misbehaving
receivers.  Instead, we immediately send the state to mPolicy
so that it can wake/sleep the device without delay.

Fixes bug 14313639

Change-Id: I21a191f90e0a19f1ee75c160ecc4e63e8def709e
parent 8f2e74ca
Loading
Loading
Loading
Loading
+28 −24
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ final class Notifier {
    /**
     * Notifies that the device is changing interactive state.
     */
    public void onInteractiveStateChangeStarted(boolean interactive, int reason) {
    public void onInteractiveStateChangeStarted(boolean interactive, final int reason) {
        if (DEBUG) {
            Slog.d(TAG, "onInteractiveChangeStarted: interactive=" + interactive
                    + ", reason=" + reason);
@@ -259,6 +259,14 @@ final class Notifier {
                        mScreenOnBlockerAcquired = true;
                        mScreenOnBlocker.acquire();
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
                            mPolicy.wakingUp(mScreenOnListener);
                            mActivityManagerInternal.wakingUp();
                        }
                    });
                    updatePendingBroadcastLocked();
                }
            } else {
@@ -298,6 +306,23 @@ final class Notifier {
                        mUserActivityPending = false;
                        mHandler.removeMessages(MSG_USER_ACTIVITY);
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
                            switch (mLastGoToSleepReason) {
                                case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
                                    why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
                                    break;
                                case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
                                    why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
                                    break;
                            }
                            EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
                            mPolicy.goingToSleep(why);
                            mActivityManagerInternal.goingToSleep();
                        }
                    });
                    updatePendingBroadcastLocked();
                }
            }
@@ -409,7 +434,6 @@ final class Notifier {

            mBroadcastStartTime = SystemClock.uptimeMillis();
            powerState = mBroadcastedPowerState;
            goToSleepReason = mLastGoToSleepReason;
        }

        EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
@@ -417,7 +441,7 @@ final class Notifier {
        if (powerState == POWER_STATE_AWAKE) {
            sendWakeUpBroadcast();
        } else {
            sendGoToSleepBroadcast(goToSleepReason);
            sendGoToSleepBroadcast();
        }
    }

@@ -426,11 +450,6 @@ final class Notifier {
            Slog.d(TAG, "Sending wake up broadcast.");
        }

        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);

        mPolicy.wakingUp(mScreenOnListener);
        mActivityManagerInternal.wakingUp();

        if (ActivityManagerNative.isSystemReady()) {
            mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
                    mWakeUpBroadcastDone, mHandler, 0, null, null);
@@ -462,26 +481,11 @@ final class Notifier {
        }
    };

    private void sendGoToSleepBroadcast(int reason) {
    private void sendGoToSleepBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending go to sleep broadcast.");
        }

        int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
        switch (reason) {
            case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
                why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
                break;
            case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
                why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
                break;
        }

        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);

        mPolicy.goingToSleep(why);
        mActivityManagerInternal.goingToSleep();

        if (ActivityManagerNative.isSystemReady()) {
            mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
                    mGoToSleepBroadcastDone, mHandler, 0, null, null);