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

Commit e84d855d authored by Evan Laird's avatar Evan Laird
Browse files

Extract dozing parts of StatusBarState logic out of onStateChanged

Status bar used to be calling updateDozingState every time the state
changed. When moving to StatusBarStateController however, the state
change callbacks happen less often (due to not triggering callbacks if
the state doesn't actually change). Because of this, the status bar
lost the opportunity to collapse the panel when AOD got triggered.

To fix it, I've started to transition StatusBar#mDozing to be a state on
SbStateController. This way related classes can get callbacks when the
state OR dozing chnages.

The actual bit that fixes the collapsing of the panel is to put the
logic for collapsing in the state change for dozing rather than SbState.

Change-Id: Ibabfdbfdc2e96d1f44b1d50b10e2ffdbe01a2293
Fixes: 114300041
Test: expand QS on keyguard and power screen off
Test: atest SystemUITests
parent 0036c05f
Loading
Loading
Loading
Loading
+68 −9
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.IntDef;
import android.util.ArraySet;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.systemui.statusbar.phone.StatusBar;
import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Comparator;
@@ -39,6 +40,7 @@ public class StatusBarStateController {
            = (o1, o2) -> Integer.compare(o1.rank, o2.rank);

    private final ArrayList<RankedListener> mListeners = new ArrayList<>();
    private boolean mIsDozing;
    private int mState;
    private int mLastState;
    private boolean mLeaveOpenOnKeyguardHide;
@@ -57,6 +59,11 @@ public class StatusBarStateController {
        return mState;
    }

    /**
     * Update the status bar state
     * @param state see {@link StatusBarState} for valid options
     * @return {@code true} if the state changed, else {@code false}
     */
    public boolean setState(int state) {
        if (state > MAX_STATE || state < MIN_STATE) {
            throw new IllegalArgumentException("Invalid state " + state);
@@ -82,6 +89,32 @@ public class StatusBarStateController {
        return true;
    }

    public boolean isDozing() {
        return mIsDozing;
    }

    /**
     * Update the dozing state from {@link StatusBar}'s perspective
     * @param isDozing well, are we dozing?
     * @return {@code true} if the state changed, else {@code false}
     */
    @SuppressWarnings("UnusedReturnValue")
    public boolean setIsDozing(boolean isDozing) {
        if (mIsDozing == isDozing) {
            return false;
        }

        mIsDozing = isDozing;

        synchronized (mListeners) {
            for (RankedListener rl : new ArrayList<>(mListeners)) {
                rl.listener.onDozingChanged(isDozing);
            }
        }

        return true;
    }

    public boolean goingToFullShade() {
        return mState == StatusBarState.SHADE && mLeaveOpenOnKeyguardHide;
    }
@@ -144,23 +177,49 @@ public class StatusBarStateController {
        return StatusBarState.toShortString(state);
    }

    private class RankedListener {
        private final StateListener listener;
        private final int rank;

        private RankedListener(StateListener l, int r) {
            listener = l;
            rank = r;
        }
    }

    /**
     * Listener for StatusBarState updates
     */
    public interface StateListener {

        /**
         * Callback before the new state is applied, for those who need to preempt the change
         * @param oldState state before the change
         * @param newState new state to be applied in {@link #onStateChanged}
         */
        public default void onStatePreChange(int oldState, int newState) {
        }

        /**
         * Callback after all listeners have had a chance to update based on the state change
         */
        public default void onStatePostChange() {
        }

        /**
         * Required callback. Get the new state and do what you will with it. Keep in mind that
         * other listeners are typically unordered and don't rely on your work being done before
         * other peers
         *
         * Only called if the state is actually different
         * @param newState the new {@link StatusBarState}
         */
        public void onStateChanged(int newState);
    }

    private class RankedListener {
        private final StateListener listener;
        private final int rank;

        private RankedListener(StateListener l, int r) {
            listener = l;
            rank = r;
        }
        /**
         * Callback to be notified when Dozing changes. Dozing is stored separately from state.
         * @param isDozing {@code true} if dozing according to {@link StatusBar}
         */
        public default void onDozingChanged(boolean isDozing) {}
    }
}
+41 −31
Original line number Diff line number Diff line
@@ -3756,9 +3756,6 @@ public class StatusBar extends SystemUI implements DemoMode,
        Trace.beginSection("StatusBar#updateKeyguardState");
        if (mState == StatusBarState.KEYGUARD) {
            mKeyguardIndicationController.setVisible(true);
            boolean dozingAnimated = mDozingRequested
                    && DozeParameters.getInstance(mContext).shouldControlScreenOff();
            mNotificationPanel.resetViews(dozingAnimated);
            if (mKeyguardUserSwitcher != null) {
                mKeyguardUserSwitcher.setKeyguard(true,
                        mStatusBarStateController.fromShadeLocked());
@@ -3789,6 +3786,47 @@ public class StatusBar extends SystemUI implements DemoMode,
        Trace.endSection();
    }

    @Override
    public void onDozingChanged(boolean isDozing) {
        Trace.beginSection("StatusBar#updateDozing");
        mDozing = isDozing;

        // Collapse the notification panel if open
        boolean dozingAnimated = mDozingRequested
                && DozeParameters.getInstance(mContext).shouldControlScreenOff();
        mNotificationPanel.resetViews(dozingAnimated);

        mKeyguardViewMediator.setAodShowing(mDozing);

        //TODO: make these folks listeners of StatusBarStateController.onDozingChanged
        mStatusBarWindowController.setDozing(mDozing);
        mStatusBarKeyguardViewManager.setDozing(mDozing);
        if (mAmbientIndicationContainer instanceof DozeReceiver) {
            ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
        }

        mEntryManager.updateNotifications();
        updateDozingState();
        updateScrimController();
        updateReportRejectedTouchVisibility();
        Trace.endSection();
    }

    private void updateDozing() {
        // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
        boolean dozing = mDozingRequested && mState == StatusBarState.KEYGUARD
                || mBiometricUnlockController.getMode()
                == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
        // When in wake-and-unlock we may not have received a change to mState
        // but we still should not be dozing, manually set to false.
        if (mBiometricUnlockController.getMode() ==
                BiometricUnlockController.MODE_WAKE_AND_UNLOCK) {
            dozing = false;
        }

        mStatusBarStateController.setIsDozing(dozing);
    }

    @Override
    public void onActivationReset(ActivatableNotificationView view) {
        if (view == mNotificationPanel.getActivatedChild()) {
@@ -4341,34 +4379,6 @@ public class StatusBar extends SystemUI implements DemoMode,
        updateScrimController();
    }

    private void updateDozing() {
        Trace.beginSection("StatusBar#updateDozing");
        // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
        boolean dozing = mDozingRequested && mState == StatusBarState.KEYGUARD
                || mBiometricUnlockController.getMode()
                        == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
        // When in wake-and-unlock we may not have received a change to mState
        // but we still should not be dozing, manually set to false.
        if (mBiometricUnlockController.getMode() ==
                mBiometricUnlockController.MODE_WAKE_AND_UNLOCK) {
            dozing = false;
        }
        if (mDozing != dozing) {
            mDozing = dozing;
            mKeyguardViewMediator.setAodShowing(mDozing);
            mStatusBarWindowController.setDozing(mDozing);
            mStatusBarKeyguardViewManager.setDozing(mDozing);
            if (mAmbientIndicationContainer instanceof DozeReceiver) {
                ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
            }
            mEntryManager.updateNotifications();
            updateDozingState();
            updateScrimController();
            updateReportRejectedTouchVisibility();
        }
        Trace.endSection();
    }

    @VisibleForTesting
    void updateScrimController() {
        Trace.beginSection("StatusBar#updateScrimController");