summaryrefslogtreecommitdiffstats
path: root/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp
diff options
context:
space:
mode:
authorMatthew Williams <mjwilliams@google.com>2014-07-25 11:30:40 -0700
committerMatthew Williams <mjwilliams@google.com>2014-07-29 11:11:41 -0700
commitee410da42b6b8352213f03f7725fd041f703b035 (patch)
treed79add63a7762d26f9d8396876fc8cc47ce0cb75 /tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp
parentc503896a4d0cab029bca56cf7ac18ae182729a0a (diff)
downloadframeworks_base-ee410da42b6b8352213f03f7725fd041f703b035.zip
frameworks_base-ee410da42b6b8352213f03f7725fd041f703b035.tar.gz
frameworks_base-ee410da42b6b8352213f03f7725fd041f703b035.tar.bz2
remove possible JobScheduler race in cancel()
Client can jobFinished() before getting a cancel msg. 1) Do better clean up of JobServiceContext after client jobFinished() to remove superfluous MSG_CANCELs 2) When processing MSG_CANCEL check whether the context is still active 3) Do JobServiceContext cleanup before calling back to JobSchedulerService Client can get a cancel msg even after calling jobFinished() (opposite to above) 1) explicitly check whether there are any MSG_CALLBACKs in the queue before processing a MSG_CANCEL. If there are we can throw away the cancel. Bug: 16547638 Change-Id: I90644586c7895a9ce97de752a5d657faf7f74b78
Diffstat (limited to 'tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp')
-rw-r--r--tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java60
1 files changed, 51 insertions, 9 deletions
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
index bf8e887..e2c3be0 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
@@ -20,16 +20,21 @@ import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobParameters;
import android.app.job.JobService;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.AsyncTask;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
+import android.util.SparseArray;
import com.android.demo.jobSchedulerApp.MainActivity;
+import java.util.HashMap;
import java.util.LinkedList;
+import java.util.Random;
/**
@@ -75,39 +80,76 @@ public class TestJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
- jobParamsMap.add(params);
+ Log.i(TAG, "on start job: " + params.getJobId());
+ currentId++;
+ jobParamsMap.put(currentId, params);
+ final int currId = this.currentId;
+ Log.d(TAG, "putting :" + currId + " for " + params.toString());
+ Log.d(TAG, " pulled: " + jobParamsMap.get(currId));
if (mActivity != null) {
mActivity.onReceivedStartJob(params);
}
- Log.i(TAG, "on start job: " + params.getJobId());
+
+ // Spin off a new task on a separate thread for a couple seconds.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... voids) {
+ try {
+ Log.d(TAG, "Sleeping for 3 seconds.");
+ Thread.sleep(3000L);
+ } catch (InterruptedException e) {}
+ final JobParameters params = jobParamsMap.get(currId);
+ Log.d(TAG, "Pulled :" + currId + " " + params);
+ jobFinished(params, false);
+
+ Log.d(TAG, "Rescheduling new job: " + params.getJobId());
+ scheduleJob(
+ new JobInfo.Builder(params.getJobId(),
+ new ComponentName(getBaseContext(), TestJobService.class))
+ .setMinimumLatency(2000L)
+ .setOverrideDeadline(3000L)
+ .setRequiresCharging(true)
+ .build()
+ );
+
+ return null;
+ }
+ }.execute();
return true;
}
+
@Override
public boolean onStopJob(JobParameters params) {
- jobParamsMap.remove(params);
- mActivity.onReceivedStopJob();
Log.i(TAG, "on stop job: " + params.getJobId());
+ int ind = jobParamsMap.indexOfValue(params);
+ jobParamsMap.remove(ind);
+ mActivity.onReceivedStopJob();
return true;
}
+ static int currentId = 0;
MainActivity mActivity;
- private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
+ private final SparseArray<JobParameters> jobParamsMap = new SparseArray<JobParameters>();
+
public void setUiCallback(MainActivity activity) {
mActivity = activity;
}
/** Send job to the JobScheduler. */
- public void scheduleJob(JobInfo t) {
- Log.d(TAG, "Scheduling job");
+ public void scheduleJob(JobInfo job) {
+ Log.d(TAG, "Scheduling job " + job);
JobScheduler tm =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
- tm.schedule(t);
+ tm.schedule(job);
}
public boolean callJobFinished() {
- JobParameters params = jobParamsMap.poll();
+ if (jobParamsMap.size() == 0) {
+ return false;
+ }
+ JobParameters params = jobParamsMap.valueAt(0);
if (params == null) {
return false;
} else {