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

Commit cb566aab authored by John Spurlock's avatar John Spurlock
Browse files

Doze: Follow the notification light.

 - Send the notification light info up to SystemUI from NoMan.
 - Doze mode will now periodically pulse the display (once)
   if the notification light is active.
 - Change "tease" terminology to "pulse", which is the singular.
   Maintain the multi-pulse on buzz-beep-blink for now as extra
   emphasis.
 - Scrim controller now always takes number of pulses as an arg,
   to support a single pulse (used for notification light, and
   eventually pickup once available).
 - Dial down the display brightness when pulsing.

Bug:15863249
Change-Id: Ifb208a27e82b66cff1d0c04e5b7f758098ea29cf
parent 3e137eb2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ oneway interface IStatusBar
    void setHardKeyboardStatus(boolean available, boolean enabled);
    void setWindowState(int window, int state);
    void buzzBeepBlinked();
    void notificationLightOff();
    void notificationLightPulse(int argb, int millisOn, int millisOff);

    void showRecentApps(boolean triggeredFromAltTab);
    void hideRecentApps(boolean triggeredFromAltTab);
+10 −4
Original line number Diff line number Diff line
@@ -162,11 +162,17 @@
    <!-- Doze: does this device support STATE_DOZE and STATE_DOZE_SUSPEND?  -->
    <bool name="doze_display_state_supported">false</bool>

    <!-- Doze: should the significant motion sensor be used as a tease signal? -->
    <bool name="doze_tease_on_significant_motion">false</bool>
    <!-- Doze: should the significant motion sensor be used as a pulse signal? -->
    <bool name="doze_pulse_on_significant_motion">false</bool>

    <!-- Doze: maximum brightness to use when teasing -->
    <integer name="doze_tease_brightness">80</integer>
    <!-- Doze: maximum brightness to use when pulsing -->
    <integer name="doze_pulse_brightness">40</integer>

    <!-- Doze: number of pulses when doing multiple pulses in quick succession -->
    <integer name="doze_multipulse_count">3</integer>

    <!-- Doze: interval between pulses when following the notification light -->
    <integer name="doze_notification_pulse_interval">30000</integer>

    <!-- Volume: time to delay dismissing the volume panel after a click is performed -->
    <integer name="volume_panel_dismiss_delay">200</integer>
+83 −26
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.doze;
import static android.os.PowerManager.BRIGHTNESS_OFF;
import static android.os.PowerManager.BRIGHTNESS_ON;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -42,12 +44,16 @@ import com.android.systemui.SystemUIApplication;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Date;

public class DozeService extends DreamService {
    private static final String TAG = "DozeService";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private static final String TEASE_ACTION = "com.android.systemui.doze.tease";
    private static final String ACTION_BASE = "com.android.systemui.doze";
    private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
    private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
    private static final String EXTRA_PULSES = "pulses";

