Ambient: Pulse for every noisy notification exactly once
am: d13602f1e7
Change-Id: I45cf1a129ae53d251bd033a8f15618b3868cd351
This commit is contained in:
@@ -218,12 +218,6 @@
|
|||||||
<!-- Doze: should notifications be used as a pulse signal? -->
|
<!-- Doze: should notifications be used as a pulse signal? -->
|
||||||
<bool name="doze_pulse_on_notifications">true</bool>
|
<bool name="doze_pulse_on_notifications">true</bool>
|
||||||
|
|
||||||
<!-- Doze: when to pulse after a buzzworthy notification arrives -->
|
|
||||||
<string name="doze_pulse_schedule" translatable="false">10s,30s,60s</string>
|
|
||||||
|
|
||||||
<!-- Doze: maximum number of times the notification pulse schedule can be reset -->
|
|
||||||
<integer name="doze_pulse_schedule_resets">2</integer>
|
|
||||||
|
|
||||||
<!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
|
<!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
|
||||||
<integer name="doze_pickup_vibration_threshold">2000</integer>
|
<integer name="doze_pickup_vibration_threshold">2000</integer>
|
||||||
|
|
||||||
@@ -253,7 +247,7 @@
|
|||||||
<integer name="doze_pulse_duration_in_pickup">130</integer>
|
<integer name="doze_pulse_duration_in_pickup">130</integer>
|
||||||
|
|
||||||
<!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
|
<!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
|
||||||
<integer name="doze_pulse_duration_visible">3000</integer>
|
<integer name="doze_pulse_duration_visible">6000</integer>
|
||||||
|
|
||||||
<!-- Doze: pulse parameter - how long does it take to fade out? -->
|
<!-- Doze: pulse parameter - how long does it take to fade out? -->
|
||||||
<integer name="doze_pulse_duration_out">600</integer>
|
<integer name="doze_pulse_duration_out">600</integer>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class DozeLog {
|
|||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
private static final boolean ENABLED = true;
|
private static final boolean ENABLED = true;
|
||||||
private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
|
private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
|
||||||
private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
|
static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
|
||||||
|
|
||||||
private static final int PULSE_REASONS = 4;
|
private static final int PULSE_REASONS = 4;
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.doze;
|
package com.android.systemui.doze;
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.app.UiModeManager;
|
import android.app.UiModeManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -43,7 +41,6 @@ import com.android.internal.logging.MetricsLogger;
|
|||||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||||
import com.android.systemui.SystemUIApplication;
|
import com.android.systemui.SystemUIApplication;
|
||||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||||
import com.android.systemui.statusbar.phone.DozeParameters.PulseSchedule;
|
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -55,19 +52,6 @@ public class DozeService extends DreamService {
|
|||||||
|
|
||||||
private static final String ACTION_BASE = "com.android.systemui.doze";
|
private static final String ACTION_BASE = "com.android.systemui.doze";
|
||||||
private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
|
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_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 String mTag = String.format(TAG + ".%08x", hashCode());
|
||||||
private final Context mContext = this;
|
private final Context mContext = this;
|
||||||
@@ -80,19 +64,14 @@ public class DozeService extends DreamService {
|
|||||||
private TriggerSensor mPickupSensor;
|
private TriggerSensor mPickupSensor;
|
||||||
private PowerManager mPowerManager;
|
private PowerManager mPowerManager;
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
private AlarmManager mAlarmManager;
|
|
||||||
private UiModeManager mUiModeManager;
|
private UiModeManager mUiModeManager;
|
||||||
private boolean mDreaming;
|
private boolean mDreaming;
|
||||||
private boolean mPulsing;
|
private boolean mPulsing;
|
||||||
private boolean mBroadcastReceiverRegistered;
|
private boolean mBroadcastReceiverRegistered;
|
||||||
private boolean mDisplayStateSupported;
|
private boolean mDisplayStateSupported;
|
||||||
private boolean mNotificationLightOn;
|
|
||||||
private boolean mPowerSaveActive;
|
private boolean mPowerSaveActive;
|
||||||
private boolean mCarMode;
|
private boolean mCarMode;
|
||||||
private long mNotificationPulseTime;
|
private long mNotificationPulseTime;
|
||||||
private long mLastScheduleResetTime;
|
|
||||||
private long mEarliestPulseDueToLight;
|
|
||||||
private int mScheduleResetsRemaining;
|
|
||||||
|
|
||||||
public DozeService() {
|
public DozeService() {
|
||||||
if (DEBUG) Log.d(mTag, "new DozeService()");
|
if (DEBUG) Log.d(mTag, "new DozeService()");
|
||||||
@@ -110,11 +89,11 @@ public class DozeService extends DreamService {
|
|||||||
pw.print(" mSigMotionSensor: "); pw.println(mSigMotionSensor);
|
pw.print(" mSigMotionSensor: "); pw.println(mSigMotionSensor);
|
||||||
pw.print(" mPickupSensor:"); pw.println(mPickupSensor);
|
pw.print(" mPickupSensor:"); pw.println(mPickupSensor);
|
||||||
pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
|
pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
|
||||||
pw.print(" mNotificationLightOn: "); pw.println(mNotificationLightOn);
|
|
||||||
pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive);
|
pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive);
|
||||||
pw.print(" mCarMode: "); pw.println(mCarMode);
|
pw.print(" mCarMode: "); pw.println(mCarMode);
|
||||||
pw.print(" mNotificationPulseTime: "); pw.println(mNotificationPulseTime);
|
pw.print(" mNotificationPulseTime: "); pw.println(
|
||||||
pw.print(" mScheduleResetsRemaining: "); pw.println(mScheduleResetsRemaining);
|
DozeLog.FORMAT.format(new Date(mNotificationPulseTime
|
||||||
|
- SystemClock.elapsedRealtime() + System.currentTimeMillis())));
|
||||||
mDozeParameters.dump(pw);
|
mDozeParameters.dump(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +120,6 @@ public class DozeService extends DreamService {
|
|||||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||||
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||||
mWakeLock.setReferenceCounted(true);
|
mWakeLock.setReferenceCounted(true);
|
||||||
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
|
|
||||||
mDisplayStateSupported = mDozeParameters.getDisplayStateSupported();
|
mDisplayStateSupported = mDozeParameters.getDisplayStateSupported();
|
||||||
mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
|
mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
|
||||||
turnDisplayOff();
|
turnDisplayOff();
|
||||||
@@ -176,8 +154,6 @@ public class DozeService extends DreamService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mDreaming = true;
|
mDreaming = true;
|
||||||
rescheduleNotificationPulse(false /*predicate*/); // cancel any pending pulse alarms
|
|
||||||
mEarliestPulseDueToLight = System.currentTimeMillis() + EARLIEST_LIGHT_PULSE_AFTER_START_MS;
|
|
||||||
listenForPulseSignals(true);
|
listenForPulseSignals(true);
|
||||||
|
|
||||||
// Ask the host to get things ready to start dozing.
|
// Ask the host to get things ready to start dozing.
|
||||||
@@ -316,7 +292,6 @@ public class DozeService extends DreamService {
|
|||||||
private void listenForBroadcasts(boolean listen) {
|
private void listenForBroadcasts(boolean listen) {
|
||||||
if (listen) {
|
if (listen) {
|
||||||
final IntentFilter filter = new IntentFilter(PULSE_ACTION);
|
final IntentFilter filter = new IntentFilter(PULSE_ACTION);
|
||||||
filter.addAction(NOTIFICATION_PULSE_ACTION);
|
|
||||||
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
|
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
|
||||||
mContext.registerReceiver(mBroadcastReceiver, filter);
|
mContext.registerReceiver(mBroadcastReceiver, filter);
|
||||||
mBroadcastReceiverRegistered = true;
|
mBroadcastReceiverRegistered = true;
|
||||||
@@ -330,93 +305,17 @@ public class DozeService extends DreamService {
|
|||||||
|
|
||||||
private void listenForNotifications(boolean listen) {
|
private void listenForNotifications(boolean listen) {
|
||||||
if (listen) {
|
if (listen) {
|
||||||
resetNotificationResets();
|
|
||||||
mHost.addCallback(mHostCallback);
|
mHost.addCallback(mHostCallback);
|
||||||
|
|
||||||
// Continue to pulse for existing LEDs.
|
|
||||||
mNotificationLightOn = mHost.isNotificationLightOn();
|
|
||||||
if (mNotificationLightOn) {
|
|
||||||
updateNotificationPulseDueToLight();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mHost.removeCallback(mHostCallback);
|
mHost.removeCallback(mHostCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetNotificationResets() {
|
private void requestNotificationPulse() {
|
||||||
if (DEBUG) Log.d(mTag, "resetNotificationResets");
|
if (DEBUG) Log.d(mTag, "requestNotificationPulse");
|
||||||
mScheduleResetsRemaining = mDozeParameters.getPulseScheduleResets();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (!mDozeParameters.getPulseOnNotifications()) return;
|
||||||
if (mScheduleResetsRemaining <= 0) {
|
mNotificationPulseTime = SystemClock.elapsedRealtime();
|
||||||
if (DEBUG) Log.d(mTag, "No more schedule resets remaining");
|
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
|
||||||
return;
|
|
||||||
}
|
|
||||||
final long pulseDuration = mDozeParameters.getPulseDuration(false /*pickup*/);
|
|
||||||
boolean pulseImmediately = System.currentTimeMillis() >= notificationTimeMs;
|
|
||||||
if ((notificationTimeMs - mLastScheduleResetTime) >= pulseDuration) {
|
|
||||||
mScheduleResetsRemaining--;
|
|
||||||
mLastScheduleResetTime = notificationTimeMs;
|
|
||||||
} else if (!pulseImmediately){
|
|
||||||
if (DEBUG) Log.d(mTag, "Recently updated, not resetting schedule");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (DEBUG) Log.d(mTag, "mScheduleResetsRemaining = " + mScheduleResetsRemaining);
|
|
||||||
mNotificationPulseTime = notificationTimeMs;
|
|
||||||
if (pulseImmediately) {
|
|
||||||
DozeLog.traceNotificationPulse(mContext, 0);
|
|
||||||
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
|
|
||||||
}
|
|
||||||
// schedule the rest of the pulses
|
|
||||||
rescheduleNotificationPulse(true /*predicate*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PendingIntent notificationPulseIntent(long instance) {
|
|
||||||
return PendingIntent.getBroadcast(mContext, 0,
|
|
||||||
new Intent(NOTIFICATION_PULSE_ACTION)
|
|
||||||
.setPackage(getPackageName())
|
|
||||||
.putExtra(EXTRA_INSTANCE, instance)
|
|
||||||
.setFlags(Intent.FLAG_RECEIVER_FOREGROUND),
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rescheduleNotificationPulse(boolean predicate) {
|
|
||||||
if (DEBUG) Log.d(mTag, "rescheduleNotificationPulse predicate=" + predicate);
|
|
||||||
final PendingIntent notificationPulseIntent = notificationPulseIntent(0);
|
|
||||||
mAlarmManager.cancel(notificationPulseIntent);
|
|
||||||
if (!predicate) {
|
|
||||||
if (DEBUG) Log.d(mTag, " don't reschedule: predicate is false");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final PulseSchedule schedule = mDozeParameters.getPulseSchedule();
|
|
||||||
if (schedule == null) {
|
|
||||||
if (DEBUG) Log.d(mTag, " don't reschedule: schedule is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final long now = System.currentTimeMillis();
|
|
||||||
final long time = schedule.getNextTime(now, mNotificationPulseTime);
|
|
||||||
if (time <= 0) {
|
|
||||||
if (DEBUG) Log.d(mTag, " don't reschedule: time is " + time);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final long delta = time - now;
|
|
||||||
if (delta <= 0) {
|
|
||||||
if (DEBUG) Log.d(mTag, " don't reschedule: delta is " + delta);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final long instance = time - mNotificationPulseTime;
|
|
||||||
if (DEBUG) Log.d(mTag, "Scheduling pulse " + instance + " in " + delta + "ms for "
|
|
||||||
+ new Date(time));
|
|
||||||
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, notificationPulseIntent(instance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String triggerEventToString(TriggerEvent event) {
|
private static String triggerEventToString(TriggerEvent event) {
|
||||||
@@ -439,13 +338,6 @@ public class DozeService extends DreamService {
|
|||||||
if (DEBUG) Log.d(mTag, "Received pulse intent");
|
if (DEBUG) Log.d(mTag, "Received pulse intent");
|
||||||
requestPulse(DozeLog.PULSE_REASON_INTENT);
|
requestPulse(DozeLog.PULSE_REASON_INTENT);
|
||||||
}
|
}
|
||||||
if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
|
|
||||||
final long instance = intent.getLongExtra(EXTRA_INSTANCE, -1);
|
|
||||||
if (DEBUG) Log.d(mTag, "Received notification pulse intent instance=" + instance);
|
|
||||||
DozeLog.traceNotificationPulse(mContext, instance);
|
|
||||||
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
|
|
||||||
rescheduleNotificationPulse(mNotificationLightOn);
|
|
||||||
}
|
|
||||||
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
|
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
|
||||||
mCarMode = true;
|
mCarMode = true;
|
||||||
if (mCarMode && mDreaming) {
|
if (mCarMode && mDreaming) {
|
||||||
@@ -465,17 +357,13 @@ public class DozeService extends DreamService {
|
|||||||
@Override
|
@Override
|
||||||
public void onBuzzBeepBlinked() {
|
public void onBuzzBeepBlinked() {
|
||||||
if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
|
if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
|
||||||
updateNotificationPulse(System.currentTimeMillis());
|
requestNotificationPulse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotificationLight(boolean on) {
|
public void onNotificationLight(boolean on) {
|
||||||
if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on);
|
if (DEBUG) Log.d(mTag, "onNotificationLight (noop) on=" + on);
|
||||||
if (mNotificationLightOn == on) return;
|
// noop for now
|
||||||
mNotificationLightOn = on;
|
|
||||||
if (mNotificationLightOn) {
|
|
||||||
updateNotificationPulseDueToLight();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -564,17 +452,12 @@ public class DozeService extends DreamService {
|
|||||||
requestPulse(mPulseReason, sensorPerformsProxCheck);
|
requestPulse(mPulseReason, sensorPerformsProxCheck);
|
||||||
updateListener(); // reregister, this sensor only fires once
|
updateListener(); // reregister, this sensor only fires once
|
||||||
|
|
||||||
// reset the notification pulse schedule, but only if we think we were not triggered
|
// record pickup gesture, also keep track of whether we might have been triggered
|
||||||
// by a notification-related vibration
|
// by recent vibration.
|
||||||
final long timeSinceNotification = System.currentTimeMillis()
|
final long timeSinceNotification = SystemClock.elapsedRealtime()
|
||||||
- mNotificationPulseTime;
|
- mNotificationPulseTime;
|
||||||
final boolean withinVibrationThreshold =
|
final boolean withinVibrationThreshold =
|
||||||
timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
|
timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
|
||||||
if (withinVibrationThreshold) {
|
|
||||||
if (DEBUG) Log.d(mTag, "Not resetting schedule, recent notification");
|
|
||||||
} else {
|
|
||||||
resetNotificationResets();
|
|
||||||
}
|
|
||||||
if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
|
if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
|
||||||
DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
|
DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ public class DozeParameters {
|
|||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
private static PulseSchedule sPulseSchedule;
|
|
||||||
|
|
||||||
private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
|
private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
|
||||||
|
|
||||||
public DozeParameters(Context context) {
|
public DozeParameters(Context context) {
|
||||||
@@ -61,8 +59,6 @@ public class DozeParameters {
|
|||||||
pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
|
pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
|
||||||
pw.print(" getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
|
pw.print(" getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
|
||||||
pw.print(" getPulseOnNotifications(): "); pw.println(getPulseOnNotifications());
|
pw.print(" getPulseOnNotifications(): "); pw.println(getPulseOnNotifications());
|
||||||
pw.print(" getPulseSchedule(): "); pw.println(getPulseSchedule());
|
|
||||||
pw.print(" getPulseScheduleResets(): "); pw.println(getPulseScheduleResets());
|
|
||||||
pw.print(" getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
|
pw.print(" getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
|
||||||
pw.print(" getPickupSubtypePerformsProxCheck(): ");pw.println(
|
pw.print(" getPickupSubtypePerformsProxCheck(): ");pw.println(
|
||||||
dumpPickupSubtypePerformsProxCheck());
|
dumpPickupSubtypePerformsProxCheck());
|
||||||
@@ -126,18 +122,6 @@ public class DozeParameters {
|
|||||||
return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications);
|
return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 sPulseSchedule;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPulseScheduleResets() {
|
|
||||||
return getInt("doze.pulse.schedule.resets", R.integer.doze_pulse_schedule_resets);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPickupVibrationThreshold() {
|
public int getPickupVibrationThreshold() {
|
||||||
return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
|
return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
|
||||||
}
|
}
|
||||||
@@ -249,44 +233,4 @@ public class DozeParameters {
|
|||||||
return (mIsIn.get(value, mDefaultIsIn));
|
return (mIsIn.get(value, mDefaultIsIn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PulseSchedule {
|
|
||||||
private static final Pattern PATTERN = Pattern.compile("(\\d+?)s", 0);
|
|
||||||
|
|
||||||
private String mSpec;
|
|
||||||
private int[] mSchedule;
|
|
||||||
|
|
||||||
public static PulseSchedule parse(String spec) {
|
|
||||||
if (TextUtils.isEmpty(spec)) return null;
|
|
||||||
try {
|
|
||||||
final PulseSchedule rt = new PulseSchedule();
|
|
||||||
rt.mSpec = spec;
|
|
||||||
final String[] tokens = spec.split(",");
|
|
||||||
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.mSchedule[i] = Integer.parseInt(m.group(1));
|
|
||||||
}
|
|
||||||
if (DEBUG) Log.d(TAG, "Parsed spec [" + spec + "] as: " + rt);
|
|
||||||
return rt;
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Log.w(TAG, "Error parsing spec: " + spec, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user