Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.components.background_task_scheduler; | |
| 6 | |
| 7 import android.annotation.TargetApi; | |
| 8 import android.app.job.JobInfo; | |
| 9 import android.app.job.JobParameters; | |
| 10 import android.app.job.JobScheduler; | |
| 11 import android.content.ComponentName; | |
| 12 import android.content.Context; | |
| 13 import android.os.Build; | |
| 14 import android.os.Bundle; | |
| 15 import android.os.PersistableBundle; | |
| 16 | |
| 17 import org.chromium.base.Log; | |
| 18 import org.chromium.base.ThreadUtils; | |
| 19 import org.chromium.base.VisibleForTesting; | |
| 20 | |
| 21 /** | |
| 22 * An implementation of {@link BackgroundTaskSchedulerDelegate} that uses the sy stem | |
| 23 * {@link JobScheduler} to schedule jobs. | |
| 24 */ | |
| 25 @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) | |
| 26 class BackgroundTaskSchedulerJobService implements BackgroundTaskSchedulerDelega te { | |
| 27 private static final String TAG = "BkgrdTaskSchedulerJS"; | |
| 28 | |
| 29 private static final String BACKGROUND_TASK_CLASS_KEY = "_background_task_cl ass"; | |
| 30 @VisibleForTesting | |
| 31 static final String BACKGROUND_TASK_EXTRAS_KEY = "_background_task_extras"; | |
| 32 | |
| 33 static BackgroundTask getBackgroundTaskFromJobParameters(JobParameters jobPa rameters) { | |
| 34 String backgroundTaskClassName = getBackgroundTaskClassFromJobParameters (jobParameters); | |
| 35 return BackgroundTaskScheduler.getBackgroundTaskFromClassName(background TaskClassName); | |
| 36 } | |
| 37 | |
| 38 private static String getBackgroundTaskClassFromJobParameters(JobParameters jobParameters) { | |
| 39 PersistableBundle extras = jobParameters.getExtras(); | |
| 40 if (extras == null) return null; | |
| 41 return extras.getString(BACKGROUND_TASK_CLASS_KEY); | |
| 42 } | |
| 43 | |
| 44 /** | |
| 45 * Retrieves the {@link TaskParameters} from the {@link JobParameters}, whic h are passed as | |
|
David Trainor- moved to gerrit
2017/02/24 07:19:49
Mention that only persistable data is transmitted
nyquist
2017/02/24 23:41:12
Done.
| |
| 46 * one of the keys. | |
| 47 * | |
| 48 * @param jobParameters the {@link JobParameters} to extract the {@link Task Parameters} from. | |
| 49 * @return the {@link TaskParameters} for the current job. | |
| 50 */ | |
| 51 static TaskParameters getTaskParametersFromJobParameters(JobParameters jobPa rameters) { | |
| 52 TaskParameters.Builder builder = TaskParameters.create(jobParameters.get JobId()); | |
| 53 | |
| 54 PersistableBundle jobExtras = jobParameters.getExtras(); | |
| 55 PersistableBundle persistableTaskExtras = | |
| 56 jobExtras.getPersistableBundle(BACKGROUND_TASK_EXTRAS_KEY); | |
| 57 | |
| 58 Bundle taskExtras = new Bundle(); | |
| 59 taskExtras.putAll(persistableTaskExtras); | |
| 60 builder.addExtras(taskExtras); | |
| 61 | |
| 62 return builder.build(); | |
| 63 } | |
| 64 | |
| 65 @VisibleForTesting | |
| 66 static JobInfo createJobInfoFromTaskInfo(Context context, TaskInfo taskInfo) { | |
| 67 PersistableBundle jobExtras = new PersistableBundle(); | |
| 68 jobExtras.putString(BACKGROUND_TASK_CLASS_KEY, taskInfo.getBackgroundTas kClass().getName()); | |
| 69 | |
| 70 PersistableBundle persistableBundle = getTaskExtrasAsPersistableBundle(t askInfo); | |
| 71 jobExtras.putPersistableBundle(BACKGROUND_TASK_EXTRAS_KEY, persistableBu ndle); | |
| 72 | |
| 73 JobInfo.Builder builder = | |
| 74 new JobInfo | |
| 75 .Builder(taskInfo.getTaskId(), | |
| 76 new ComponentName(context, BackgroundTaskJobServ ice.class)) | |
| 77 .setExtras(jobExtras) | |
| 78 .setPersisted(taskInfo.isPersisted()) | |
| 79 .setRequiresCharging(taskInfo.requiresCharging()) | |
| 80 .setRequiredNetworkType(getJobInfoNetworkTypeFromTaskNet workType( | |
| 81 taskInfo.getRequiredNetworkType())); | |
| 82 | |
| 83 if (taskInfo.isPeriodic()) { | |
| 84 builder = getPeriodicJobInfo(builder, taskInfo); | |
| 85 } else { | |
| 86 builder = getOneOffJobInfo(builder, taskInfo); | |
| 87 } | |
| 88 | |
| 89 return builder.build(); | |
| 90 } | |
| 91 | |
| 92 private static JobInfo.Builder getOneOffJobInfo(JobInfo.Builder builder, Tas kInfo taskInfo) { | |
| 93 TaskInfo.OneOffInfo oneOffInfo = taskInfo.getOneOffInfo(); | |
| 94 if (oneOffInfo.hasWindowStartTimeConstraint()) { | |
| 95 builder = builder.setMinimumLatency(oneOffInfo.getWindowStartTimeMs( )); | |
| 96 } | |
| 97 return builder.setOverrideDeadline(oneOffInfo.getWindowEndTimeMs()); | |
| 98 } | |
| 99 | |
| 100 private static JobInfo.Builder getPeriodicJobInfo(JobInfo.Builder builder, T askInfo taskInfo) { | |
| 101 TaskInfo.PeriodicInfo periodicInfo = taskInfo.getPeriodicInfo(); | |
| 102 if (periodicInfo.hasFlex()) { | |
| 103 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | |
| 104 return builder.setPeriodic(periodicInfo.getIntervalMs(), periodi cInfo.getFlexMs()); | |
| 105 } | |
| 106 return builder.setPeriodic(periodicInfo.getIntervalMs()); | |
| 107 } | |
| 108 return builder.setPeriodic(periodicInfo.getIntervalMs()); | |
| 109 } | |
| 110 | |
| 111 private static int getJobInfoNetworkTypeFromTaskNetworkType( | |
| 112 @TaskInfo.NetworkType int networkType) { | |
| 113 // The values are hard coded to represent the same as the network type f rom JobService. | |
| 114 return networkType; | |
| 115 } | |
| 116 | |
| 117 private static PersistableBundle getTaskExtrasAsPersistableBundle(TaskInfo t askInfo) { | |
| 118 Bundle taskExtras = taskInfo.getExtras(); | |
| 119 BundleToPersistableBundleConverter.Result convertedData = | |
| 120 BundleToPersistableBundleConverter.convert(taskExtras); | |
| 121 if (convertedData.hasErrors()) { | |
| 122 Log.w(TAG, "Failed converting extras to PersistableBundle: " | |
| 123 + convertedData.getFailedKeysErrorString()); | |
| 124 } | |
| 125 return convertedData.getPersistableBundle(); | |
| 126 } | |
| 127 | |
| 128 @Override | |
| 129 public boolean schedule(Context context, TaskInfo taskInfo) { | |
| 130 ThreadUtils.assertOnUiThread(); | |
| 131 JobInfo jobInfo = createJobInfoFromTaskInfo(context, taskInfo); | |
| 132 | |
| 133 JobScheduler jobScheduler = | |
| 134 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SE RVICE); | |
| 135 | |
| 136 if (taskInfo.shouldUpdateCurrent()) { | |
| 137 jobScheduler.cancel(taskInfo.getTaskId()); | |
| 138 } | |
| 139 | |
| 140 int result = jobScheduler.schedule(jobInfo); | |
| 141 return result == JobScheduler.RESULT_SUCCESS; | |
| 142 } | |
| 143 | |
| 144 @Override | |
| 145 public void cancel(Context context, int taskId) { | |
| 146 ThreadUtils.assertOnUiThread(); | |
| 147 JobScheduler jobScheduler = | |
| 148 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SE RVICE); | |
| 149 jobScheduler.cancel(taskId); | |
| 150 } | |
| 151 } | |
| OLD | NEW |