Merge "Use non-wakeup alarm for delay constraint."
This commit is contained in:
@@ -232,6 +232,8 @@ message ConstantsProto {
|
|||||||
// Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
|
// Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
|
||||||
// ready now.
|
// ready now.
|
||||||
optional bool skip_not_ready_jobs = 1;
|
optional bool skip_not_ready_jobs = 1;
|
||||||
|
// Whether or not TimeController will use a non-wakeup alarm for delay constraints.
|
||||||
|
optional bool use_non_wakeup_alarm_for_delay = 2;
|
||||||
}
|
}
|
||||||
optional TimeController time_controller = 25;
|
optional TimeController time_controller = 25;
|
||||||
|
|
||||||
|
|||||||
@@ -325,8 +325,7 @@ public final class TimeController extends StateController {
|
|||||||
&& !wouldBeReadyWithConstraintLocked(
|
&& !wouldBeReadyWithConstraintLocked(
|
||||||
job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
|
job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.i(TAG,
|
Slog.i(TAG, "Skipping " + job + " because delay won't make it ready.");
|
||||||
"Skipping " + job + " because delay won't make it ready.");
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -385,7 +384,8 @@ public final class TimeController extends StateController {
|
|||||||
/**
|
/**
|
||||||
* Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
|
* Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
|
||||||
* delay will expire.
|
* delay will expire.
|
||||||
* This alarm <b>will</b> wake up the phone.
|
* This alarm <b>will not</b> wake up the phone if
|
||||||
|
* {@link TcConstants#USE_NON_WAKEUP_ALARM_FOR_DELAY} is true.
|
||||||
*/
|
*/
|
||||||
private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) {
|
private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) {
|
||||||
alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
|
alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
|
||||||
@@ -393,8 +393,11 @@ public final class TimeController extends StateController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
|
mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
|
||||||
updateAlarmWithListenerLocked(DELAY_TAG, mNextDelayExpiredListener,
|
final int alarmType =
|
||||||
mNextDelayExpiredElapsedMillis, ws);
|
mTcConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY
|
||||||
|
? AlarmManager.ELAPSED_REALTIME : AlarmManager.ELAPSED_REALTIME_WAKEUP;
|
||||||
|
updateAlarmWithListenerLocked(DELAY_TAG, alarmType,
|
||||||
|
mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis, ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -408,16 +411,16 @@ public final class TimeController extends StateController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
|
mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
|
||||||
updateAlarmWithListenerLocked(DEADLINE_TAG, mDeadlineExpiredListener,
|
updateAlarmWithListenerLocked(DEADLINE_TAG, AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||||
mNextJobExpiredElapsedMillis, ws);
|
mDeadlineExpiredListener, mNextJobExpiredElapsedMillis, ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long maybeAdjustAlarmTime(long proposedAlarmTimeElapsedMillis) {
|
private long maybeAdjustAlarmTime(long proposedAlarmTimeElapsedMillis) {
|
||||||
return Math.max(proposedAlarmTimeElapsedMillis, sElapsedRealtimeClock.millis());
|
return Math.max(proposedAlarmTimeElapsedMillis, sElapsedRealtimeClock.millis());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAlarmWithListenerLocked(String tag, OnAlarmListener listener,
|
private void updateAlarmWithListenerLocked(String tag, @AlarmManager.AlarmType int alarmType,
|
||||||
long alarmTimeElapsed, WorkSource ws) {
|
OnAlarmListener listener, long alarmTimeElapsed, WorkSource ws) {
|
||||||
ensureAlarmServiceLocked();
|
ensureAlarmServiceLocked();
|
||||||
if (alarmTimeElapsed == Long.MAX_VALUE) {
|
if (alarmTimeElapsed == Long.MAX_VALUE) {
|
||||||
mAlarmService.cancel(listener);
|
mAlarmService.cancel(listener);
|
||||||
@@ -425,7 +428,7 @@ public final class TimeController extends StateController {
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed);
|
Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed);
|
||||||
}
|
}
|
||||||
mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTimeElapsed,
|
mAlarmService.set(alarmType, alarmTimeElapsed,
|
||||||
AlarmManager.WINDOW_HEURISTIC, 0, tag, listener, null, ws);
|
AlarmManager.WINDOW_HEURISTIC, 0, tag, listener, null, ws);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,8 +467,11 @@ public final class TimeController extends StateController {
|
|||||||
private final KeyValueListParser mParser = new KeyValueListParser(',');
|
private final KeyValueListParser mParser = new KeyValueListParser(',');
|
||||||
|
|
||||||
private static final String KEY_SKIP_NOT_READY_JOBS = "skip_not_ready_jobs";
|
private static final String KEY_SKIP_NOT_READY_JOBS = "skip_not_ready_jobs";
|
||||||
|
private static final String KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY =
|
||||||
|
"use_non_wakeup_delay_alarm";
|
||||||
|
|
||||||
private static final boolean DEFAULT_SKIP_NOT_READY_JOBS = true;
|
private static final boolean DEFAULT_SKIP_NOT_READY_JOBS = true;
|
||||||
|
private static final boolean DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
|
* Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
|
||||||
@@ -473,6 +479,12 @@ public final class TimeController extends StateController {
|
|||||||
*/
|
*/
|
||||||
public boolean SKIP_NOT_READY_JOBS = DEFAULT_SKIP_NOT_READY_JOBS;
|
public boolean SKIP_NOT_READY_JOBS = DEFAULT_SKIP_NOT_READY_JOBS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
|
||||||
|
* ready now.
|
||||||
|
*/
|
||||||
|
public boolean USE_NON_WAKEUP_ALARM_FOR_DELAY = DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a content observer.
|
* Creates a content observer.
|
||||||
*
|
*
|
||||||
@@ -510,6 +522,12 @@ public final class TimeController extends StateController {
|
|||||||
recheckAlarmsLocked();
|
recheckAlarmsLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USE_NON_WAKEUP_ALARM_FOR_DELAY = mParser.getBoolean(
|
||||||
|
KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY, DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY);
|
||||||
|
// Intentionally not calling checkExpiredDelaysAndResetAlarm() here. There's no need to
|
||||||
|
// iterate through the entire list again for this constant change. The next delay alarm
|
||||||
|
// that is set will make use of the new constant value.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dump(IndentingPrintWriter pw) {
|
private void dump(IndentingPrintWriter pw) {
|
||||||
@@ -517,12 +535,16 @@ public final class TimeController extends StateController {
|
|||||||
pw.println("TimeController:");
|
pw.println("TimeController:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
pw.printPair(KEY_SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS).println();
|
pw.printPair(KEY_SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS).println();
|
||||||
|
pw.printPair(KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY,
|
||||||
|
USE_NON_WAKEUP_ALARM_FOR_DELAY).println();
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dump(ProtoOutputStream proto) {
|
private void dump(ProtoOutputStream proto) {
|
||||||
final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
|
final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
|
||||||
proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS);
|
proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS);
|
||||||
|
proto.write(ConstantsProto.TimeController.USE_NON_WAKEUP_ALARM_FOR_DELAY,
|
||||||
|
USE_NON_WAKEUP_ALARM_FOR_DELAY);
|
||||||
proto.end(tcToken);
|
proto.end(tcToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -529,6 +529,46 @@ public class TimeControllerTest {
|
|||||||
runTestCheckExpiredDelaysAndResetAlarm();
|
runTestCheckExpiredDelaysAndResetAlarm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJobDelayWakeupAlarmToggling() {
|
||||||
|
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
|
||||||
|
|
||||||
|
JobStatus job = createJobStatus(
|
||||||
|
"testMaybeStartTrackingJobLocked_DeadlineReverseOrder",
|
||||||
|
createJob().setMinimumLatency(HOUR_IN_MILLIS));
|
||||||
|
|
||||||
|
doReturn(true).when(mTimeController)
|
||||||
|
.wouldBeReadyWithConstraintLocked(eq(job), anyInt());
|
||||||
|
|
||||||
|
// Starting off with using a wakeup alarm.
|
||||||
|
mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = false;
|
||||||
|
InOrder inOrder = inOrder(mAlarmManager);
|
||||||
|
|
||||||
|
mTimeController.maybeStartTrackingJobLocked(job, null);
|
||||||
|
inOrder.verify(mAlarmManager, times(1))
|
||||||
|
.set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(now + HOUR_IN_MILLIS), anyLong(),
|
||||||
|
anyLong(),
|
||||||
|
eq(TAG_DELAY), any(), any(), any());
|
||||||
|
|
||||||
|
// Use a non wakeup alarm.
|
||||||
|
mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = true;
|
||||||
|
|
||||||
|
mTimeController.maybeStartTrackingJobLocked(job, null);
|
||||||
|
inOrder.verify(mAlarmManager, times(1))
|
||||||
|
.set(eq(AlarmManager.ELAPSED_REALTIME), eq(now + HOUR_IN_MILLIS), anyLong(),
|
||||||
|
anyLong(), eq(TAG_DELAY),
|
||||||
|
any(), any(), any());
|
||||||
|
|
||||||
|
// Back off, use a wakeup alarm.
|
||||||
|
mConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY = false;
|
||||||
|
|
||||||
|
mTimeController.maybeStartTrackingJobLocked(job, null);
|
||||||
|
inOrder.verify(mAlarmManager, times(1))
|
||||||
|
.set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), eq(now + HOUR_IN_MILLIS), anyLong(),
|
||||||
|
anyLong(),
|
||||||
|
eq(TAG_DELAY), any(), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() {
|
public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() {
|
||||||
mConstants.SKIP_NOT_READY_JOBS = true;
|
mConstants.SKIP_NOT_READY_JOBS = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user