/*package*/ static JobRequest fromCursor(Cursor cursor) { JobRequest request = new Builder(cursor).build(); request.mFailureCount = cursor.getInt(cursor.getColumnIndex(JobStorage.COLUMN_NUM_FAILURES)); request.mScheduledAt = cursor.getLong(cursor.getColumnIndex(JobStorage.COLUMN_SCHEDULED_AT)); request.mStarted = cursor.getInt(cursor.getColumnIndex(JobStorage.COLUMN_STARTED)) > 0; request.mFlexSupport = cursor.getInt(cursor.getColumnIndex(JobStorage.COLUMN_FLEX_SUPPORT)) > 0; request.mLastRun = cursor.getLong(cursor.getColumnIndex(JobStorage.COLUMN_LAST_RUN)); JobPreconditions.checkArgumentNonnegative(request.mFailureCount, "failure count can't be negative"); JobPreconditions.checkArgumentNonnegative(request.mScheduledAt, "scheduled at can't be negative"); return request; }
public static JobRequest.Builder createBuilder(Class<? extends Job> jobClass) { try { String tag = (String) jobClass.getDeclaredField("TAG").get(null); return new JobRequest.Builder(tag); } catch (Exception e) { throw new IllegalStateException(e); } }
@Test public void testConstraintsOneOff() { testConstraints(new JobRequest.Builder(TAG) .setExecutionWindow(TimeUnit.HOURS.toMillis(4), TimeUnit.HOURS.toMillis(5)) .setBackoffCriteria(TimeUnit.MINUTES.toMillis(4), JobRequest.BackoffPolicy.EXPONENTIAL) ); }
@Override public void createPeriodic() { for (int i = 0; i < 10; i++) { JobRequest.Builder builder = new JobRequest.Builder("tag") .setPeriodic(TimeUnit.MINUTES.toMillis(1)) .setRequiresCharging(random()) .setRequiresDeviceIdle(random()) .setRequiredNetworkType(random() ? JobRequest.NetworkType.ANY : JobRequest.NetworkType.CONNECTED) .setRequirementsEnforced(random()); if (random()) { PersistableBundleCompat extras = new PersistableBundleCompat(); extras.putString("key", "Hello world"); builder.setExtras(extras); } builder.build().schedule(); } } }
@Test @Config(sdk = 21) public void verifyExactJobRescheduled() throws Exception { assertThat(manager().getAllJobRequests()).isEmpty(); ContentValues contentValues = new JobRequest.Builder("tag") .setExact(TimeUnit.HOURS.toMillis(1)) .build() .toContentValues(); manager().getJobStorage().getDatabase() .insert(JobStorage.JOB_TABLE_NAME, null, contentValues); Set<JobRequest> requests = manager().getAllJobRequests(); assertThat(requests).isNotEmpty(); final int jobId = 1; Intent intent = new Intent(context(), PlatformAlarmReceiver.class); assertThat(PendingIntent.getBroadcast(context(), jobId, intent, PendingIntent.FLAG_NO_CREATE)).isNull(); int rescheduledJobs = new JobRescheduleService().rescheduleJobs(manager()); assertThat(rescheduledJobs).isEqualTo(1); assertThat(PendingIntent.getBroadcast(context(), jobId, intent, PendingIntent.FLAG_NO_CREATE)).isNotNull(); }
@Test public void testCancel() { int jobId = new JobRequest.Builder(TAG) .setExecutionWindow(TimeUnit.HOURS.toMillis(4), TimeUnit.HOURS.toMillis(5)) .build() .schedule(); JobRequest request = mWorkManagerRule.getManager().getJobRequest(jobId); JobProxyWorkManager jobProxyWorkManager = new JobProxyWorkManager(InstrumentationRegistry.getTargetContext()); assertThat(jobProxyWorkManager.isPlatformJobScheduled(request)).isTrue(); String tag = JobProxyWorkManager.createTag(jobId); List<WorkInfo> statuses = mWorkManagerRule.getWorkStatus(tag); assertThat(statuses).isNotNull().hasSize(1); assertThat(statuses.get(0).getState()).isEqualTo(WorkInfo.State.ENQUEUED); mWorkManagerRule.getManager().cancel(jobId); assertThat(mWorkManagerRule.getWorkStatus(tag).get(0).getState()).isEqualTo(WorkInfo.State.CANCELLED); assertThat(jobProxyWorkManager.isPlatformJobScheduled(request)).isFalse(); }
@Test @Config(sdk = 21) public void verifyPeriodicJobRescheduled() throws Exception { assertThat(manager().getAllJobRequests()).isEmpty(); ContentValues contentValues = new JobRequest.Builder("tag") .setPeriodic(TimeUnit.HOURS.toMillis(1)) .build() .toContentValues(); manager().getJobStorage().getDatabase() .insert(JobStorage.JOB_TABLE_NAME, null, contentValues); Set<JobRequest> requests = manager().getAllJobRequests(); assertThat(requests).isNotEmpty(); JobScheduler scheduler = (JobScheduler) context().getSystemService(Context.JOB_SCHEDULER_SERVICE); assertThat(scheduler.getAllPendingJobs()).isEmpty(); int rescheduledJobs = new JobRescheduleService().rescheduleJobs(manager()); assertThat(rescheduledJobs).isEqualTo(1); }
@Test public void testTransientExtras() { Bundle extras = new Bundle(); extras.putInt("key", 5); JobRequest.Builder builder = new JobRequest.Builder(TAG) .setExecutionWindow(TimeUnit.HOURS.toMillis(4), TimeUnit.HOURS.toMillis(5)) .setTransientExtras(extras); int jobId = builder.build().schedule(); Bundle bundle = TransientBundleHolder.getBundle(jobId); assertThat(bundle).isNotNull(); assertThat(bundle.getInt("key")).isEqualTo(5); mWorkManagerRule.getManager().cancel(jobId); assertThat(TransientBundleHolder.getBundle(jobId)).isNull(); jobId = builder.build().schedule(); mWorkManagerRule.runJob(JobProxyWorkManager.createTag(jobId)); assertThat(TransientBundleHolder.getBundle(jobId)).isNull(); }
@Test public void verifyTransientJobNotRescheduled() throws Exception { assertThat(manager().getAllJobRequests()).isEmpty(); Bundle bundle = new Bundle(); bundle.putString("key", "value"); ContentValues contentValues = new JobRequest.Builder("tag") .setExact(TimeUnit.HOURS.toMillis(1)) .setTransientExtras(bundle) .build() .toContentValues(); manager().getJobStorage().getDatabase() .insert(JobStorage.JOB_TABLE_NAME, null, contentValues); Set<JobRequest> requests = manager().getAllJobRequests(); assertThat(requests).isEmpty(); } }
/*package*/ Builder createBuilder() { return new Builder(mBuilder, true); }
/*package*/ JobRequest reschedule(boolean failure, boolean newJob) { JobRequest newRequest = new Builder(this.mBuilder, newJob).build(); if (failure) { newRequest.mFailureCount = mFailureCount + 1; } try { newRequest.schedule(); } catch (Exception e) { CAT.e(e); // this may crash (e.g. more than 100 jobs with JobScheduler), but it's not catchable for the user, wait for reschedule } return newRequest; }
@Test @Config(sdk = Build.VERSION_CODES.M) public void verifyNotFoundJobCanceledPeriodicFlexSupport() { final String tag = "something"; final int jobId = new JobRequest.Builder(tag) .setPeriodic(TimeUnit.HOURS.toMillis(4)) .build() .schedule(); assertThat(manager().getAllJobRequestsForTag(tag)).hasSize(1); executeJob(jobId, Job.Result.FAILURE); assertThat(manager().getAllJobRequestsForTag(tag)).isEmpty(); } }
@Test public void testStartNow() throws Exception { mJob = new TestJob(); new JobRequest.Builder("tag") .startNow() .setTransientExtras(createTransientBundle()) .build() .schedule(); mJob.verifyJob(3, TimeUnit.SECONDS); }
@Test public void testStartNow() throws Exception { mJob = new TestJob(PlatformAlarmService.class); new JobRequest.Builder("tag") .startNow() .build() .schedule(); mJob.verifyJob(3, TimeUnit.SECONDS); }
@Test public void testConstraintsPeriodic() { testConstraints(new JobRequest.Builder(TAG) .setPeriodic(TimeUnit.HOURS.toMillis(4), TimeUnit.HOURS.toMillis(2)) ); }
@Test public void verifyNotFoundJobCanceledDailyJob() { final String tag = "something"; int jobId = DailyJob.schedule(new JobRequest.Builder(tag), TimeUnit.HOURS.toMillis(5), TimeUnit.HOURS.toMillis(6)); assertThat(manager().getAllJobRequestsForTag(tag)).hasSize(1); executeJob(jobId, Job.Result.FAILURE); assertThat(manager().getAllJobRequestsForTag(tag)).isEmpty(); }
private void testPeriodic() { mLastJobId = new JobRequest.Builder(DemoSyncJob.TAG) .setPeriodic(JobRequest.MIN_INTERVAL, JobRequest.MIN_FLEX) .setRequiresCharging(mRequiresCharging.isChecked()) .setRequiresDeviceIdle(mRequiresDeviceIdle.isChecked()) .setRequiredNetworkType(JobRequest.NetworkType.values()[mNetworkTypeSpinner.getSelectedItemPosition()]) .build() .schedule(); }
@Test public void verifyNotFoundJobCanceledPeriodic() { final String tag = "something"; final int jobId = new JobRequest.Builder(tag) .setPeriodic(TimeUnit.HOURS.toMillis(4)) .build() .schedule(); assertThat(manager().getAllJobRequestsForTag(tag)).hasSize(1); executeJob(jobId, Job.Result.FAILURE); assertThat(manager().getAllJobRequestsForTag(tag)).isEmpty(); }
@Test public void verifyNotFoundJobCanceledOneOff() { final String tag = "something"; final int jobId = new JobRequest.Builder(tag) .setExecutionWindow(TimeUnit.HOURS.toMillis(4), TimeUnit.HOURS.toMillis(5)) .build() .schedule(); assertThat(manager().getAllJobRequestsForTag(tag)).hasSize(1); executeJob(jobId, Job.Result.FAILURE); assertThat(manager().getAllJobRequestsForTag(tag)).isEmpty(); }
@Test public void verifyNotFoundJobCanceledExact() { final String tag = "something"; final int jobId = new JobRequest.Builder(tag) .setExact(TimeUnit.HOURS.toMillis(4)) .build() .schedule(); assertThat(manager().getAllJobRequestsForTag(tag)).hasSize(1); executeJob(jobId, Job.Result.FAILURE); assertThat(manager().getAllJobRequestsForTag(tag)).isEmpty(); }