Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +29 −2 Original line number Diff line number Diff line Loading @@ -268,6 +268,7 @@ public class JobSchedulerService extends com.android.server.SystemService /** Master list of jobs. */ final JobStore mJobs; private final CountDownLatch mJobStoreLoadedLatch; private final CountDownLatch mStartControllerTrackingLatch; /** Tracking the standby bucket state of each app */ final StandbyTracker mStandbyTracker; /** Tracking amount of time each package runs for. */ Loading Loading @@ -2521,6 +2522,7 @@ public class JobSchedulerService extends com.android.server.SystemService mBatteryStateTracker.startTracking(); // Create the controllers. mStartControllerTrackingLatch = new CountDownLatch(1); mControllers = new ArrayList<StateController>(); mPrefetchController = new PrefetchController(this); mControllers.add(mPrefetchController); Loading Loading @@ -2552,6 +2554,8 @@ public class JobSchedulerService extends com.android.server.SystemService new TareController(this, backgroundJobsController, mConnectivityController); mControllers.add(mTareController); startControllerTrackingAsync(); mRestrictiveControllers = new ArrayList<>(); mRestrictiveControllers.add(batteryController); mRestrictiveControllers.add(mConnectivityController); Loading Loading @@ -2623,7 +2627,13 @@ public class JobSchedulerService extends com.android.server.SystemService public void onBootPhase(int phase) { if (PHASE_LOCK_SETTINGS_READY == phase) { // This is the last phase before PHASE_SYSTEM_SERVICES_READY. We need to ensure that // controllers have started tracking and that // persisted jobs are loaded before we can proceed to PHASE_SYSTEM_SERVICES_READY. try { mStartControllerTrackingLatch.await(); } catch (InterruptedException e) { Slog.e(TAG, "Couldn't wait on controller tracking start latch"); } try { mJobStoreLoadedLatch.await(); } catch (InterruptedException e) { Loading @@ -2631,8 +2641,8 @@ public class JobSchedulerService extends com.android.server.SystemService } } else if (PHASE_SYSTEM_SERVICES_READY == phase) { mConstantsObserver.start(); for (StateController controller : mControllers) { controller.onSystemServicesReady(); for (int i = mControllers.size() - 1; i >= 0; --i) { mControllers.get(i).onSystemServicesReady(); } mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull( Loading Loading @@ -2695,6 +2705,17 @@ public class JobSchedulerService extends com.android.server.SystemService } } private void startControllerTrackingAsync() { mHandler.post(() -> { synchronized (mLock) { for (int i = mControllers.size() - 1; i >= 0; --i) { mControllers.get(i).startTrackingLocked(); } } mStartControllerTrackingLatch.countDown(); }); } /** * Called when we have a job status object that we need to insert in our * {@link com.android.server.job.JobStore}, and make sure all the relevant controllers know Loading Loading @@ -5176,6 +5197,12 @@ public class JobSchedulerService extends com.android.server.SystemService return mTareController; } @VisibleForTesting protected void waitOnAsyncLoadingForTesting() throws Exception { mStartControllerTrackingLatch.await(); // Ignore the job store loading for testing. } // Shell command infrastructure int getJobState(PrintWriter pw, String pkgName, int userId, @Nullable String namespace, int jobId) { Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +4 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,10 @@ public final class BackgroundJobsController extends StateController { LocalServices.getService(ActivityManagerInternal.class)); mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull( LocalServices.getService(AppStateTracker.class)); } @Override public void startTrackingLocked() { mAppStateTracker.addListener(mForceAppStandbyListener); } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +5 −1 Original line number Diff line number Diff line Loading @@ -78,10 +78,14 @@ public final class BatteryController extends RestrictingController { FlexibilityController flexibilityController) { super(service); mPowerTracker = new PowerTracker(); mPowerTracker.startTracking(); mFlexibilityController = flexibilityController; } @Override public void startTrackingLocked() { mPowerTracker.startTracking(); } @Override public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) { if (taskStatus.hasPowerConstraint()) { Loading apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java +3 −0 Original line number Diff line number Diff line Loading @@ -106,7 +106,10 @@ public class ComponentController extends StateController { public ComponentController(JobSchedulerService service) { super(service); } @Override public void startTrackingLocked() { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_CHANGED); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java +21 −3 Original line number Diff line number Diff line Loading @@ -201,6 +201,10 @@ public final class FlexibilityController extends StateController { mPercentToDropConstraints = mFcConfig.DEFAULT_PERCENT_TO_DROP_FLEXIBLE_CONSTRAINTS; mPrefetchController = prefetchController; } @Override public void startTrackingLocked() { if (mFlexibilityEnabled) { mPrefetchController.registerPrefetchChangedListener(mPrefetchChangedListener); } Loading Loading @@ -369,8 +373,23 @@ public final class FlexibilityController extends StateController { @VisibleForTesting @GuardedBy("mLock") long getLifeCycleBeginningElapsedLocked(JobStatus js) { long earliestRuntime = js.getEarliestRunTime() == JobStatus.NO_EARLIEST_RUNTIME ? js.enqueueTime : js.getEarliestRunTime(); if (js.getJob().isPeriodic() && js.getNumPreviousAttempts() == 0) { // Rescheduling periodic jobs (after a successful execution) may result in the job's // start time being a little after the "true" periodic start time (to avoid jobs // running back to back). See JobSchedulerService#getRescheduleJobForPeriodic for more // details. Since rescheduled periodic jobs may already be delayed slightly by this // policy, don't penalize them further by then enforcing the full set of applied // flex constraints at the beginning of the newly determined start time. Let the flex // constraint requirement start closer to the true periodic start time. final long truePeriodicStartTimeElapsed = js.getLatestRunTimeElapsed() - js.getJob().getFlexMillis(); // For now, treat the lifecycle beginning as the midpoint between the true periodic // start time and the adjusted start time. earliestRuntime = (earliestRuntime + truePeriodicStartTimeElapsed) / 2; } if (js.getJob().isPrefetch()) { final long earliestRuntime = Math.max(js.enqueueTime, js.getEarliestRunTime()); final long estimatedLaunchTime = mPrefetchController.getNextEstimatedLaunchTimeLocked(js); long prefetchWindowStart = mPrefetchLifeCycleStart.getOrDefault( Loading @@ -381,8 +400,7 @@ public final class FlexibilityController extends StateController { } return Math.max(prefetchWindowStart, earliestRuntime); } return js.getEarliestRunTime() == JobStatus.NO_EARLIEST_RUNTIME ? js.enqueueTime : js.getEarliestRunTime(); return earliestRuntime; } @VisibleForTesting Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +29 −2 Original line number Diff line number Diff line Loading @@ -268,6 +268,7 @@ public class JobSchedulerService extends com.android.server.SystemService /** Master list of jobs. */ final JobStore mJobs; private final CountDownLatch mJobStoreLoadedLatch; private final CountDownLatch mStartControllerTrackingLatch; /** Tracking the standby bucket state of each app */ final StandbyTracker mStandbyTracker; /** Tracking amount of time each package runs for. */ Loading Loading @@ -2521,6 +2522,7 @@ public class JobSchedulerService extends com.android.server.SystemService mBatteryStateTracker.startTracking(); // Create the controllers. mStartControllerTrackingLatch = new CountDownLatch(1); mControllers = new ArrayList<StateController>(); mPrefetchController = new PrefetchController(this); mControllers.add(mPrefetchController); Loading Loading @@ -2552,6 +2554,8 @@ public class JobSchedulerService extends com.android.server.SystemService new TareController(this, backgroundJobsController, mConnectivityController); mControllers.add(mTareController); startControllerTrackingAsync(); mRestrictiveControllers = new ArrayList<>(); mRestrictiveControllers.add(batteryController); mRestrictiveControllers.add(mConnectivityController); Loading Loading @@ -2623,7 +2627,13 @@ public class JobSchedulerService extends com.android.server.SystemService public void onBootPhase(int phase) { if (PHASE_LOCK_SETTINGS_READY == phase) { // This is the last phase before PHASE_SYSTEM_SERVICES_READY. We need to ensure that // controllers have started tracking and that // persisted jobs are loaded before we can proceed to PHASE_SYSTEM_SERVICES_READY. try { mStartControllerTrackingLatch.await(); } catch (InterruptedException e) { Slog.e(TAG, "Couldn't wait on controller tracking start latch"); } try { mJobStoreLoadedLatch.await(); } catch (InterruptedException e) { Loading @@ -2631,8 +2641,8 @@ public class JobSchedulerService extends com.android.server.SystemService } } else if (PHASE_SYSTEM_SERVICES_READY == phase) { mConstantsObserver.start(); for (StateController controller : mControllers) { controller.onSystemServicesReady(); for (int i = mControllers.size() - 1; i >= 0; --i) { mControllers.get(i).onSystemServicesReady(); } mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull( Loading Loading @@ -2695,6 +2705,17 @@ public class JobSchedulerService extends com.android.server.SystemService } } private void startControllerTrackingAsync() { mHandler.post(() -> { synchronized (mLock) { for (int i = mControllers.size() - 1; i >= 0; --i) { mControllers.get(i).startTrackingLocked(); } } mStartControllerTrackingLatch.countDown(); }); } /** * Called when we have a job status object that we need to insert in our * {@link com.android.server.job.JobStore}, and make sure all the relevant controllers know Loading Loading @@ -5176,6 +5197,12 @@ public class JobSchedulerService extends com.android.server.SystemService return mTareController; } @VisibleForTesting protected void waitOnAsyncLoadingForTesting() throws Exception { mStartControllerTrackingLatch.await(); // Ignore the job store loading for testing. } // Shell command infrastructure int getJobState(PrintWriter pw, String pkgName, int userId, @Nullable String namespace, int jobId) { Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +4 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,10 @@ public final class BackgroundJobsController extends StateController { LocalServices.getService(ActivityManagerInternal.class)); mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull( LocalServices.getService(AppStateTracker.class)); } @Override public void startTrackingLocked() { mAppStateTracker.addListener(mForceAppStandbyListener); } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +5 −1 Original line number Diff line number Diff line Loading @@ -78,10 +78,14 @@ public final class BatteryController extends RestrictingController { FlexibilityController flexibilityController) { super(service); mPowerTracker = new PowerTracker(); mPowerTracker.startTracking(); mFlexibilityController = flexibilityController; } @Override public void startTrackingLocked() { mPowerTracker.startTracking(); } @Override public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) { if (taskStatus.hasPowerConstraint()) { Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java +3 −0 Original line number Diff line number Diff line Loading @@ -106,7 +106,10 @@ public class ComponentController extends StateController { public ComponentController(JobSchedulerService service) { super(service); } @Override public void startTrackingLocked() { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_CHANGED); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java +21 −3 Original line number Diff line number Diff line Loading @@ -201,6 +201,10 @@ public final class FlexibilityController extends StateController { mPercentToDropConstraints = mFcConfig.DEFAULT_PERCENT_TO_DROP_FLEXIBLE_CONSTRAINTS; mPrefetchController = prefetchController; } @Override public void startTrackingLocked() { if (mFlexibilityEnabled) { mPrefetchController.registerPrefetchChangedListener(mPrefetchChangedListener); } Loading Loading @@ -369,8 +373,23 @@ public final class FlexibilityController extends StateController { @VisibleForTesting @GuardedBy("mLock") long getLifeCycleBeginningElapsedLocked(JobStatus js) { long earliestRuntime = js.getEarliestRunTime() == JobStatus.NO_EARLIEST_RUNTIME ? js.enqueueTime : js.getEarliestRunTime(); if (js.getJob().isPeriodic() && js.getNumPreviousAttempts() == 0) { // Rescheduling periodic jobs (after a successful execution) may result in the job's // start time being a little after the "true" periodic start time (to avoid jobs // running back to back). See JobSchedulerService#getRescheduleJobForPeriodic for more // details. Since rescheduled periodic jobs may already be delayed slightly by this // policy, don't penalize them further by then enforcing the full set of applied // flex constraints at the beginning of the newly determined start time. Let the flex // constraint requirement start closer to the true periodic start time. final long truePeriodicStartTimeElapsed = js.getLatestRunTimeElapsed() - js.getJob().getFlexMillis(); // For now, treat the lifecycle beginning as the midpoint between the true periodic // start time and the adjusted start time. earliestRuntime = (earliestRuntime + truePeriodicStartTimeElapsed) / 2; } if (js.getJob().isPrefetch()) { final long earliestRuntime = Math.max(js.enqueueTime, js.getEarliestRunTime()); final long estimatedLaunchTime = mPrefetchController.getNextEstimatedLaunchTimeLocked(js); long prefetchWindowStart = mPrefetchLifeCycleStart.getOrDefault( Loading @@ -381,8 +400,7 @@ public final class FlexibilityController extends StateController { } return Math.max(prefetchWindowStart, earliestRuntime); } return js.getEarliestRunTime() == JobStatus.NO_EARLIEST_RUNTIME ? js.enqueueTime : js.getEarliestRunTime(); return earliestRuntime; } @VisibleForTesting Loading