    private final String mTag = String.format(TAG + ".%08x", hashCode());
    private final Context mContext = this;
@@ -58,13 +64,18 @@ public class DozeService extends DreamService {
    private Sensor mSigMotionSensor;
    private PowerManager mPowerManager;
    private PowerManager.WakeLock mWakeLock;
    private AlarmManager mAlarmManager;
    private int mMaxBrightness;
    private boolean mDreaming;
    private boolean mTeaseReceiverRegistered;
    private boolean mBroadcastReceiverRegistered;
    private boolean mSigMotionConfigured;
    private boolean mSigMotionEnabled;
    private boolean mDisplayStateSupported;
    private int mDisplayStateWhenOn;
    private boolean mNotificationLightOn;
    private PendingIntent mNotificationPulseIntent;
    private int mMultipulseCount;
    private int mNotificationPulseInterval;

    public DozeService() {
        if (DEBUG) Log.d(mTag, "new DozeService()");
@@ -75,12 +86,15 @@ public class DozeService extends DreamService {
    protected void dumpOnHandler(FileDescriptor fd, PrintWriter pw, String[] args) {
        super.dumpOnHandler(fd, pw, args);
        pw.print("  mDreaming: "); pw.println(mDreaming);
        pw.print("  mTeaseReceiverRegistered: "); pw.println(mTeaseReceiverRegistered);
        pw.print("  mBroadcastReceiverRegistered: "); pw.println(mBroadcastReceiverRegistered);
        pw.print("  mSigMotionSensor: "); pw.println(mSigMotionSensor);
        pw.print("  mSigMotionConfigured: "); pw.println(mSigMotionConfigured);
        pw.print("  mSigMotionEnabled: "); pw.println(mSigMotionEnabled);
        pw.print("  mMaxBrightness: "); pw.println(mMaxBrightness);
        pw.print("  mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
        pw.print("  mNotificationLightOn: "); pw.println(mNotificationLightOn);
        pw.print("  mMultipulseCount: "); pw.println(mMultipulseCount);
        pw.print("  mNotificationPulseInterval: "); pw.println(mNotificationPulseInterval);
    }

    @Override
@@ -99,14 +113,21 @@ public class DozeService extends DreamService {
        mSigMotionSensor = mSensors.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        final Resources res = mContext.getResources();
        mSigMotionConfigured = SystemProperties.getBoolean("doze.tease.sigmotion",
                res.getBoolean(R.bool.doze_tease_on_significant_motion));
        mSigMotionConfigured = SystemProperties.getBoolean("doze.pulse.sigmotion",
                res.getBoolean(R.bool.doze_pulse_on_significant_motion));
        mDisplayStateSupported = SystemProperties.getBoolean("doze.display.supported",
                res.getBoolean(R.bool.doze_display_state_supported));
        mMaxBrightness = MathUtils.constrain(res.getInteger(R.integer.doze_tease_brightness),
        mMaxBrightness = MathUtils.constrain(res.getInteger(R.integer.doze_pulse_brightness),
                BRIGHTNESS_OFF, BRIGHTNESS_ON);

        mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0,
                new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()),
                PendingIntent.FLAG_CANCEL_CURRENT);
        mMultipulseCount = SystemProperties.getInt("doze.multipulses",
                res.getInteger(R.integer.doze_multipulse_count));
        mNotificationPulseInterval = SystemProperties.getInt("doze.notification.pulse",
                res.getInteger(R.integer.doze_notification_pulse_interval));
        mDisplayStateWhenOn = mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON;
        setDozeScreenState(mDisplayStateWhenOn);
    }
@@ -122,7 +143,7 @@ public class DozeService extends DreamService {
        super.onDreamingStarted();
        if (DEBUG) Log.d(mTag, "onDreamingStarted canDoze=" + canDoze());
        mDreaming = true;
        listenForTeaseSignals(true);
        listenForPulseSignals(true);
        requestDoze();
    }

@@ -160,7 +181,7 @@ public class DozeService extends DreamService {
        if (mWakeLock.isHeld()) {
            mWakeLock.release();
        }
        listenForTeaseSignals(false);
        listenForPulseSignals(false);
        stopDozing();
        dozingStopped();
    }
@@ -187,9 +208,17 @@ public class DozeService extends DreamService {
        }
    }

    private void requestTease() {
    private void requestMultipulse() {
        requestPulse(mMultipulseCount);
    }

    private void requestPulse() {
        requestPulse(1);
    }

    private void requestPulse(int pulses) {
        if (mHost != null) {
            mHost.requestTease(this);
            mHost.requestPulse(pulses, this);
        }
    }

@@ -199,10 +228,10 @@ public class DozeService extends DreamService {
        }
    }

    private void listenForTeaseSignals(boolean listen) {
        if (DEBUG) Log.d(mTag, "listenForTeaseSignals: " + listen);
    private void listenForPulseSignals(boolean listen) {
        if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
        listenForSignificantMotion(listen);
        listenForBroadcast(listen);
        listenForBroadcasts(listen);
        listenForNotifications(listen);
    }

@@ -216,15 +245,17 @@ public class DozeService extends DreamService {
        }
    }

    private void listenForBroadcast(boolean listen) {
    private void listenForBroadcasts(boolean listen) {
        if (listen) {
            mContext.registerReceiver(mTeaseReceiver, new IntentFilter(TEASE_ACTION));
            mTeaseReceiverRegistered = true;
            final IntentFilter filter = new IntentFilter(PULSE_ACTION);
            filter.addAction(NOTIFICATION_PULSE_ACTION);
            mContext.registerReceiver(mBroadcastReceiver, filter);
            mBroadcastReceiverRegistered = true;
        } else {
            if (mTeaseReceiverRegistered) {
                mContext.unregisterReceiver(mTeaseReceiver);
            if (mBroadcastReceiverRegistered) {
                mContext.unregisterReceiver(mBroadcastReceiver);
            }
            mTeaseReceiverRegistered = false;
            mBroadcastReceiverRegistered = false;
        }
    }

@@ -237,6 +268,15 @@ public class DozeService extends DreamService {
        }
    }

    private void rescheduleNotificationPulse() {
        mAlarmManager.cancel(mNotificationPulseIntent);
        if (mNotificationLightOn) {
            final long time = System.currentTimeMillis() + mNotificationPulseInterval;
            if (DEBUG) Log.d(TAG, "Scheduling pulse for " + new Date(time));
            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
        }
    }

    private static String triggerEventToString(TriggerEvent event) {
        if (event == null) return null;
        final StringBuilder sb = new StringBuilder("TriggerEvent[")
@@ -269,16 +309,23 @@ public class DozeService extends DreamService {
                    v.vibrate(1000);
                }
            }
            requestTease();
            requestPulse();
            listenForSignificantMotion(true);  // reregister, this sensor only fires once
        }
    };

    private final BroadcastReceiver mTeaseReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (DEBUG) Log.d(mTag, "Received tease intent");
            requestTease();
            if (PULSE_ACTION.equals(intent.getAction())) {
                if (DEBUG) Log.d(mTag, "Received pulse intent");
                requestPulse(intent.getIntExtra(EXTRA_PULSES, mMultipulseCount));
            }
            if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
                if (DEBUG) Log.d(mTag, "Received notification pulse intent");
                requestPulse();
                rescheduleNotificationPulse();
            }
        }
    };

