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

Commit 1f32c656 authored by Christoph Studer's avatar Christoph Studer
Browse files

NoMan/SysUI: Clear LEDs only when entering the shade

Don't clear notification LEDs when seeing notifications on the
lockscreen.

Also fix a bug where the LED didn't continue flashing after
the screen turned off.

For devices with doze capability, ensure that the LED continuing
to flash after screen off doesn't cause an immediate pulses, but
delay the first pulse by 10s.

Bug: 15449039
Change-Id: Id34d51a2c91ceaf069e49add1ab690bb855f9638
parent da392904
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -40,8 +40,10 @@ interface IStatusBarService
    // You need the STATUS_BAR_SERVICE permission
    void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList,
            out int[] switches, out List<IBinder> binders);
    void onPanelRevealed();
    void onPanelRevealed(boolean clearNotificationEffects);
    void onPanelHidden();
    // Mark current notifications as "seen" and stop ringing, vibrating, blinking.
    void clearNotificationEffects();
    void onNotificationClick(String key);
    void onNotificationActionClick(String key, int actionIndex);
    void onNotificationError(String pkg, String tag, int id,
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ public interface DozeHost {
    void pulseWhileDozing(@NonNull PulseCallback callback);
    void stopDozing();
    boolean isPowerSaveActive();
    boolean isNotificationLightOn();

    public interface Callback {
        void onNewNotifications();
+33 −9
Original line number Diff line number Diff line
@@ -56,6 +56,17 @@ public class DozeService extends DreamService {
    private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
    private static final String EXTRA_INSTANCE = "instance";

    /**
     * Earliest time we pulse due to a notification light after the service started.
     *
     * <p>Incoming notification light events during the blackout period are
     * delayed to the earliest time defined by this constant.</p>
     *
     * <p>This delay avoids a pulse immediately after screen off, at which
     * point the notification light is re-enabled again by NoMan.</p>
     */
    private static final int EARLIEST_LIGHT_PULSE_AFTER_START_MS = 10 * 1000;

    private final String mTag = String.format(TAG + ".%08x", hashCode());
    private final Context mContext = this;
    private final DozeParameters mDozeParameters = new DozeParameters(mContext);
@@ -77,6 +88,7 @@ public class DozeService extends DreamService {
    private boolean mPowerSaveActive;
    private boolean mCarMode;
    private long mNotificationPulseTime;
    private long mEarliestPulseDueToLight;
    private int mScheduleResetsRemaining;

    public DozeService() {
@@ -159,8 +171,9 @@ public class DozeService extends DreamService {
        }

        mDreaming = true;
        listenForPulseSignals(true);
        rescheduleNotificationPulse(false /*predicate*/);  // cancel any pending pulse alarms
        mEarliestPulseDueToLight = System.currentTimeMillis() + EARLIEST_LIGHT_PULSE_AFTER_START_MS;
        listenForPulseSignals(true);

        // Ask the host to get things ready to start dozing.
        // Once ready, we call startDozing() at which point the CPU may suspend
@@ -295,6 +308,12 @@ public class DozeService extends DreamService {
        if (listen) {
            resetNotificationResets();
            mHost.addCallback(mHostCallback);

            // Continue to pulse for existing LEDs.
            mNotificationLightOn = mHost.isNotificationLightOn();
            if (mNotificationLightOn) {
                updateNotificationPulseDueToLight();
            }
        } else {
            mHost.removeCallback(mHostCallback);
        }
@@ -305,21 +324,26 @@ public class DozeService extends DreamService {
        mScheduleResetsRemaining = mDozeParameters.getPulseScheduleResets();
    }

    private void updateNotificationPulse() {
        if (DEBUG) Log.d(mTag, "updateNotificationPulse");
    private void updateNotificationPulseDueToLight() {
        long timeMs = System.currentTimeMillis();
        timeMs = Math.max(timeMs, mEarliestPulseDueToLight);
        updateNotificationPulse(timeMs);
    }

    private void updateNotificationPulse(long notificationTimeMs) {
        if (DEBUG) Log.d(mTag, "updateNotificationPulse notificationTimeMs=" + notificationTimeMs);
        if (!mDozeParameters.getPulseOnNotifications()) return;
        if (mScheduleResetsRemaining <= 0) {
            if (DEBUG) Log.d(mTag, "No more schedule resets remaining");
            return;
        }
        final long now = System.currentTimeMillis();
        if ((now - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) {
        if ((notificationTimeMs - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) {
            if (DEBUG) Log.d(mTag, "Recently updated, not resetting schedule");
            return;
        }
        mScheduleResetsRemaining--;
        if (DEBUG) Log.d(mTag, "mScheduleResetsRemaining = " + mScheduleResetsRemaining);
        mNotificationPulseTime = now;
        mNotificationPulseTime = notificationTimeMs;
        rescheduleNotificationPulse(true /*predicate*/);
    }

@@ -401,14 +425,14 @@ public class DozeService extends DreamService {
    private final DozeHost.Callback mHostCallback = new DozeHost.Callback() {
        @Override
        public void onNewNotifications() {
            if (DEBUG) Log.d(mTag, "onNewNotifications");
            if (DEBUG) Log.d(mTag, "onNewNotifications (noop)");
            // noop for now
        }

        @Override
        public void onBuzzBeepBlinked() {
            if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
            updateNotificationPulse();
            updateNotificationPulse(System.currentTimeMillis());
        }

        @Override
@@ -417,7 +441,7 @@ public class DozeService extends DreamService {
            if (mNotificationLightOn == on) return;
            mNotificationLightOn = on;
            if (mNotificationLightOn) {
                updateNotificationPulse();
                updateNotificationPulseDueToLight();
            }
        }

+5 −1
Original line number Diff line number Diff line
@@ -1642,7 +1642,11 @@ public abstract class BaseStatusBar extends SystemUI implements
    protected void handleVisibleToUserChanged(boolean visibleToUser) {
        try {
            if (visibleToUser) {
                mBarService.onPanelRevealed();
                // Only stop blinking, vibrating, ringing when the user went into the shade
                // manually (SHADE or SHADE_LOCKED).
                boolean clearNotificationEffects =
                        (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
                mBarService.onPanelRevealed(clearNotificationEffects);
            } else {
                mBarService.onPanelHidden();
            }
+19 −0
Original line number Diff line number Diff line
@@ -3807,6 +3807,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
     * @param state The {@link StatusBarState} to set.
     */
    public void setBarState(int state) {
        // If we're visible and switched to SHADE_LOCKED (the user dragged down
        // on the lockscreen), clear notification LED, vibration, ringing.
        // Other transitions are covered in handleVisibleToUserChanged().
        if (mVisible && mState != state && state == StatusBarState.SHADE_LOCKED) {
            try {
                mBarService.clearNotificationEffects();
            } catch (RemoteException e) {
                // Ignore.
            }
        }
        mState = state;
        mStatusBarWindowManager.setStatusBarState(state);
    }
@@ -4138,6 +4148,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
        private final H mHandler = new H();

        // Keeps the last reported state by fireNotificationLight.
        private boolean mNotificationLightOn;

        @Override
        public String toString() {
            return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
@@ -4156,6 +4169,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        }

        public void fireNotificationLight(boolean on) {
            mNotificationLightOn = on;
            for (Callback callback : mCallbacks) {
                callback.onNotificationLight(on);
            }
@@ -4197,6 +4211,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            return mBatteryController != null && mBatteryController.isPowerSave();
        }

        @Override
        public boolean isNotificationLightOn() {
            return mNotificationLightOn;
        }

        private void handleStartDozing(@NonNull Runnable ready) {
            if (!mDozing) {
                mDozing = true;
Loading