1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.car.kitchensink.job; 17 18 import android.app.job.JobParameters; 19 import android.app.job.JobService; 20 import android.os.AsyncTask; 21 import android.os.Handler; 22 import android.os.Message; 23 import android.util.Log; 24 import android.util.SparseArray; 25 26 import java.lang.ref.WeakReference; 27 28 public class DishService extends JobService { 29 private static final String TAG = "JobScheduler_DishService"; 30 private static final int DELAY_MS = 1000; // wash a plate every second! 31 32 private static final int MSG_FINISHED = 0; 33 private static final int MSG_RUN_JOB = 1; 34 private static final int MSG_CANCEL_JOB = 2; 35 36 public static final String EXTRA_DISH_COUNT = "dish_count"; 37 38 private final Handler mHandler = new Handler() { 39 private SparseArray<JobParameters> mTaskMap = new SparseArray<JobParameters>(); 40 @Override 41 public void handleMessage(Message msg) { 42 JobParameters job = (JobParameters) msg.obj; 43 switch (msg.what) { 44 case MSG_FINISHED: 45 Log.d(TAG, "Job done! " + job.getJobId()); 46 mTaskMap.remove(job.getJobId()); 47 jobFinished(job, false); 48 break; 49 case MSG_RUN_JOB: 50 DishWasherTask task = new DishWasherTask(this, job, msg.arg1); 51 task.execute(); 52 mTaskMap.put(job.getJobId(), job); 53 break; 54 case MSG_CANCEL_JOB: 55 JobParameters job1 = mTaskMap.get(job.getJobId()); 56 if (job1 != null) { 57 removeMessages(MSG_RUN_JOB, job1); 58 Log.d(TAG, "cancelled job " + job1); 59 mTaskMap.remove(job.getJobId()); 60 } 61 break; 62 default: 63 Log.w(TAG, "Unknown message " + msg.what); 64 } 65 } 66 }; 67 68 @Override 69 public boolean onStopJob(JobParameters jobParameters) { 70 Log.d(TAG, "onStopJob " + jobParameters); 71 Message msg = mHandler.obtainMessage(MSG_CANCEL_JOB, 0, 0, jobParameters); 72 mHandler.sendMessage(msg); 73 return false; 74 } 75 76 @Override 77 public boolean onStartJob(final JobParameters jobParameters) { 78 Log.d(TAG, "onStartJob " + jobParameters); 79 Message msg = mHandler.obtainMessage(MSG_RUN_JOB, 0, 0, jobParameters); 80 mHandler.sendMessage(msg); 81 return true; 82 } 83 84 private static final class DishWasherTask extends AsyncTask<Void, Void, Boolean> { 85 private final WeakReference<Handler> mHandler; 86 private final JobParameters mJobParameter; 87 private final int mMyDishNum; 88 89 90 public DishWasherTask(Handler handler, JobParameters jobParameters, int dishNum) { 91 mHandler = new WeakReference<Handler>(handler); 92 mJobParameter = jobParameters; 93 mMyDishNum = dishNum; 94 } 95 96 @Override 97 protected Boolean doInBackground(Void... infos) { 98 int dishTotal = mJobParameter.getExtras().getInt(EXTRA_DISH_COUNT); 99 100 Log.d(TAG, "jobId: " + mJobParameter.getJobId() + " totalDish: " + dishTotal 101 + " washing: #" + mMyDishNum); 102 wash(); 103 if (mMyDishNum >= dishTotal - 1) { 104 // all done! 105 return false; 106 } 107 return true; 108 } 109 110 @Override 111 protected void onPostExecute(Boolean result) { 112 if (mHandler.get() == null) { 113 return; 114 } 115 if (result) { 116 Message msg = mHandler.get().obtainMessage(MSG_RUN_JOB, 117 mMyDishNum +1, 0, mJobParameter); 118 mHandler.get().sendMessageDelayed(msg, DELAY_MS); 119 } else { 120 Message msg = mHandler.get().obtainMessage(MSG_FINISHED, 0, 121 0, mJobParameter); 122 mHandler.get().sendMessage(msg); 123 } 124 } 125 126 private void wash() { 127 // TODO: add heavy wash tasks here... 128 } 129 } 130 } 131