@Override public int schedule(JobInfo job) throws RemoteException { int vuid = VBinder.getCallingUid(); int id = job.getId(); ComponentName service = job.getService(); JobId jobId = new JobId(vuid, service.getPackageName(), id); JobConfig config = mJobStore.get(jobId); if (config == null) { config = new JobConfig(mGlobalJobId++, service.getClassName(), job.getExtras()); mJobStore.put(jobId, config); } else { config.serviceName = service.getClassName(); config.extras = job.getExtras(); } saveJobs(); mirror.android.app.job.JobInfo.jobId.set(job, config.virtualJobId); mirror.android.app.job.JobInfo.service.set(job, mJobProxyComponent); return mScheduler.schedule(job); }
private void networkTest(@NetworkUtil.NetworkStatus int networkType, int expected) { SchedulerConstraint constraint = mock(SchedulerConstraint.class); when(constraint.getNetworkStatus()).thenReturn(networkType); JobInfo jobInfo = schedule(constraint); assertThat(jobInfo.isPersisted(), is(true)); assertThat(jobInfo.getId(), is(1)); assertThat(jobInfo.getMinLatencyMillis(), is(0L)); assertThat(jobInfo.getMaxExecutionDelayMillis(), is(0L)); assertThat(jobInfo.getNetworkType(), is(expected)); }
@Override public List<JobInfo> getAllPendingJobs() throws RemoteException { int vuid = VBinder.getCallingUid(); List<JobInfo> jobs = mScheduler.getAllPendingJobs(); synchronized (mJobStore) { Iterator<JobInfo> iterator = jobs.listIterator(); while (iterator.hasNext()) { JobInfo job = iterator.next(); if (!VASettings.STUB_JOB.equals(job.getService().getClassName())) { // Schedule by Host, invisible in VA. iterator.remove(); continue; } Map.Entry<JobId, JobConfig> jobEntry = findJobByVirtualJobId(job.getId()); if (jobEntry == null) { iterator.remove(); continue; } JobId jobId = jobEntry.getKey(); JobConfig config = jobEntry.getValue(); if (jobId.vuid != vuid) { iterator.remove(); continue; } mirror.android.app.job.JobInfo.jobId.set(job, jobId.clientJobId); mirror.android.app.job.JobInfo.service.set(job, new ComponentName(jobId.packageName, config.serviceName)); } } return jobs; }
private void assertNativeJobInfoMatchesJobInfo(android.app.job.JobInfo nativeJob, JobInfo job) { assertEquals(nativeJob.getId(), job.getId()); assertEquals(new PersistableBundle(nativeJob.getExtras()).toMap(10), job.getExtras().toMap(10)); assertEquals(nativeJob.getService(), new ComponentName(context, JobSchedulerJobService.class)); assertEquals(nativeJob.isRequireCharging(), job.isRequireCharging()); assertEquals(nativeJob.isRequireDeviceIdle(), job.isRequireDeviceIdle()); assertEquals(nativeJob.getNetworkType(), job.getNetworkType()); assertEquals(nativeJob.getMinLatencyMillis(), job.getMinLatencyMillis()); assertEquals(nativeJob.getMaxExecutionDelayMillis(), job.getMaxExecutionDelayMillis()); assertEquals(nativeJob.isPeriodic(), job.isPeriodic()); assertEquals(nativeJob.isPersisted(), job.isPersisted()); assertEquals(nativeJob.getInitialBackoffMillis(), job.getInitialBackoffMillis()); assertEquals(nativeJob.getBackoffPolicy(), job.getBackoffPolicy()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { assertEquals(nativeJob.getFlexMillis(), job.getFlexMillis()); assertArrayEquals(getUris(nativeJob.getTriggerContentUris()), getUris(job.getTriggerContentUris())); assertEquals(nativeJob.getTriggerContentUpdateDelay(), job.getTriggerContentUpdateDelay()); assertEquals(nativeJob.getTriggerContentMaxDelay(), job.getTriggerContentMaxDelay()); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { assertEquals( BundleUtils.toMap(nativeJob.getTransientExtras(), 10), BundleUtils.toMap(job.getTransientExtras(), 10)); assertEquals(nativeJob.isRequireBatteryNotLow(), job.isRequireBatteryNotLow()); assertEquals(nativeJob.isRequireStorageNotLow(), job.isRequireBatteryNotLow()); } }
/** * Compare two jobs, returns `true' if the values we care about * are equal * * @param a the first job to compare * @param b the second job to compare * @return true if `a' and `b' are equal jobs */ private static boolean jobsEqual(JobInfo a, JobInfo b) { return (a.getId() == b.getId() && a.getIntervalMillis() == b.getIntervalMillis() && a.isRequireCharging() == b.isRequireCharging() && a.isRequireDeviceIdle() == b.isRequireDeviceIdle() && a.isPeriodic() == b.isPeriodic()); }
String jobId = jobInfo.getId(); ListResult<AssetInfo> outputAssets = mediaService.list(Asset.list(jobInfo.getOutputAssetsLink())); AssetInfo thumbnailAsset = outputAssets.get(0);
@Test public void bundleNullDeadline() throws Exception { SchedulerConstraint constraint = mock(SchedulerConstraint.class); when(constraint.getNetworkStatus()).thenReturn(NetworkUtil.METERED); when(constraint.getUuid()).thenReturn("abc"); when(constraint.getDelayInMs()).thenReturn(345L); when(constraint.getOverrideDeadlineInMs()).thenReturn(null); JobInfo jobInfo = schedule(constraint); PersistableBundle extras = jobInfo.getExtras(); SchedulerConstraint fromBundle = FrameworkScheduler.fromBundle(extras); assertThat(fromBundle.getNetworkStatus(), is(NetworkUtil.METERED)); assertThat(fromBundle.getUuid(), is("abc")); assertThat(fromBundle.getDelayInMs(), is(345L)); assertThat(fromBundle.getOverrideDeadlineInMs(), is(nullValue())); }
@Test public void testScheduledJob() { PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application) .edit() .putBoolean(RuntimeEnvironment.application.getString(R.string.pref_saved_item_sync), true) .apply(); shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)) .setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null, ConnectivityManager.TYPE_WIFI, 0, true, NetworkInfo.State.CONNECTED)); new SyncScheduler().scheduleSync(RuntimeEnvironment.application, "1"); List<JobInfo> pendingJobs = shadowOf((JobScheduler) RuntimeEnvironment.application .getSystemService(Context.JOB_SCHEDULER_SERVICE)).getAllPendingJobs(); assertThat(pendingJobs).isNotEmpty(); JobInfo actual = pendingJobs.get(0); assertThat(actual.getService().getClassName()) .isEqualTo(ItemSyncJobService.class.getName()); }
@Override public void onReceive(Context context, Intent intent) { JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); // If there are not pending jobs. Create a sync job and schedule it. List<JobInfo> pendingJobs = jobScheduler.getAllPendingJobs(); if (pendingJobs.isEmpty()) { String inputId = context.getSharedPreferences(EpgSyncJobService.PREFERENCE_EPG_SYNC, Context.MODE_PRIVATE).getString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, null); if (inputId != null) { // Set up periodic sync only when input has set up. EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class)); } return; } // On L/L-MR1, reschedule the pending jobs. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { for (JobInfo job : pendingJobs) { if (job.isPersisted()) { jobScheduler.schedule(job); } } } } }
@Override public List<JobInfo> getAllPendingJobs() throws RemoteException { int vuid = VBinder.getCallingUid(); List<JobInfo> jobs = mScheduler.getAllPendingJobs(); synchronized (mJobStore) { Iterator<JobInfo> iterator = jobs.listIterator(); while (iterator.hasNext()) { JobInfo job = iterator.next(); if (!VASettings.STUB_JOB.equals(job.getService().getClassName())) { // Schedule by Host, invisible in VA. iterator.remove(); continue; } Map.Entry<JobId, JobConfig> jobEntry = findJobByVirtualJobId(job.getId()); if (jobEntry == null) { iterator.remove(); continue; } JobId jobId = jobEntry.getKey(); JobConfig config = jobEntry.getValue(); if (jobId.vuid != vuid) { iterator.remove(); continue; } mirror.android.app.job.JobInfo.jobId.set(job, jobId.clientJobId); mirror.android.app.job.JobInfo.service.set(job, new ComponentName(jobId.packageName, config.serviceName)); } } return jobs; }
@Test public void bundle() throws Exception { SchedulerConstraint constraint = mock(SchedulerConstraint.class); when(constraint.getNetworkStatus()).thenReturn(NetworkUtil.METERED); when(constraint.getUuid()).thenReturn("abc"); when(constraint.getDelayInMs()).thenReturn(345L); when(constraint.getOverrideDeadlineInMs()).thenReturn(235L); JobInfo jobInfo = schedule(constraint); PersistableBundle extras = jobInfo.getExtras(); SchedulerConstraint fromBundle = FrameworkScheduler.fromBundle(extras); assertThat(fromBundle.getNetworkStatus(), is(NetworkUtil.METERED)); assertThat(fromBundle.getUuid(), is("abc")); assertThat(fromBundle.getDelayInMs(), is(345L)); assertThat(fromBundle.getOverrideDeadlineInMs(), is(235L)); }
@Override protected boolean isJobInfoScheduled(@Nullable JobInfo info, @NonNull JobRequest request) { return info != null && info.getId() == request.getJobId(); }
@Test public void delay() { SchedulerConstraint constraint = mock(SchedulerConstraint.class); when(constraint.getNetworkStatus()).thenReturn(NetworkUtil.DISCONNECTED); when(constraint.getDelayInMs()).thenReturn(133L); JobInfo jobInfo = schedule(constraint); assertThat(jobInfo.isPersisted(), is(true)); assertThat(jobInfo.getId(), is(1)); assertThat(jobInfo.getMinLatencyMillis(), is(133L)); assertThat(jobInfo.getMaxExecutionDelayMillis(), is(0L)); }
@Override public int schedule(JobInfo job) { int vuid = VBinder.getCallingUid(); int id = job.getId(); ComponentName service = job.getService(); JobId jobId = new JobId(vuid, service.getPackageName(), id); JobConfig config = mJobStore.get(jobId); if (config == null) { config = new JobConfig(mGlobalJobId++, service.getClassName(), job.getExtras()); mJobStore.put(jobId, config); } else { config.serviceName = service.getClassName(); config.extras = job.getExtras(); } saveJobs(); mirror.android.app.job.JobInfo.jobId.set(job, config.virtualJobId); mirror.android.app.job.JobInfo.service.set(job, mJobProxyComponent); return mScheduler.schedule(job); }
@Override public List<JobInfo> getAllPendingJobs() { int vuid = VBinder.getCallingUid(); List<JobInfo> jobs = mScheduler.getAllPendingJobs(); synchronized (mJobStore) { Iterator<JobInfo> iterator = jobs.listIterator(); while (iterator.hasNext()) { JobInfo job = iterator.next(); if (!VASettings.STUB_JOB.equals(job.getService().getClassName())) { // Schedule by Host, invisible in VA. iterator.remove(); continue; } Map.Entry<JobId, JobConfig> jobEntry = findJobByVirtualJobId(job.getId()); if (jobEntry == null) { iterator.remove(); continue; } JobId jobId = jobEntry.getKey(); JobConfig config = jobEntry.getValue(); if (jobId.vuid != vuid) { iterator.remove(); continue; } mirror.android.app.job.JobInfo.jobId.set(job, jobId.clientJobId); mirror.android.app.job.JobInfo.service.set(job, new ComponentName(jobId.packageName, config.serviceName)); } } return jobs; }
@SuppressWarnings("SimplifiableIfStatement") protected boolean isJobInfoScheduled(@Nullable JobInfo info, @NonNull JobRequest request) { boolean correctInfo = info != null && info.getId() == request.getJobId(); if (!correctInfo) { return false; } return !request.isTransient() || TransientBundleCompat.isScheduled(mContext, request.getJobId()); }
@Test public void deadline() { SchedulerConstraint constraint = mock(SchedulerConstraint.class); when(constraint.getNetworkStatus()).thenReturn(NetworkUtil.DISCONNECTED); when(constraint.getOverrideDeadlineInMs()).thenReturn(255L); JobInfo jobInfo = schedule(constraint); assertThat(jobInfo.isPersisted(), is(true)); assertThat(jobInfo.getId(), is(1)); assertThat(jobInfo.getMinLatencyMillis(), is(0L)); assertThat(jobInfo.getMaxExecutionDelayMillis(), is(255L)); }