Merge "Remove TimeController constants."
This commit is contained in:
committed by
Android (Google) Code Review
commit
dc91aaab2d
@@ -18,28 +18,20 @@ package com.android.server.job.controllers;
|
|||||||
|
|
||||||
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
|
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.AlarmManager.OnAlarmListener;
|
import android.app.AlarmManager.OnAlarmListener;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.ContentObserver;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.WorkSource;
|
import android.os.WorkSource;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.IndentingPrintWriter;
|
import android.util.IndentingPrintWriter;
|
||||||
import android.util.KeyValueListParser;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.server.job.ConstantsProto;
|
|
||||||
import com.android.server.job.JobSchedulerService;
|
import com.android.server.job.JobSchedulerService;
|
||||||
import com.android.server.job.StateControllerProto;
|
import com.android.server.job.StateControllerProto;
|
||||||
|
|
||||||
@@ -63,9 +55,6 @@ public final class TimeController extends StateController {
|
|||||||
/** Delay alarm tag for logging purposes */
|
/** Delay alarm tag for logging purposes */
|
||||||
private final String DELAY_TAG = "*job.delay*";
|
private final String DELAY_TAG = "*job.delay*";
|
||||||
|
|
||||||
private final Handler mHandler;
|
|
||||||
private final TcConstants mTcConstants;
|
|
||||||
|
|
||||||
private long mNextJobExpiredElapsedMillis;
|
private long mNextJobExpiredElapsedMillis;
|
||||||
private long mNextDelayExpiredElapsedMillis;
|
private long mNextDelayExpiredElapsedMillis;
|
||||||
|
|
||||||
@@ -81,14 +70,6 @@ public final class TimeController extends StateController {
|
|||||||
mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
|
mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
|
||||||
mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
|
mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
|
||||||
mChainedAttributionEnabled = mService.isChainedAttributionEnabled();
|
mChainedAttributionEnabled = mService.isChainedAttributionEnabled();
|
||||||
|
|
||||||
mHandler = new Handler(mContext.getMainLooper());
|
|
||||||
mTcConstants = new TcConstants(mHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSystemServicesReady() {
|
|
||||||
mTcConstants.start(mContext.getContentResolver());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -372,8 +353,7 @@ 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 not</b> wake up the phone if
|
* This alarm <b>will not</b> wake up the phone.
|
||||||
* {@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);
|
||||||
@@ -381,10 +361,7 @@ public final class TimeController extends StateController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
|
mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
|
||||||
final int alarmType =
|
updateAlarmWithListenerLocked(DELAY_TAG, AlarmManager.ELAPSED_REALTIME,
|
||||||
mTcConstants.USE_NON_WAKEUP_ALARM_FOR_DELAY
|
|
||||||
? AlarmManager.ELAPSED_REALTIME : AlarmManager.ELAPSED_REALTIME_WAKEUP;
|
|
||||||
updateAlarmWithListenerLocked(DELAY_TAG, alarmType,
|
|
||||||
mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis, ws);
|
mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis, ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,80 +420,6 @@ public final class TimeController extends StateController {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
class TcConstants extends ContentObserver {
|
|
||||||
private ContentResolver mResolver;
|
|
||||||
private final KeyValueListParser mParser = new KeyValueListParser(',');
|
|
||||||
|
|
||||||
private static final String KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY =
|
|
||||||
"use_non_wakeup_delay_alarm";
|
|
||||||
|
|
||||||
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
|
|
||||||
* ready now.
|
|
||||||
*/
|
|
||||||
public boolean USE_NON_WAKEUP_ALARM_FOR_DELAY = DEFAULT_USE_NON_WAKEUP_ALARM_FOR_DELAY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a content observer.
|
|
||||||
*
|
|
||||||
* @param handler The handler to run {@link #onChange} on, or null if none.
|
|
||||||
*/
|
|
||||||
TcConstants(Handler handler) {
|
|
||||||
super(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void start(ContentResolver resolver) {
|
|
||||||
mResolver = resolver;
|
|
||||||
mResolver.registerContentObserver(Settings.Global.getUriFor(
|
|
||||||
Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS), false, this);
|
|
||||||
onChange(true, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChange(boolean selfChange, Uri uri) {
|
|
||||||
final String constants = Settings.Global.getString(
|
|
||||||
mResolver, Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS);
|
|
||||||
|
|
||||||
try {
|
|
||||||
mParser.setString(constants);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Failed to parse the settings string, log this and move on with defaults.
|
|
||||||
Slog.e(TAG, "Bad jobscheduler time controller settings", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
pw.println();
|
|
||||||
pw.println("TimeController:");
|
|
||||||
pw.increaseIndent();
|
|
||||||
pw.print(KEY_USE_NON_WAKEUP_ALARM_FOR_DELAY,
|
|
||||||
USE_NON_WAKEUP_ALARM_FOR_DELAY).println();
|
|
||||||
pw.decreaseIndent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dump(ProtoOutputStream proto) {
|
|
||||||
final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
|
|
||||||
proto.write(ConstantsProto.TimeController.USE_NON_WAKEUP_ALARM_FOR_DELAY,
|
|
||||||
USE_NON_WAKEUP_ALARM_FOR_DELAY);
|
|
||||||
proto.end(tcToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
@NonNull
|
|
||||||
TcConstants getTcConstants() {
|
|
||||||
return mTcConstants;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dumpControllerStateLocked(IndentingPrintWriter pw,
|
public void dumpControllerStateLocked(IndentingPrintWriter pw,
|
||||||
Predicate<JobStatus> predicate) {
|
Predicate<JobStatus> predicate) {
|
||||||
@@ -591,14 +494,4 @@ public final class TimeController extends StateController {
|
|||||||
proto.end(mToken);
|
proto.end(mToken);
|
||||||
proto.end(token);
|
proto.end(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dumpConstants(IndentingPrintWriter pw) {
|
|
||||||
mTcConstants.dump(pw);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dumpConstants(ProtoOutputStream proto) {
|
|
||||||
mTcConstants.dump(proto);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11861,21 +11861,6 @@ public final class Settings {
|
|||||||
public static final String JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS =
|
public static final String JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS =
|
||||||
"job_scheduler_quota_controller_constants";
|
"job_scheduler_quota_controller_constants";
|
||||||
|
|
||||||
/**
|
|
||||||
* Job scheduler TimeController specific settings.
|
|
||||||
* This is encoded as a key=value list, separated by commas. Ex:
|
|
||||||
*
|
|
||||||
* "skip_not_ready_jobs=true5,other_key=2"
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Type: string
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
* @see com.android.server.job.JobSchedulerService.Constants
|
|
||||||
*/
|
|
||||||
public static final String JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS =
|
|
||||||
"job_scheduler_time_controller_constants";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ShortcutManager specific settings.
|
* ShortcutManager specific settings.
|
||||||
* This is encoded as a key=value list, separated by commas. Ex:
|
* This is encoded as a key=value list, separated by commas. Ex:
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ message GlobalSettingsProto {
|
|||||||
|
|
||||||
optional SettingProto job_scheduler_constants = 66 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
optional SettingProto job_scheduler_constants = 66 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
||||||
optional SettingProto job_scheduler_quota_controller_constants = 149 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
optional SettingProto job_scheduler_quota_controller_constants = 149 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
||||||
optional SettingProto job_scheduler_time_controller_constants = 150 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
reserved 150; // job_scheduler_time_controller_constants
|
||||||
|
|
||||||
optional SettingProto keep_profile_in_background = 67 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
optional SettingProto keep_profile_in_background = 67 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
||||||
|
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ message ConstantsProto {
|
|||||||
// ready now.
|
// ready now.
|
||||||
reserved 1; // skip_not_ready_jobs
|
reserved 1; // skip_not_ready_jobs
|
||||||
// Whether or not TimeController will use a non-wakeup alarm for delay constraints.
|
// Whether or not TimeController will use a non-wakeup alarm for delay constraints.
|
||||||
optional bool use_non_wakeup_alarm_for_delay = 2;
|
reserved 2; // use_non_wakeup_alarm_for_delay
|
||||||
}
|
}
|
||||||
optional TimeController time_controller = 25;
|
optional TimeController time_controller = 25;
|
||||||
|
|
||||||
|
|||||||
@@ -865,9 +865,6 @@ class SettingsProtoDumpUtil {
|
|||||||
dumpSetting(s, p,
|
dumpSetting(s, p,
|
||||||
Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
|
Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
|
||||||
GlobalSettingsProto.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS);
|
GlobalSettingsProto.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS);
|
||||||
dumpSetting(s, p,
|
|
||||||
Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS,
|
|
||||||
GlobalSettingsProto.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS);
|
|
||||||
dumpSetting(s, p,
|
dumpSetting(s, p,
|
||||||
Settings.Global.KEEP_PROFILE_IN_BACKGROUND,
|
Settings.Global.KEEP_PROFILE_IN_BACKGROUND,
|
||||||
GlobalSettingsProto.KEEP_PROFILE_IN_BACKGROUND);
|
GlobalSettingsProto.KEEP_PROFILE_IN_BACKGROUND);
|
||||||
|
|||||||
@@ -311,7 +311,6 @@ public class SettingsBackupTest {
|
|||||||
Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL,
|
Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL,
|
||||||
Settings.Global.JOB_SCHEDULER_CONSTANTS,
|
Settings.Global.JOB_SCHEDULER_CONSTANTS,
|
||||||
Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
|
Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
|
||||||
Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS,
|
|
||||||
Settings.Global.KEEP_PROFILE_IN_BACKGROUND,
|
Settings.Global.KEEP_PROFILE_IN_BACKGROUND,
|
||||||
Settings.Global.KERNEL_CPU_THREAD_READER,
|
Settings.Global.KERNEL_CPU_THREAD_READER,
|
||||||
Settings.Global.LANG_ID_UPDATE_CONTENT_URL,
|
Settings.Global.LANG_ID_UPDATE_CONTENT_URL,
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ public class TimeControllerTest {
|
|||||||
private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
|
private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
|
||||||
private static final int SOURCE_USER_ID = 0;
|
private static final int SOURCE_USER_ID = 0;
|
||||||
|
|
||||||
private TimeController.TcConstants mConstants;
|
|
||||||
private TimeController mTimeController;
|
private TimeController mTimeController;
|
||||||
|
|
||||||
private MockitoSession mMockingSession;
|
private MockitoSession mMockingSession;
|
||||||
@@ -111,7 +110,6 @@ public class TimeControllerTest {
|
|||||||
|
|
||||||
// Initialize real objects.
|
// Initialize real objects.
|
||||||
mTimeController = new TimeController(mJobSchedulerService);
|
mTimeController = new TimeController(mJobSchedulerService);
|
||||||
mConstants = mTimeController.getTcConstants();
|
|
||||||
spyOn(mTimeController);
|
spyOn(mTimeController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,46 +527,6 @@ public class TimeControllerTest {
|
|||||||
.set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any());
|
.set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 testCheckExpiredDeadlinesAndResetAlarm_AllReady() {
|
public void testCheckExpiredDeadlinesAndResetAlarm_AllReady() {
|
||||||
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
|
doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
|
||||||
|
|||||||
Reference in New Issue
Block a user