Loading packages/SystemUI/res/values/config.xml +8 −6 Original line number Diff line number Diff line Loading @@ -194,9 +194,14 @@ <!-- Doze: should the pickup sensor be used as a pulse signal? --> <bool name="doze_pulse_on_pick_up">false</bool> <!-- Doze: period of time between pulses (start of pulse) when following the notification light Format: <under_ms>:<period_ms>,...,<default_ms> --> <string name="doze_pulse_period_function">60000:10000,300000:30000,1800000:60000,0</string> <!-- Doze: should notifications be used as a pulse signal? --> <bool name="doze_pulse_on_notifications">true</bool> <!-- Doze: when to pulse after a buzzworthy notification arrives --> <string name="doze_pulse_schedule">1s,10s,30s,60s,120s</string> <!-- Doze: maximum number of times the notification pulse schedule can be reset --> <integer name="doze_pulse_schedule_resets">3</integer> <!-- Doze: pulse parameter - how long does it take to fade in? --> <integer name="doze_pulse_duration_in">1000</integer> Loading @@ -207,9 +212,6 @@ <!-- Doze: pulse parameter - how long does it take to fade out? --> <integer name="doze_pulse_duration_out">1000</integer> <!-- Doze: pulse parameter - how long to wait before pulsing (if not starting immediately) --> <integer name="doze_pulse_delay">1000</integer> <!-- Doze: alpha to apply to small icons when dozing --> <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff --> Loading packages/SystemUI/src/com/android/systemui/doze/DozeService.java +79 −37 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorManager; import android.hardware.TriggerEvent; Loading @@ -30,15 +29,14 @@ import android.hardware.TriggerEventListener; import android.media.AudioAttributes; import android.os.Handler; import android.os.PowerManager; import android.os.SystemProperties; import android.os.Vibrator; import android.service.dreams.DreamService; import android.util.Log; import android.view.Display; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters.PulseSchedule; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -72,6 +70,7 @@ public class DozeService extends DreamService { private PendingIntent mNotificationPulseIntent; private boolean mPowerSaveActive; private long mNotificationPulseTime; private int mScheduleResetsRemaining; public DozeService() { if (DEBUG) Log.d(mTag, "new DozeService()"); Loading @@ -90,6 +89,7 @@ public class DozeService extends DreamService { pw.print(" mNotificationLightOn: "); pw.println(mNotificationLightOn); pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive); pw.print(" mNotificationPulseTime: "); pw.println(mNotificationPulseTime); pw.print(" mScheduleResetsRemaining: "); pw.println(mScheduleResetsRemaining); mDozeParameters.dump(pw); } Loading @@ -107,16 +107,14 @@ public class DozeService extends DreamService { setWindowless(true); mSensors = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); mSigMotionSensor = new TriggerSensor(Sensor.TYPE_SIGNIFICANT_MOTION, "doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion); mPickupSensor = new TriggerSensor(Sensor.TYPE_PICK_UP_GESTURE, "doze.pulse.pickup", R.bool.doze_pulse_on_pick_up); mSigMotionSensor = new TriggerSensor(Sensor.TYPE_SIGNIFICANT_MOTION, mDozeParameters.getPulseOnSigMotion(), mDozeParameters.getVibrateOnSigMotion()); mPickupSensor = new TriggerSensor(Sensor.TYPE_PICK_UP_GESTURE, mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup()); 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(); mDisplayStateSupported = SystemProperties.getBoolean("doze.display.supported", res.getBoolean(R.bool.doze_display_state_supported)); mDisplayStateSupported = mDozeParameters.getDisplayStateSupported(); mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()), PendingIntent.FLAG_UPDATE_CURRENT); Loading @@ -142,6 +140,7 @@ public class DozeService extends DreamService { } mDreaming = true; listenForPulseSignals(true); rescheduleNotificationPulse(false /*predicate*/); // cancel any pending pulse alarms requestDoze(); } Loading Loading @@ -174,15 +173,21 @@ public class DozeService extends DreamService { mHandler.removeCallbacks(mDisplayOff); } @Override public void startDozing() { if (DEBUG) Log.d(mTag, "startDozing"); super.startDozing(); } private void requestDoze() { if (mHost != null) { mHost.requestDoze(this); } } private void requestPulse(boolean delayed) { private void requestPulse() { if (mHost != null) { mHost.requestPulse(delayed, this); mHost.requestPulse(this); } } Loading Loading @@ -222,24 +227,61 @@ public class DozeService extends DreamService { private void listenForNotifications(boolean listen) { if (mHost == null) return; if (listen) { resetNotificationResets(); mHost.addCallback(mHostCallback); } else { mHost.removeCallback(mHostCallback); } } private void rescheduleNotificationPulse() { private void resetNotificationResets() { if (DEBUG) Log.d(TAG, "resetNotificationResets"); mScheduleResetsRemaining = mDozeParameters.getPulseScheduleResets(); } private void updateNotificationPulse() { if (DEBUG) Log.d(TAG, "updateNotificationPulse"); if (!mDozeParameters.getPulseOnNotifications()) return; if (mScheduleResetsRemaining <= 0) { if (DEBUG) Log.d(TAG, "No more schedule resets remaining"); return; } final long now = System.currentTimeMillis(); if ((now - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) { if (DEBUG) Log.d(TAG, "Recently updated, not resetting schedule"); return; } mScheduleResetsRemaining--; if (DEBUG) Log.d(TAG, "mScheduleResetsRemaining = " + mScheduleResetsRemaining); mNotificationPulseTime = now; rescheduleNotificationPulse(true /*predicate*/); } private void rescheduleNotificationPulse(boolean predicate) { if (DEBUG) Log.d(TAG, "rescheduleNotificationPulse predicate=" + predicate); mAlarmManager.cancel(mNotificationPulseIntent); if (mNotificationLightOn) { if (!predicate) { if (DEBUG) Log.d(TAG, " don't reschedule: predicate is false"); return; } final PulseSchedule schedule = mDozeParameters.getPulseSchedule(); if (schedule == null) { if (DEBUG) Log.d(TAG, " don't reschedule: schedule is null"); return; } final long now = System.currentTimeMillis(); final long age = now - mNotificationPulseTime; final long period = mDozeParameters.getPulsePeriod(age); final long time = now + period; if (period > 0) { if (DEBUG) Log.d(TAG, "Scheduling pulse in " + period + " for " + new Date(time)); mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent); final long time = schedule.getNextTime(now, mNotificationPulseTime); if (time <= 0) { if (DEBUG) Log.d(TAG, " don't reschedule: time is " + time); return; } final long delta = time - now; if (delta <= 0) { if (DEBUG) Log.d(TAG, " don't reschedule: delta is " + delta); return; } if (DEBUG) Log.d(TAG, "Scheduling pulse in " + delta + "ms for " + new Date(time)); mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent); } private static String triggerEventToString(TriggerEvent event) { Loading Loading @@ -268,12 +310,12 @@ public class DozeService extends DreamService { public void onReceive(Context context, Intent intent) { if (PULSE_ACTION.equals(intent.getAction())) { if (DEBUG) Log.d(mTag, "Received pulse intent"); requestPulse(false /*delayed*/); requestPulse(); } if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) { if (DEBUG) Log.d(mTag, "Received notification pulse intent"); requestPulse(true /*delayed*/); rescheduleNotificationPulse(); requestPulse(); rescheduleNotificationPulse(mNotificationLightOn); } } }; Loading @@ -288,8 +330,7 @@ public class DozeService extends DreamService { @Override public void onBuzzBeepBlinked() { if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked"); mNotificationPulseTime = System.currentTimeMillis(); requestPulse(true /*delayed*/); updateNotificationPulse(); } @Override Loading @@ -298,10 +339,8 @@ public class DozeService extends DreamService { if (mNotificationLightOn == on) return; mNotificationLightOn = on; if (mNotificationLightOn) { mNotificationPulseTime = System.currentTimeMillis(); requestPulse(true /*delayed*/); updateNotificationPulse(); } rescheduleNotificationPulse(); } @Override Loading @@ -317,7 +356,7 @@ public class DozeService extends DreamService { void addCallback(Callback callback); void removeCallback(Callback callback); void requestDoze(DozeService dozeService); void requestPulse(boolean delayed, DozeService dozeService); void requestPulse(DozeService dozeService); void dozingStopped(DozeService dozeService); boolean isPowerSaveActive(); Loading @@ -332,13 +371,14 @@ public class DozeService extends DreamService { private class TriggerSensor extends TriggerEventListener { private final Sensor mSensor; private final boolean mConfigured; private final boolean mDebugVibrate; private boolean mEnabled; public TriggerSensor(int type, String sysPropConfig, int resConfig) { public TriggerSensor(int type, boolean configured, boolean debugVibrate) { mSensor = mSensors.getDefaultSensor(type); mConfigured = SystemProperties.getBoolean(sysPropConfig, mContext.getResources().getBoolean(resConfig)); mConfigured = configured; mDebugVibrate = debugVibrate; } public void setListening(boolean listen) { Loading @@ -354,13 +394,14 @@ public class DozeService extends DreamService { @Override public String toString() { return new StringBuilder("{mEnabled=").append(mEnabled).append(", mConfigured=") .append(mConfigured).append(", mSensor=").append(mSensor).append("}").toString(); .append(mConfigured).append(", mDebugVibrate=").append(mDebugVibrate) .append(", mSensor=").append(mSensor).append("}").toString(); } @Override public void onTrigger(TriggerEvent event) { if (DEBUG) Log.d(mTag, "onTrigger: " + triggerEventToString(event)); if (DEBUG) { if (mDebugVibrate) { final Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); if (v != null) { v.vibrate(1000, new AudioAttributes.Builder() Loading @@ -368,8 +409,9 @@ public class DozeService extends DreamService { .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build()); } } requestPulse(false /*delayed*/); requestPulse(); setListening(true); // reregister, this sensor only fires once resetNotificationResets(); } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +63 −29 Original line number Diff line number Diff line Loading @@ -25,17 +25,19 @@ import android.util.MathUtils; import com.android.systemui.R; import java.io.PrintWriter; import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DozeParameters { private static final String TAG = "DozeParameters"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int MAX_DURATION = 10 * 1000; private final Context mContext; private StepFunction mPulsePeriodFunction; private static PulseSchedule sPulseSchedule; public DozeParameters(Context context) { mContext = context; Loading @@ -43,12 +45,22 @@ public class DozeParameters { public void dump(PrintWriter pw) { pw.println(" DozeParameters:"); pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported()); pw.print(" getPulseDuration(): "); pw.println(getPulseDuration()); pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration()); pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration()); pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration()); pw.print(" getPulseStartDelay(): "); pw.println(getPulseStartDelay()); pw.print(" getPulsePeriodFunction(): "); pw.println(getPulsePeriodFunction()); pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion()); pw.print(" getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion()); pw.print(" getPulseOnPickup(): "); pw.println(getPulseOnPickup()); pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup()); pw.print(" getPulseOnNotifications(): "); pw.println(getPulseOnNotifications()); pw.print(" getPulseSchedule(): "); pw.println(getPulseSchedule()); pw.print(" getPulseScheduleResets(): "); pw.println(getPulseScheduleResets()); } public boolean getDisplayStateSupported() { return getBoolean("doze.display.supported", R.bool.doze_display_state_supported); } public int getPulseDuration() { Loading @@ -67,20 +79,40 @@ public class DozeParameters { return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out); } public int getPulseStartDelay() { return getInt("doze.pulse.delay", R.integer.doze_pulse_delay); public boolean getPulseOnSigMotion() { return getBoolean("doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion); } public boolean getVibrateOnSigMotion() { return SystemProperties.getBoolean("doze.vibrate.sigmotion", false); } public boolean getPulseOnPickup() { return getBoolean("doze.pulse.pickup", R.bool.doze_pulse_on_pick_up); } public boolean getVibrateOnPickup() { return SystemProperties.getBoolean("doze.vibrate.pickup", false); } public boolean getPulseOnNotifications() { return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications); } public long getPulsePeriod(long age) { final String spec = getPulsePeriodFunction(); if (mPulsePeriodFunction == null || !mPulsePeriodFunction.mSpec.equals(spec)) { mPulsePeriodFunction = StepFunction.parse(spec); public PulseSchedule getPulseSchedule() { final String spec = getString("doze.pulse.schedule", R.string.doze_pulse_schedule); if (sPulseSchedule == null || !sPulseSchedule.mSpec.equals(spec)) { sPulseSchedule = PulseSchedule.parse(spec); } return mPulsePeriodFunction != null ? mPulsePeriodFunction.evaluate(age) : 0; return sPulseSchedule; } private String getPulsePeriodFunction() { return getString("doze.pulse.period.function", R.string.doze_pulse_period_function); public int getPulseScheduleResets() { return getInt("doze.pulse.schedule.resets", R.integer.doze_pulse_schedule_resets); } private boolean getBoolean(String propName, int resId) { return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId)); } private int getInt(String propName, int resId) { Loading @@ -92,29 +124,25 @@ public class DozeParameters { return SystemProperties.get(propName, mContext.getString(resId)); } private static class StepFunction { private static final Pattern PATTERN = Pattern.compile("(\\d+?)(:(\\d+?))?", 0); public static class PulseSchedule { private static final Pattern PATTERN = Pattern.compile("(\\d+?)s", 0); private String mSpec; private long[] mSteps; private long[] mValues; private long mDefault; private int[] mSchedule; public static StepFunction parse(String spec) { public static PulseSchedule parse(String spec) { if (TextUtils.isEmpty(spec)) return null; try { final StepFunction rt = new StepFunction(); final PulseSchedule rt = new PulseSchedule(); rt.mSpec = spec; final String[] tokens = spec.split(","); rt.mSteps = new long[tokens.length - 1]; rt.mValues = new long[tokens.length - 1]; for (int i = 0; i < tokens.length - 1; i++) { rt.mSchedule = new int[tokens.length]; for (int i = 0; i < tokens.length; i++) { final Matcher m = PATTERN.matcher(tokens[i]); if (!m.matches()) throw new IllegalArgumentException("Bad token: " + tokens[i]); rt.mSteps[i] = Long.parseLong(m.group(1)); rt.mValues[i] = Long.parseLong(m.group(3)); rt.mSchedule[i] = Integer.parseInt(m.group(1)); } rt.mDefault = Long.parseLong(tokens[tokens.length - 1]); if (DEBUG) Log.d(TAG, "Parsed spec [" + spec + "] as: " + rt); return rt; } catch (RuntimeException e) { Log.w(TAG, "Error parsing spec: " + spec, e); Loading @@ -122,11 +150,17 @@ public class DozeParameters { } } public long evaluate(long x) { for (int i = 0; i < mSteps.length; i++) { if (x < mSteps[i]) return mValues[i]; @Override public String toString() { return Arrays.toString(mSchedule); } public long getNextTime(long now, long notificationTime) { for (int i = 0; i < mSchedule.length; i++) { final long time = notificationTime + mSchedule[i] * 1000; if (time > now) return time; } return mDefault; return 0; } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +5 −6 Original line number Diff line number Diff line Loading @@ -4083,11 +4083,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override public void requestPulse(boolean delayed, DozeService dozeService) { public void requestPulse(DozeService dozeService) { if (dozeService == null) return; dozeService.stayAwake(PROCESSING_TIME); mHandler.obtainMessage(H.REQUEST_PULSE, delayed ? 1 : 0, 0, dozeService) .sendToTarget(); mHandler.obtainMessage(H.REQUEST_PULSE, dozeService).sendToTarget(); } @Override Loading @@ -4110,9 +4109,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mCurrentDozeService.startDozing(); } private void handleRequestPulse(boolean delayed, DozeService dozeService) { private void handleRequestPulse(DozeService dozeService) { if (!dozeService.equals(mCurrentDozeService)) return; final long stayAwake = mScrimController.pulse(delayed); final long stayAwake = mScrimController.pulse(); mCurrentDozeService.stayAwake(stayAwake); } Loading @@ -4136,7 +4135,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (msg.what == REQUEST_DOZE) { handleRequestDoze((DozeService) msg.obj); } else if (msg.what == REQUEST_PULSE) { handleRequestPulse(msg.arg1 != 0, (DozeService) msg.obj); handleRequestPulse((DozeService) msg.obj); } else if (msg.what == DOZING_STOPPED) { handleDozingStopped((DozeService) msg.obj); } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +6 −6 Original line number Diff line number Diff line Loading @@ -129,20 +129,20 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { if (!mDozing) { cancelPulsing(); mAnimateChange = true; } else { mAnimateChange = false; } scheduleUpdate(); } /** When dozing, fade screen contents in and out using the front scrim. */ public long pulse(boolean delayed) { public long pulse() { if (!mDozing) return 0; final long now = System.currentTimeMillis(); if (DEBUG) Log.d(TAG, "pulse delayed=" + delayed + " mPulseEndTime=" + mPulseEndTime + " now=" + now); if (DEBUG) Log.d(TAG, "pulse mPulseEndTime=" + mPulseEndTime + " now=" + now); if (mPulseEndTime != 0 && mPulseEndTime > now) return mPulseEndTime - now; final long delay = delayed ? mDozeParameters.getPulseStartDelay() : 0; mScrimInFront.postDelayed(mPulseIn, delay); mPulseEndTime = now + delay + mDozeParameters.getPulseDuration(); mScrimInFront.post(mPulseIn); mPulseEndTime = now + mDozeParameters.getPulseDuration(); return mPulseEndTime - now; } Loading Loading
packages/SystemUI/res/values/config.xml +8 −6 Original line number Diff line number Diff line Loading @@ -194,9 +194,14 @@ <!-- Doze: should the pickup sensor be used as a pulse signal? --> <bool name="doze_pulse_on_pick_up">false</bool> <!-- Doze: period of time between pulses (start of pulse) when following the notification light Format: <under_ms>:<period_ms>,...,<default_ms> --> <string name="doze_pulse_period_function">60000:10000,300000:30000,1800000:60000,0</string> <!-- Doze: should notifications be used as a pulse signal? --> <bool name="doze_pulse_on_notifications">true</bool> <!-- Doze: when to pulse after a buzzworthy notification arrives --> <string name="doze_pulse_schedule">1s,10s,30s,60s,120s</string> <!-- Doze: maximum number of times the notification pulse schedule can be reset --> <integer name="doze_pulse_schedule_resets">3</integer> <!-- Doze: pulse parameter - how long does it take to fade in? --> <integer name="doze_pulse_duration_in">1000</integer> Loading @@ -207,9 +212,6 @@ <!-- Doze: pulse parameter - how long does it take to fade out? --> <integer name="doze_pulse_duration_out">1000</integer> <!-- Doze: pulse parameter - how long to wait before pulsing (if not starting immediately) --> <integer name="doze_pulse_delay">1000</integer> <!-- Doze: alpha to apply to small icons when dozing --> <integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff --> Loading
packages/SystemUI/src/com/android/systemui/doze/DozeService.java +79 −37 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorManager; import android.hardware.TriggerEvent; Loading @@ -30,15 +29,14 @@ import android.hardware.TriggerEventListener; import android.media.AudioAttributes; import android.os.Handler; import android.os.PowerManager; import android.os.SystemProperties; import android.os.Vibrator; import android.service.dreams.DreamService; import android.util.Log; import android.view.Display; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters.PulseSchedule; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -72,6 +70,7 @@ public class DozeService extends DreamService { private PendingIntent mNotificationPulseIntent; private boolean mPowerSaveActive; private long mNotificationPulseTime; private int mScheduleResetsRemaining; public DozeService() { if (DEBUG) Log.d(mTag, "new DozeService()"); Loading @@ -90,6 +89,7 @@ public class DozeService extends DreamService { pw.print(" mNotificationLightOn: "); pw.println(mNotificationLightOn); pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive); pw.print(" mNotificationPulseTime: "); pw.println(mNotificationPulseTime); pw.print(" mScheduleResetsRemaining: "); pw.println(mScheduleResetsRemaining); mDozeParameters.dump(pw); } Loading @@ -107,16 +107,14 @@ public class DozeService extends DreamService { setWindowless(true); mSensors = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); mSigMotionSensor = new TriggerSensor(Sensor.TYPE_SIGNIFICANT_MOTION, "doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion); mPickupSensor = new TriggerSensor(Sensor.TYPE_PICK_UP_GESTURE, "doze.pulse.pickup", R.bool.doze_pulse_on_pick_up); mSigMotionSensor = new TriggerSensor(Sensor.TYPE_SIGNIFICANT_MOTION, mDozeParameters.getPulseOnSigMotion(), mDozeParameters.getVibrateOnSigMotion()); mPickupSensor = new TriggerSensor(Sensor.TYPE_PICK_UP_GESTURE, mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup()); 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(); mDisplayStateSupported = SystemProperties.getBoolean("doze.display.supported", res.getBoolean(R.bool.doze_display_state_supported)); mDisplayStateSupported = mDozeParameters.getDisplayStateSupported(); mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()), PendingIntent.FLAG_UPDATE_CURRENT); Loading @@ -142,6 +140,7 @@ public class DozeService extends DreamService { } mDreaming = true; listenForPulseSignals(true); rescheduleNotificationPulse(false /*predicate*/); // cancel any pending pulse alarms requestDoze(); } Loading Loading @@ -174,15 +173,21 @@ public class DozeService extends DreamService { mHandler.removeCallbacks(mDisplayOff); } @Override public void startDozing() { if (DEBUG) Log.d(mTag, "startDozing"); super.startDozing(); } private void requestDoze() { if (mHost != null) { mHost.requestDoze(this); } } private void requestPulse(boolean delayed) { private void requestPulse() { if (mHost != null) { mHost.requestPulse(delayed, this); mHost.requestPulse(this); } } Loading Loading @@ -222,24 +227,61 @@ public class DozeService extends DreamService { private void listenForNotifications(boolean listen) { if (mHost == null) return; if (listen) { resetNotificationResets(); mHost.addCallback(mHostCallback); } else { mHost.removeCallback(mHostCallback); } } private void rescheduleNotificationPulse() { private void resetNotificationResets() { if (DEBUG) Log.d(TAG, "resetNotificationResets"); mScheduleResetsRemaining = mDozeParameters.getPulseScheduleResets(); } private void updateNotificationPulse() { if (DEBUG) Log.d(TAG, "updateNotificationPulse"); if (!mDozeParameters.getPulseOnNotifications()) return; if (mScheduleResetsRemaining <= 0) { if (DEBUG) Log.d(TAG, "No more schedule resets remaining"); return; } final long now = System.currentTimeMillis(); if ((now - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) { if (DEBUG) Log.d(TAG, "Recently updated, not resetting schedule"); return; } mScheduleResetsRemaining--; if (DEBUG) Log.d(TAG, "mScheduleResetsRemaining = " + mScheduleResetsRemaining); mNotificationPulseTime = now; rescheduleNotificationPulse(true /*predicate*/); } private void rescheduleNotificationPulse(boolean predicate) { if (DEBUG) Log.d(TAG, "rescheduleNotificationPulse predicate=" + predicate); mAlarmManager.cancel(mNotificationPulseIntent); if (mNotificationLightOn) { if (!predicate) { if (DEBUG) Log.d(TAG, " don't reschedule: predicate is false"); return; } final PulseSchedule schedule = mDozeParameters.getPulseSchedule(); if (schedule == null) { if (DEBUG) Log.d(TAG, " don't reschedule: schedule is null"); return; } final long now = System.currentTimeMillis(); final long age = now - mNotificationPulseTime; final long period = mDozeParameters.getPulsePeriod(age); final long time = now + period; if (period > 0) { if (DEBUG) Log.d(TAG, "Scheduling pulse in " + period + " for " + new Date(time)); mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent); final long time = schedule.getNextTime(now, mNotificationPulseTime); if (time <= 0) { if (DEBUG) Log.d(TAG, " don't reschedule: time is " + time); return; } final long delta = time - now; if (delta <= 0) { if (DEBUG) Log.d(TAG, " don't reschedule: delta is " + delta); return; } if (DEBUG) Log.d(TAG, "Scheduling pulse in " + delta + "ms for " + new Date(time)); mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent); } private static String triggerEventToString(TriggerEvent event) { Loading Loading @@ -268,12 +310,12 @@ public class DozeService extends DreamService { public void onReceive(Context context, Intent intent) { if (PULSE_ACTION.equals(intent.getAction())) { if (DEBUG) Log.d(mTag, "Received pulse intent"); requestPulse(false /*delayed*/); requestPulse(); } if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) { if (DEBUG) Log.d(mTag, "Received notification pulse intent"); requestPulse(true /*delayed*/); rescheduleNotificationPulse(); requestPulse(); rescheduleNotificationPulse(mNotificationLightOn); } } }; Loading @@ -288,8 +330,7 @@ public class DozeService extends DreamService { @Override public void onBuzzBeepBlinked() { if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked"); mNotificationPulseTime = System.currentTimeMillis(); requestPulse(true /*delayed*/); updateNotificationPulse(); } @Override Loading @@ -298,10 +339,8 @@ public class DozeService extends DreamService { if (mNotificationLightOn == on) return; mNotificationLightOn = on; if (mNotificationLightOn) { mNotificationPulseTime = System.currentTimeMillis(); requestPulse(true /*delayed*/); updateNotificationPulse(); } rescheduleNotificationPulse(); } @Override Loading @@ -317,7 +356,7 @@ public class DozeService extends DreamService { void addCallback(Callback callback); void removeCallback(Callback callback); void requestDoze(DozeService dozeService); void requestPulse(boolean delayed, DozeService dozeService); void requestPulse(DozeService dozeService); void dozingStopped(DozeService dozeService); boolean isPowerSaveActive(); Loading @@ -332,13 +371,14 @@ public class DozeService extends DreamService { private class TriggerSensor extends TriggerEventListener { private final Sensor mSensor; private final boolean mConfigured; private final boolean mDebugVibrate; private boolean mEnabled; public TriggerSensor(int type, String sysPropConfig, int resConfig) { public TriggerSensor(int type, boolean configured, boolean debugVibrate) { mSensor = mSensors.getDefaultSensor(type); mConfigured = SystemProperties.getBoolean(sysPropConfig, mContext.getResources().getBoolean(resConfig)); mConfigured = configured; mDebugVibrate = debugVibrate; } public void setListening(boolean listen) { Loading @@ -354,13 +394,14 @@ public class DozeService extends DreamService { @Override public String toString() { return new StringBuilder("{mEnabled=").append(mEnabled).append(", mConfigured=") .append(mConfigured).append(", mSensor=").append(mSensor).append("}").toString(); .append(mConfigured).append(", mDebugVibrate=").append(mDebugVibrate) .append(", mSensor=").append(mSensor).append("}").toString(); } @Override public void onTrigger(TriggerEvent event) { if (DEBUG) Log.d(mTag, "onTrigger: " + triggerEventToString(event)); if (DEBUG) { if (mDebugVibrate) { final Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); if (v != null) { v.vibrate(1000, new AudioAttributes.Builder() Loading @@ -368,8 +409,9 @@ public class DozeService extends DreamService { .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build()); } } requestPulse(false /*delayed*/); requestPulse(); setListening(true); // reregister, this sensor only fires once resetNotificationResets(); } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +63 −29 Original line number Diff line number Diff line Loading @@ -25,17 +25,19 @@ import android.util.MathUtils; import com.android.systemui.R; import java.io.PrintWriter; import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DozeParameters { private static final String TAG = "DozeParameters"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int MAX_DURATION = 10 * 1000; private final Context mContext; private StepFunction mPulsePeriodFunction; private static PulseSchedule sPulseSchedule; public DozeParameters(Context context) { mContext = context; Loading @@ -43,12 +45,22 @@ public class DozeParameters { public void dump(PrintWriter pw) { pw.println(" DozeParameters:"); pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported()); pw.print(" getPulseDuration(): "); pw.println(getPulseDuration()); pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration()); pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration()); pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration()); pw.print(" getPulseStartDelay(): "); pw.println(getPulseStartDelay()); pw.print(" getPulsePeriodFunction(): "); pw.println(getPulsePeriodFunction()); pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion()); pw.print(" getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion()); pw.print(" getPulseOnPickup(): "); pw.println(getPulseOnPickup()); pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup()); pw.print(" getPulseOnNotifications(): "); pw.println(getPulseOnNotifications()); pw.print(" getPulseSchedule(): "); pw.println(getPulseSchedule()); pw.print(" getPulseScheduleResets(): "); pw.println(getPulseScheduleResets()); } public boolean getDisplayStateSupported() { return getBoolean("doze.display.supported", R.bool.doze_display_state_supported); } public int getPulseDuration() { Loading @@ -67,20 +79,40 @@ public class DozeParameters { return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out); } public int getPulseStartDelay() { return getInt("doze.pulse.delay", R.integer.doze_pulse_delay); public boolean getPulseOnSigMotion() { return getBoolean("doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion); } public boolean getVibrateOnSigMotion() { return SystemProperties.getBoolean("doze.vibrate.sigmotion", false); } public boolean getPulseOnPickup() { return getBoolean("doze.pulse.pickup", R.bool.doze_pulse_on_pick_up); } public boolean getVibrateOnPickup() { return SystemProperties.getBoolean("doze.vibrate.pickup", false); } public boolean getPulseOnNotifications() { return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications); } public long getPulsePeriod(long age) { final String spec = getPulsePeriodFunction(); if (mPulsePeriodFunction == null || !mPulsePeriodFunction.mSpec.equals(spec)) { mPulsePeriodFunction = StepFunction.parse(spec); public PulseSchedule getPulseSchedule() { final String spec = getString("doze.pulse.schedule", R.string.doze_pulse_schedule); if (sPulseSchedule == null || !sPulseSchedule.mSpec.equals(spec)) { sPulseSchedule = PulseSchedule.parse(spec); } return mPulsePeriodFunction != null ? mPulsePeriodFunction.evaluate(age) : 0; return sPulseSchedule; } private String getPulsePeriodFunction() { return getString("doze.pulse.period.function", R.string.doze_pulse_period_function); public int getPulseScheduleResets() { return getInt("doze.pulse.schedule.resets", R.integer.doze_pulse_schedule_resets); } private boolean getBoolean(String propName, int resId) { return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId)); } private int getInt(String propName, int resId) { Loading @@ -92,29 +124,25 @@ public class DozeParameters { return SystemProperties.get(propName, mContext.getString(resId)); } private static class StepFunction { private static final Pattern PATTERN = Pattern.compile("(\\d+?)(:(\\d+?))?", 0); public static class PulseSchedule { private static final Pattern PATTERN = Pattern.compile("(\\d+?)s", 0); private String mSpec; private long[] mSteps; private long[] mValues; private long mDefault; private int[] mSchedule; public static StepFunction parse(String spec) { public static PulseSchedule parse(String spec) { if (TextUtils.isEmpty(spec)) return null; try { final StepFunction rt = new StepFunction(); final PulseSchedule rt = new PulseSchedule(); rt.mSpec = spec; final String[] tokens = spec.split(","); rt.mSteps = new long[tokens.length - 1]; rt.mValues = new long[tokens.length - 1]; for (int i = 0; i < tokens.length - 1; i++) { rt.mSchedule = new int[tokens.length]; for (int i = 0; i < tokens.length; i++) { final Matcher m = PATTERN.matcher(tokens[i]); if (!m.matches()) throw new IllegalArgumentException("Bad token: " + tokens[i]); rt.mSteps[i] = Long.parseLong(m.group(1)); rt.mValues[i] = Long.parseLong(m.group(3)); rt.mSchedule[i] = Integer.parseInt(m.group(1)); } rt.mDefault = Long.parseLong(tokens[tokens.length - 1]); if (DEBUG) Log.d(TAG, "Parsed spec [" + spec + "] as: " + rt); return rt; } catch (RuntimeException e) { Log.w(TAG, "Error parsing spec: " + spec, e); Loading @@ -122,11 +150,17 @@ public class DozeParameters { } } public long evaluate(long x) { for (int i = 0; i < mSteps.length; i++) { if (x < mSteps[i]) return mValues[i]; @Override public String toString() { return Arrays.toString(mSchedule); } public long getNextTime(long now, long notificationTime) { for (int i = 0; i < mSchedule.length; i++) { final long time = notificationTime + mSchedule[i] * 1000; if (time > now) return time; } return mDefault; return 0; } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +5 −6 Original line number Diff line number Diff line Loading @@ -4083,11 +4083,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override public void requestPulse(boolean delayed, DozeService dozeService) { public void requestPulse(DozeService dozeService) { if (dozeService == null) return; dozeService.stayAwake(PROCESSING_TIME); mHandler.obtainMessage(H.REQUEST_PULSE, delayed ? 1 : 0, 0, dozeService) .sendToTarget(); mHandler.obtainMessage(H.REQUEST_PULSE, dozeService).sendToTarget(); } @Override Loading @@ -4110,9 +4109,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mCurrentDozeService.startDozing(); } private void handleRequestPulse(boolean delayed, DozeService dozeService) { private void handleRequestPulse(DozeService dozeService) { if (!dozeService.equals(mCurrentDozeService)) return; final long stayAwake = mScrimController.pulse(delayed); final long stayAwake = mScrimController.pulse(); mCurrentDozeService.stayAwake(stayAwake); } Loading @@ -4136,7 +4135,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (msg.what == REQUEST_DOZE) { handleRequestDoze((DozeService) msg.obj); } else if (msg.what == REQUEST_PULSE) { handleRequestPulse(msg.arg1 != 0, (DozeService) msg.obj); handleRequestPulse((DozeService) msg.obj); } else if (msg.what == DOZING_STOPPED) { handleDozingStopped((DozeService) msg.obj); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +6 −6 Original line number Diff line number Diff line Loading @@ -129,20 +129,20 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { if (!mDozing) { cancelPulsing(); mAnimateChange = true; } else { mAnimateChange = false; } scheduleUpdate(); } /** When dozing, fade screen contents in and out using the front scrim. */ public long pulse(boolean delayed) { public long pulse() { if (!mDozing) return 0; final long now = System.currentTimeMillis(); if (DEBUG) Log.d(TAG, "pulse delayed=" + delayed + " mPulseEndTime=" + mPulseEndTime + " now=" + now); if (DEBUG) Log.d(TAG, "pulse mPulseEndTime=" + mPulseEndTime + " now=" + now); if (mPulseEndTime != 0 && mPulseEndTime > now) return mPulseEndTime - now; final long delay = delayed ? mDozeParameters.getPulseStartDelay() : 0; mScrimInFront.postDelayed(mPulseIn, delay); mPulseEndTime = now + delay + mDozeParameters.getPulseDuration(); mScrimInFront.post(mPulseIn); mPulseEndTime = now + mDozeParameters.getPulseDuration(); return mPulseEndTime - now; } Loading