Loading apex/jobscheduler/framework/java/android/app/job/JobParameters.java +9 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,13 @@ public class JobParameters implements Parcelable { public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4. /** @hide */ public static final int REASON_DEVICE_THERMAL = JobProtoEnums.STOP_REASON_DEVICE_THERMAL; // 5. /** * The job is in the {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} * bucket. * * @hide */ public static final int REASON_RESTRAINED = JobProtoEnums.STOP_REASON_RESTRAINED; // 6. /** * All the stop reason codes. This should be regarded as an immutable array at runtime. Loading @@ -65,6 +72,7 @@ public class JobParameters implements Parcelable { REASON_TIMEOUT, REASON_DEVICE_IDLE, REASON_DEVICE_THERMAL, REASON_RESTRAINED, }; /** Loading @@ -80,6 +88,7 @@ public class JobParameters implements Parcelable { case REASON_TIMEOUT: return "timeout"; case REASON_DEVICE_IDLE: return "device_idle"; case REASON_DEVICE_THERMAL: return "thermal"; case REASON_RESTRAINED: return "restrained"; default: return "unknown:" + reason; } } Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +69 −9 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ import com.android.server.job.controllers.DeviceIdleJobsController; import com.android.server.job.controllers.IdleController; import com.android.server.job.controllers.JobStatus; import com.android.server.job.controllers.QuotaController; import com.android.server.job.controllers.RestrictingController; import com.android.server.job.controllers.StateController; import com.android.server.job.controllers.StorageController; import com.android.server.job.controllers.TimeController; Loading Loading @@ -241,6 +242,11 @@ public class JobSchedulerService extends com.android.server.SystemService /** List of controllers that will notify this service of updates to jobs. */ final List<StateController> mControllers; /** * List of controllers that will apply to all jobs in the RESTRICTED bucket. This is a subset of * {@link #mControllers}. */ private final List<RestrictingController> mRestrictiveControllers; /** Need direct access to this for testing. */ private final BatteryController mBatteryController; /** Need direct access to this for testing. */ Loading Loading @@ -313,6 +319,9 @@ public class JobSchedulerService extends com.android.server.SystemService public static final int FREQUENT_INDEX = 2; public static final int RARE_INDEX = 3; public static final int NEVER_INDEX = 4; // Putting RESTRICTED_INDEX after NEVER_INDEX to make it easier for proto dumping // (ScheduledJobStateChanged and JobStatusDumpProto). public static final int RESTRICTED_INDEX = 5; // -- Pre-allocated temporaries only for use in assignJobsToContextsLocked -- Loading Loading @@ -1367,6 +1376,40 @@ public class JobSchedulerService extends com.android.server.SystemService } } @Override public void onRestrictedBucketChanged(List<JobStatus> jobs) { final int len = jobs.size(); if (len == 0) { Slog.wtf(TAG, "onRestrictedBucketChanged called with no jobs"); return; } synchronized (mLock) { for (int i = 0; i < len; ++i) { JobStatus js = jobs.get(i); for (int j = mRestrictiveControllers.size() - 1; j >= 0; --j) { // Effective standby bucket can change after this in some situations so use // the real bucket so that the job is tracked by the controllers. if (js.getStandbyBucket() == RESTRICTED_INDEX) { js.addDynamicConstraint(JobStatus.CONSTRAINT_BATTERY_NOT_LOW); js.addDynamicConstraint(JobStatus.CONSTRAINT_CHARGING); js.addDynamicConstraint(JobStatus.CONSTRAINT_CONNECTIVITY); js.addDynamicConstraint(JobStatus.CONSTRAINT_IDLE); mRestrictiveControllers.get(j).startTrackingRestrictedJobLocked(js); } else { js.removeDynamicConstraint(JobStatus.CONSTRAINT_BATTERY_NOT_LOW); js.removeDynamicConstraint(JobStatus.CONSTRAINT_CHARGING); js.removeDynamicConstraint(JobStatus.CONSTRAINT_CONNECTIVITY); js.removeDynamicConstraint(JobStatus.CONSTRAINT_IDLE); mRestrictiveControllers.get(j).stopTrackingRestrictedJobLocked(js); } } } } mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); } void reportActiveLocked() { // active is true if pending queue contains jobs OR some job is running. boolean active = mPendingJobs.size() > 0; Loading Loading @@ -1443,9 +1486,11 @@ public class JobSchedulerService extends com.android.server.SystemService // Create the controllers. mControllers = new ArrayList<StateController>(); mControllers.add(new ConnectivityController(this)); final ConnectivityController connectivityController = new ConnectivityController(this); mControllers.add(connectivityController); mControllers.add(new TimeController(this)); mControllers.add(new IdleController(this)); final IdleController idleController = new IdleController(this); mControllers.add(idleController); mBatteryController = new BatteryController(this); mControllers.add(mBatteryController); mStorageController = new StorageController(this); Loading @@ -1457,6 +1502,11 @@ public class JobSchedulerService extends com.android.server.SystemService mQuotaController = new QuotaController(this); mControllers.add(mQuotaController); mRestrictiveControllers = new ArrayList<>(); mRestrictiveControllers.add(mBatteryController); mRestrictiveControllers.add(connectivityController); mRestrictiveControllers.add(idleController); // Create restrictions mJobRestrictions = new ArrayList<>(); mJobRestrictions.add(new ThermalStatusRestriction(this)); Loading Loading @@ -2127,11 +2177,13 @@ public class JobSchedulerService extends com.android.server.SystemService } } catch (RemoteException e) { } if (mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT > 1 // Restricted jobs must always be batched if (job.getEffectiveStandbyBucket() == RESTRICTED_INDEX || (mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT > 1 && job.getEffectiveStandbyBucket() != ACTIVE_INDEX && (job.getFirstForceBatchedTimeElapsed() == 0 || sElapsedRealtimeClock.millis() - job.getFirstForceBatchedTimeElapsed() < mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS)) { < mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS))) { // Force batching non-ACTIVE jobs. Don't include them in the other counts. forceBatchedCount++; if (job.getFirstForceBatchedTimeElapsed() == 0) { Loading Loading @@ -2538,11 +2590,19 @@ public class JobSchedulerService extends com.android.server.SystemService public static int standbyBucketToBucketIndex(int bucket) { // Normalize AppStandby constants to indices into our bookkeeping if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) return NEVER_INDEX; else if (bucket > UsageStatsManager.STANDBY_BUCKET_FREQUENT) return RARE_INDEX; else if (bucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) return FREQUENT_INDEX; else if (bucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) return WORKING_INDEX; else return ACTIVE_INDEX; if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) { return NEVER_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_RARE) { return RESTRICTED_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_FREQUENT) { return RARE_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) { return FREQUENT_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) { return WORKING_INDEX; } else { return ACTIVE_INDEX; } } // Static to support external callers Loading apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +10 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.server.job; import android.annotation.NonNull; import com.android.server.job.controllers.JobStatus; import java.util.List; /** * Interface through which a {@link com.android.server.job.controllers.StateController} informs * the {@link com.android.server.job.JobSchedulerService} that there are some tasks potentially Loading @@ -39,4 +43,10 @@ public interface StateChangedListener { public void onRunJobNow(JobStatus jobStatus); public void onDeviceIdleStateChanged(boolean deviceIdle); /** * Called when these jobs are added or removed from the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket. */ void onRestrictedBucketChanged(@NonNull List<JobStatus> jobs); } apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +13 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ import java.util.function.Predicate; * be charging when it's been plugged in for more than two minutes, and the system has broadcast * ACTION_BATTERY_OK. */ public final class BatteryController extends StateController { public final class BatteryController extends RestrictingController { private static final String TAG = "JobScheduler.Battery"; private static final boolean DEBUG = JobSchedulerService.DEBUG || Log.isLoggable(TAG, Log.DEBUG); Loading Loading @@ -72,6 +72,11 @@ public final class BatteryController extends StateController { } } @Override public void startTrackingRestrictedJobLocked(JobStatus jobStatus) { maybeStartTrackingJobLocked(jobStatus, null); } @Override public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) { if (taskStatus.clearTrackingController(JobStatus.TRACKING_BATTERY)) { Loading @@ -79,6 +84,13 @@ public final class BatteryController extends StateController { } } @Override public void stopTrackingRestrictedJobLocked(JobStatus jobStatus) { if (!jobStatus.hasPowerConstraint()) { maybeStopTrackingJobLocked(jobStatus, null, false); } } private void maybeReportNewChargingStateLocked() { final boolean stablePower = mChargeTracker.isOnStablePower(); final boolean batteryNotLow = mChargeTracker.isBatteryNotLow(); Loading apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +32 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import android.app.job.JobInfo; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; Loading Loading @@ -63,7 +65,7 @@ import java.util.function.Predicate; * * Test: atest com.android.server.job.controllers.ConnectivityControllerTest */ public final class ConnectivityController extends StateController implements public final class ConnectivityController extends RestrictingController implements ConnectivityManager.OnNetworkActiveListener { private static final String TAG = "JobScheduler.Connectivity"; private static final boolean DEBUG = JobSchedulerService.DEBUG Loading Loading @@ -138,8 +140,22 @@ public final class ConnectivityController extends StateController implements } } @Override public void startTrackingRestrictedJobLocked(JobStatus jobStatus) { // Don't need to start tracking the job. If the job needed network, it would already be // tracked. updateConstraintsSatisfied(jobStatus); } @Override public void stopTrackingRestrictedJobLocked(JobStatus jobStatus) { // Shouldn't stop tracking the job here. If the job was tracked, it still needs network, // even after being unrestricted. updateConstraintsSatisfied(jobStatus); } /** * Returns true if the job's requested network is available. This DOES NOT necesarilly mean * Returns true if the job's requested network is available. This DOES NOT necessarily mean * that the UID has been granted access to the network. */ public boolean isNetworkAvailable(JobStatus job) { Loading Loading @@ -353,14 +369,24 @@ public final class ConnectivityController extends StateController implements private static boolean isStrictSatisfied(JobStatus jobStatus, Network network, NetworkCapabilities capabilities, Constants constants) { return jobStatus.getJob().getRequiredNetwork().networkCapabilities .satisfiedByNetworkCapabilities(capabilities); final NetworkCapabilities required; // A restricted job that's out of quota MUST use an unmetered network. if (jobStatus.getEffectiveStandbyBucket() == RESTRICTED_INDEX && !jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) { required = new NetworkCapabilities( jobStatus.getJob().getRequiredNetwork().networkCapabilities) .addCapability(NET_CAPABILITY_NOT_METERED); } else { required = jobStatus.getJob().getRequiredNetwork().networkCapabilities; } return required.satisfiedByNetworkCapabilities(capabilities); } private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network, NetworkCapabilities capabilities, Constants constants) { // Only consider doing this for prefetching jobs if (!jobStatus.getJob().isPrefetch()) { // Only consider doing this for unrestricted prefetching jobs if (!jobStatus.getJob().isPrefetch() || jobStatus.getStandbyBucket() == RESTRICTED_INDEX) { return false; } Loading Loading
apex/jobscheduler/framework/java/android/app/job/JobParameters.java +9 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,13 @@ public class JobParameters implements Parcelable { public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4. /** @hide */ public static final int REASON_DEVICE_THERMAL = JobProtoEnums.STOP_REASON_DEVICE_THERMAL; // 5. /** * The job is in the {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} * bucket. * * @hide */ public static final int REASON_RESTRAINED = JobProtoEnums.STOP_REASON_RESTRAINED; // 6. /** * All the stop reason codes. This should be regarded as an immutable array at runtime. Loading @@ -65,6 +72,7 @@ public class JobParameters implements Parcelable { REASON_TIMEOUT, REASON_DEVICE_IDLE, REASON_DEVICE_THERMAL, REASON_RESTRAINED, }; /** Loading @@ -80,6 +88,7 @@ public class JobParameters implements Parcelable { case REASON_TIMEOUT: return "timeout"; case REASON_DEVICE_IDLE: return "device_idle"; case REASON_DEVICE_THERMAL: return "thermal"; case REASON_RESTRAINED: return "restrained"; default: return "unknown:" + reason; } } Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +69 −9 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ import com.android.server.job.controllers.DeviceIdleJobsController; import com.android.server.job.controllers.IdleController; import com.android.server.job.controllers.JobStatus; import com.android.server.job.controllers.QuotaController; import com.android.server.job.controllers.RestrictingController; import com.android.server.job.controllers.StateController; import com.android.server.job.controllers.StorageController; import com.android.server.job.controllers.TimeController; Loading Loading @@ -241,6 +242,11 @@ public class JobSchedulerService extends com.android.server.SystemService /** List of controllers that will notify this service of updates to jobs. */ final List<StateController> mControllers; /** * List of controllers that will apply to all jobs in the RESTRICTED bucket. This is a subset of * {@link #mControllers}. */ private final List<RestrictingController> mRestrictiveControllers; /** Need direct access to this for testing. */ private final BatteryController mBatteryController; /** Need direct access to this for testing. */ Loading Loading @@ -313,6 +319,9 @@ public class JobSchedulerService extends com.android.server.SystemService public static final int FREQUENT_INDEX = 2; public static final int RARE_INDEX = 3; public static final int NEVER_INDEX = 4; // Putting RESTRICTED_INDEX after NEVER_INDEX to make it easier for proto dumping // (ScheduledJobStateChanged and JobStatusDumpProto). public static final int RESTRICTED_INDEX = 5; // -- Pre-allocated temporaries only for use in assignJobsToContextsLocked -- Loading Loading @@ -1367,6 +1376,40 @@ public class JobSchedulerService extends com.android.server.SystemService } } @Override public void onRestrictedBucketChanged(List<JobStatus> jobs) { final int len = jobs.size(); if (len == 0) { Slog.wtf(TAG, "onRestrictedBucketChanged called with no jobs"); return; } synchronized (mLock) { for (int i = 0; i < len; ++i) { JobStatus js = jobs.get(i); for (int j = mRestrictiveControllers.size() - 1; j >= 0; --j) { // Effective standby bucket can change after this in some situations so use // the real bucket so that the job is tracked by the controllers. if (js.getStandbyBucket() == RESTRICTED_INDEX) { js.addDynamicConstraint(JobStatus.CONSTRAINT_BATTERY_NOT_LOW); js.addDynamicConstraint(JobStatus.CONSTRAINT_CHARGING); js.addDynamicConstraint(JobStatus.CONSTRAINT_CONNECTIVITY); js.addDynamicConstraint(JobStatus.CONSTRAINT_IDLE); mRestrictiveControllers.get(j).startTrackingRestrictedJobLocked(js); } else { js.removeDynamicConstraint(JobStatus.CONSTRAINT_BATTERY_NOT_LOW); js.removeDynamicConstraint(JobStatus.CONSTRAINT_CHARGING); js.removeDynamicConstraint(JobStatus.CONSTRAINT_CONNECTIVITY); js.removeDynamicConstraint(JobStatus.CONSTRAINT_IDLE); mRestrictiveControllers.get(j).stopTrackingRestrictedJobLocked(js); } } } } mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); } void reportActiveLocked() { // active is true if pending queue contains jobs OR some job is running. boolean active = mPendingJobs.size() > 0; Loading Loading @@ -1443,9 +1486,11 @@ public class JobSchedulerService extends com.android.server.SystemService // Create the controllers. mControllers = new ArrayList<StateController>(); mControllers.add(new ConnectivityController(this)); final ConnectivityController connectivityController = new ConnectivityController(this); mControllers.add(connectivityController); mControllers.add(new TimeController(this)); mControllers.add(new IdleController(this)); final IdleController idleController = new IdleController(this); mControllers.add(idleController); mBatteryController = new BatteryController(this); mControllers.add(mBatteryController); mStorageController = new StorageController(this); Loading @@ -1457,6 +1502,11 @@ public class JobSchedulerService extends com.android.server.SystemService mQuotaController = new QuotaController(this); mControllers.add(mQuotaController); mRestrictiveControllers = new ArrayList<>(); mRestrictiveControllers.add(mBatteryController); mRestrictiveControllers.add(connectivityController); mRestrictiveControllers.add(idleController); // Create restrictions mJobRestrictions = new ArrayList<>(); mJobRestrictions.add(new ThermalStatusRestriction(this)); Loading Loading @@ -2127,11 +2177,13 @@ public class JobSchedulerService extends com.android.server.SystemService } } catch (RemoteException e) { } if (mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT > 1 // Restricted jobs must always be batched if (job.getEffectiveStandbyBucket() == RESTRICTED_INDEX || (mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT > 1 && job.getEffectiveStandbyBucket() != ACTIVE_INDEX && (job.getFirstForceBatchedTimeElapsed() == 0 || sElapsedRealtimeClock.millis() - job.getFirstForceBatchedTimeElapsed() < mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS)) { < mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS))) { // Force batching non-ACTIVE jobs. Don't include them in the other counts. forceBatchedCount++; if (job.getFirstForceBatchedTimeElapsed() == 0) { Loading Loading @@ -2538,11 +2590,19 @@ public class JobSchedulerService extends com.android.server.SystemService public static int standbyBucketToBucketIndex(int bucket) { // Normalize AppStandby constants to indices into our bookkeeping if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) return NEVER_INDEX; else if (bucket > UsageStatsManager.STANDBY_BUCKET_FREQUENT) return RARE_INDEX; else if (bucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) return FREQUENT_INDEX; else if (bucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) return WORKING_INDEX; else return ACTIVE_INDEX; if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) { return NEVER_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_RARE) { return RESTRICTED_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_FREQUENT) { return RARE_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) { return FREQUENT_INDEX; } else if (bucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) { return WORKING_INDEX; } else { return ACTIVE_INDEX; } } // Static to support external callers Loading
apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +10 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.server.job; import android.annotation.NonNull; import com.android.server.job.controllers.JobStatus; import java.util.List; /** * Interface through which a {@link com.android.server.job.controllers.StateController} informs * the {@link com.android.server.job.JobSchedulerService} that there are some tasks potentially Loading @@ -39,4 +43,10 @@ public interface StateChangedListener { public void onRunJobNow(JobStatus jobStatus); public void onDeviceIdleStateChanged(boolean deviceIdle); /** * Called when these jobs are added or removed from the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket. */ void onRestrictedBucketChanged(@NonNull List<JobStatus> jobs); }
apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +13 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ import java.util.function.Predicate; * be charging when it's been plugged in for more than two minutes, and the system has broadcast * ACTION_BATTERY_OK. */ public final class BatteryController extends StateController { public final class BatteryController extends RestrictingController { private static final String TAG = "JobScheduler.Battery"; private static final boolean DEBUG = JobSchedulerService.DEBUG || Log.isLoggable(TAG, Log.DEBUG); Loading Loading @@ -72,6 +72,11 @@ public final class BatteryController extends StateController { } } @Override public void startTrackingRestrictedJobLocked(JobStatus jobStatus) { maybeStartTrackingJobLocked(jobStatus, null); } @Override public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) { if (taskStatus.clearTrackingController(JobStatus.TRACKING_BATTERY)) { Loading @@ -79,6 +84,13 @@ public final class BatteryController extends StateController { } } @Override public void stopTrackingRestrictedJobLocked(JobStatus jobStatus) { if (!jobStatus.hasPowerConstraint()) { maybeStopTrackingJobLocked(jobStatus, null, false); } } private void maybeReportNewChargingStateLocked() { final boolean stablePower = mChargeTracker.isOnStablePower(); final boolean batteryNotLow = mChargeTracker.isBatteryNotLow(); Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +32 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import android.app.job.JobInfo; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; Loading Loading @@ -63,7 +65,7 @@ import java.util.function.Predicate; * * Test: atest com.android.server.job.controllers.ConnectivityControllerTest */ public final class ConnectivityController extends StateController implements public final class ConnectivityController extends RestrictingController implements ConnectivityManager.OnNetworkActiveListener { private static final String TAG = "JobScheduler.Connectivity"; private static final boolean DEBUG = JobSchedulerService.DEBUG Loading Loading @@ -138,8 +140,22 @@ public final class ConnectivityController extends StateController implements } } @Override public void startTrackingRestrictedJobLocked(JobStatus jobStatus) { // Don't need to start tracking the job. If the job needed network, it would already be // tracked. updateConstraintsSatisfied(jobStatus); } @Override public void stopTrackingRestrictedJobLocked(JobStatus jobStatus) { // Shouldn't stop tracking the job here. If the job was tracked, it still needs network, // even after being unrestricted. updateConstraintsSatisfied(jobStatus); } /** * Returns true if the job's requested network is available. This DOES NOT necesarilly mean * Returns true if the job's requested network is available. This DOES NOT necessarily mean * that the UID has been granted access to the network. */ public boolean isNetworkAvailable(JobStatus job) { Loading Loading @@ -353,14 +369,24 @@ public final class ConnectivityController extends StateController implements private static boolean isStrictSatisfied(JobStatus jobStatus, Network network, NetworkCapabilities capabilities, Constants constants) { return jobStatus.getJob().getRequiredNetwork().networkCapabilities .satisfiedByNetworkCapabilities(capabilities); final NetworkCapabilities required; // A restricted job that's out of quota MUST use an unmetered network. if (jobStatus.getEffectiveStandbyBucket() == RESTRICTED_INDEX && !jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) { required = new NetworkCapabilities( jobStatus.getJob().getRequiredNetwork().networkCapabilities) .addCapability(NET_CAPABILITY_NOT_METERED); } else { required = jobStatus.getJob().getRequiredNetwork().networkCapabilities; } return required.satisfiedByNetworkCapabilities(capabilities); } private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network, NetworkCapabilities capabilities, Constants constants) { // Only consider doing this for prefetching jobs if (!jobStatus.getJob().isPrefetch()) { // Only consider doing this for unrestricted prefetching jobs if (!jobStatus.getJob().isPrefetch() || jobStatus.getStandbyBucket() == RESTRICTED_INDEX) { return false; } Loading