@@ -288,10 +335,19 @@ public class DozeService extends DreamService {
            if (DEBUG) Log.d(mTag, "onNewNotifications");
            // noop for now
        }

        @Override
        public void onBuzzBeepBlinked() {
            if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
            requestTease();
            requestMultipulse();
        }

        @Override
        public void onNotificationLight(boolean on) {
            if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on);
            if (mNotificationLightOn == on) return;
            mNotificationLightOn = on;
            rescheduleNotificationPulse();
        }
    };

@@ -299,12 +355,13 @@ public class DozeService extends DreamService {
        void addCallback(Callback callback);
        void removeCallback(Callback callback);
        void requestDoze(DozeService dozeService);
        void requestTease(DozeService dozeService);
        void requestPulse(int pulses, DozeService dozeService);
        void dozingStopped(DozeService dozeService);

        public interface Callback {
            void onNewNotifications();
            void onBuzzBeepBlinked();
            void onNotificationLight(boolean on);
        }
    }
}
+23 −1
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ public class CommandQueue extends IStatusBar.Stub {
    private static final int MSG_SHOW_RECENT_APPS           = 14 << MSG_SHIFT;
    private static final int MSG_HIDE_RECENT_APPS           = 15 << MSG_SHIFT;
    private static final int MSG_BUZZ_BEEP_BLINKED          = 16 << MSG_SHIFT;
    private static final int MSG_NOTIFICATION_LIGHT_OFF     = 17 << MSG_SHIFT;
    private static final int MSG_NOTIFICATION_LIGHT_PULSE   = 18 << MSG_SHIFT;

    public static final int FLAG_EXCLUDE_NONE = 0;
    public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -95,6 +97,8 @@ public class CommandQueue extends IStatusBar.Stub {
        public void hideSearchPanel();
        public void setWindowState(int window, int state);
        public void buzzBeepBlinked();
        public void notificationLightOff();
        public void notificationLightPulse(int argb, int onMillis, int offMillis);
    }

    public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -230,6 +234,19 @@ public class CommandQueue extends IStatusBar.Stub {
        }
    }

    public void notificationLightOff() {
        synchronized (mList) {
            mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
        }
    }

    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
        synchronized (mList) {
            mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
                    .sendToTarget();
        }
    }

    private final class H extends Handler {
        public void handleMessage(Message msg) {
            final int what = msg.what & MSG_MASK;
@@ -306,7 +323,12 @@ public class CommandQueue extends IStatusBar.Stub {
                case MSG_BUZZ_BEEP_BLINKED:
                    mCallbacks.buzzBeepBlinked();
                    break;

                case MSG_NOTIFICATION_LIGHT_OFF:
                    mCallbacks.notificationLightOff();
                    break;
                case MSG_NOTIFICATION_LIGHT_PULSE:
                    mCallbacks.notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
                    break;
            }
        }
    }
