1 /* 2 * Copyright (C) 2016 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 17 package com.android.voicemail.impl.scheduling; 18 19 import android.content.Context; 20 import android.os.Bundle; 21 import android.support.annotation.MainThread; 22 import android.support.annotation.WorkerThread; 23 import android.telecom.PhoneAccountHandle; 24 import java.util.Objects; 25 26 /** 27 * A task for {@link TaskExecutor} to execute. Since the task is sent through a bundle to the 28 * scheduler, The task must be constructable with the bundle. Specifically, It must have a 29 * constructor with zero arguments, and have all relevant data packed inside the bundle. Use {@link 30 * Tasks#createIntent(Context, Class)} to create a intent that will construct the Task. 31 * 32 * <p>Only {@link #onExecuteInBackgroundThread()} is run on the worker thread. 33 */ 34 public interface Task { 35 /** 36 * TaskId to indicate it has not be set. If a task does not provide a default TaskId it should be 37 * set before {@link Task#onCreate(Context, Bundle)} returns 38 */ 39 int TASK_INVALID = -1; 40 41 /** 42 * TaskId to indicate it should always be queued regardless of duplicates. {@link 43 * Task#onDuplicatedTaskAdded(Task)} will never be called on tasks with this TaskId. 44 */ 45 int TASK_ALLOW_DUPLICATES = -2; 46 47 int TASK_UPLOAD = 1; 48 int TASK_SYNC = 2; 49 int TASK_ACTIVATION = 3; 50 int TASK_STATUS_CHECK = 4; 51 52 /** 53 * Used to differentiate between types of tasks. If a task with the same TaskId is already in the 54 * queue the new task will be rejected. 55 */ 56 class TaskId { 57 58 /** Indicates the operation type of the task. */ 59 public final int id; 60 /** 61 * Same operation for a different phoneAccountHandle is allowed. phoneAccountHandle is used to 62 * differentiate phone accounts in multi-SIM scenario. For example, each SIM can queue a sync 63 * task for their own. 64 */ 65 public final PhoneAccountHandle phoneAccountHandle; 66 TaskId(int id, PhoneAccountHandle phoneAccountHandle)67 public TaskId(int id, PhoneAccountHandle phoneAccountHandle) { 68 this.id = id; 69 this.phoneAccountHandle = phoneAccountHandle; 70 } 71 72 @Override equals(Object object)73 public boolean equals(Object object) { 74 if (!(object instanceof TaskId)) { 75 return false; 76 } 77 TaskId other = (TaskId) object; 78 return id == other.id && phoneAccountHandle.equals(other.phoneAccountHandle); 79 } 80 81 @Override hashCode()82 public int hashCode() { 83 return Objects.hash(id, phoneAccountHandle); 84 } 85 } 86 getId()87 TaskId getId(); 88 89 /** 90 * Serializes the task into a bundle, which will be stored in a {@link android.app.job.JobInfo} 91 * and used to reconstruct the task even if the app is terminated. The task will be initialized 92 * with {@link #onCreate(Context, Bundle)}. 93 */ toBundle()94 Bundle toBundle(); 95 96 /** 97 * A task object is created through reflection, calling the default constructor. The actual 98 * initialization is done in this method. If the task is not a new instance, but being restored 99 * from a bundle, {@link #onRestore(Bundle)} will be called afterwards. 100 */ 101 @MainThread onCreate(Context context, Bundle extras)102 void onCreate(Context context, Bundle extras); 103 104 /** 105 * Called after {@link #onCreate(Context, Bundle)} if the task is being restored from a Bundle 106 * instead creating a new instance. For example, if the task is stored in {@link 107 * TaskSchedulerJobService} during a long sleep, this will be called when the job is ran again and 108 * the tasks are being restored from the saved state. 109 */ 110 @MainThread onRestore(Bundle extras)111 void onRestore(Bundle extras); 112 113 /** 114 * @return number of milliSeconds the scheduler should wait before running this task. A value less 115 * than {@link TaskExecutor#READY_TOLERANCE_MILLISECONDS} will be considered ready. If no 116 * tasks are ready, the scheduler will sleep for this amount of time before doing another 117 * check (it will still wake if a new task is added). The first task in the queue that is 118 * ready will be executed. 119 */ 120 @MainThread getReadyInMilliSeconds()121 long getReadyInMilliSeconds(); 122 123 /** 124 * Called on the main thread when the scheduler is about to send the task into the worker thread, 125 * calling {@link #onExecuteInBackgroundThread()} 126 */ 127 @MainThread onBeforeExecute()128 void onBeforeExecute(); 129 130 /** The actual payload of the task, executed on the worker thread. */ 131 @WorkerThread onExecuteInBackgroundThread()132 void onExecuteInBackgroundThread(); 133 134 /** 135 * Called on the main thread when {@link #onExecuteInBackgroundThread()} has finished or thrown an 136 * uncaught exception. The task is already removed from the queue at this point, and a same task 137 * can be queued again. 138 */ 139 @MainThread onCompleted()140 void onCompleted(); 141 142 /** 143 * Another task with the same TaskId has been added. Necessary data can be retrieved from the 144 * other task, and after this returns the task will be discarded. 145 */ 146 @MainThread onDuplicatedTaskAdded(Task task)147 void onDuplicatedTaskAdded(Task task); 148 } 149