+27 −7
Original line number Diff line number Diff line
@@ -2336,6 +2336,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        }
    }

    @Override
    public void notificationLightOff() {
        if (mDozeServiceHost != null) {
            mDozeServiceHost.fireNotificationLight(false);
        }
    }

    @Override
    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
        if (mDozeServiceHost != null) {
            mDozeServiceHost.fireNotificationLight(true);
        }
    }

    @Override // CommandQueue
    public void setSystemUiVisibility(int vis, int mask) {
        final int oldVal = mSystemUiVisibility;
@@ -3799,6 +3813,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            }
        }

        public void fireNotificationLight(boolean on) {
            for (Callback callback : mCallbacks) {
                callback.onNotificationLight(on);
            }
        }

        public void fireNewNotifications() {
            for (Callback callback : mCallbacks) {
                callback.onNewNotifications();
@@ -3823,10 +3843,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        }

        @Override
        public void requestTease(DozeService dozeService) {
        public void requestPulse(int pulses, DozeService dozeService) {
            if (dozeService == null) return;
            dozeService.stayAwake(PROCESSING_TIME);
            mHandler.obtainMessage(H.REQUEST_TEASE, dozeService).sendToTarget();
            mHandler.obtainMessage(H.REQUEST_PULSE, pulses, 0, dozeService).sendToTarget();
        }

        @Override
@@ -3845,9 +3865,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            mCurrentDozeService.startDozing();
        }

        private void handleRequestTease(DozeService dozeService) {
        private void handleRequestPulse(int pulses, DozeService dozeService) {
            if (!dozeService.equals(mCurrentDozeService)) return;
            final long stayAwake = mScrimController.tease();
            final long stayAwake = mScrimController.pulse(pulses);
            mCurrentDozeService.stayAwake(stayAwake);
        }

@@ -3863,15 +3883,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,

        private final class H extends Handler {
            private static final int REQUEST_DOZE = 1;
            private static final int REQUEST_TEASE = 2;
            private static final int REQUEST_PULSE = 2;
            private static final int DOZING_STOPPED = 3;

            @Override
            public void handleMessage(Message msg) {
                if (msg.what == REQUEST_DOZE) {
                    handleRequestDoze((DozeService) msg.obj);
                } else if (msg.what == REQUEST_TEASE) {
                    handleRequestTease((DozeService) msg.obj);
                } else if (msg.what == REQUEST_PULSE) {
                    handleRequestPulse(msg.arg1, (DozeService) msg.obj);
                } else if (msg.what == DOZING_STOPPED) {
                    handleDozingStopped((DozeService) msg.obj);
                }
Loading