fixup! [M120 Migration] Notify media device state to webbrowser
[platform/framework/web/chromium-efl.git] / components / background_task_scheduler / README.md
1 # Quick Start Guide to using BackgroundTaskScheduler
2
3 ## Overview
4
5 This document describes how to schedule a background task in Android using
6 BackgroundTaskScheduler API. Although most of the examples are described in
7 Java, the exact same API is available in C++ as well.
8
9 ## Background
10
11 In Android it is encouraged to use `JobScheduler` for all background jobs,
12 instead of using things like `IntentService` or polling using alarms. Using the
13 system API is beneficial as it has a full view of what goes on in the system and
14 can schedule jobs accordingly.
15
16 The `background_task_scheduler` component provides a framework for use within
17 Chromium to schedule and execute background jobs using the system API. The
18 API of the framework is similar to that of the Android `JobScheduler`.
19
20 ## What is a task
21
22 A task is defined as a class that implements the `BackgroundTask` interface,
23 which looks like this:
24
25 ```java
26 interface BackgroundTask {
27   interface TaskFinishedCallback {
28     void taskFinished(boolean needsReschedule);
29   }
30
31   boolean onStartTask(Context context,
32                       TaskParameters taskParameters,
33                       TaskFinishedCallback callback);
34   boolean onStopTask(Context context,
35                      TaskParameters taskParameters);
36 }
37 ```
38
39 **Any class implementing this interface must have a public constructor which takes
40 no arguments.**
41
42 A task must also have a unique ID, and it must be listed in `TaskIds` to ensure
43 there is no overlap between different tasks.
44
45 The connection between `TaskIds` and the corresponding `BackgroundTask` classes is done by injecting
46 a `BackgroundTaskFactory` class in `BackgroundTaskSchedulerFactory`. For the //chrome embedder
47 (which is the only one needing the association), the `ChromeBackgroundTaskFactory` [implementation]
48 (https://cs.chromium.org/chromium/src/chrome/android/java/src/org/chromium/chrome/browser
49 /background_task_scheduler/ChromeBackgroundTaskFactory.java) was created. Anyone that adds a new
50 task id to `TaskIds` should add a case in this class to.
51
52 ## How to schedule a task
53
54 A task is scheduled by creating an object containing information about the task,
55 such as when to run it, whether it requires battery, and other similar
56 constraints. This object is called `TaskInfo` and has a builder you can use
57 to set all the relevant fields.
58
59 There are three main types of tasks; one-off tasks, periodic tasks, and exact timing info tasks. One-off
60 tasks are only executed once, whereas periodic tasks are executed once per
61 a defined interval. The exact info tasks are triggered at the exact scheduled time.
62
63 There are two steps in the process of creating a TaskInfo:
64
65  1. the specific timing info is created; there are three objects available - `OneOffInfo`,
66  `PeriodicInfo`, and `ExactInfo`; each one of these objects has its own builder;
67  2. the task info is created using the `createTask` method; other parameters can be set afterwards.
68
69 As an example for how to create a one-off task that executes in 200 minutes,
70 you can do the following:
71
72 ```java
73 TaskInfo.TimingInfo oneOffInfo = TaskInfo.OneOffInfo.create()
74                                     .setWindowEndTimeMs(TimeUnit.MINUTES.toMillis(200)).build();
75 TaskInfo taskInfo = TaskInfo.createTask(TaskIds.YOUR_FEATURE,
76                             oneOffInfo).build();
77 ```
78
79 For a periodic task that executes every 200 minutes, you can call:
80
81 ```java
82 TaskInfo.TimingInfo periodicInfo = TaskInfo.PeriodicInfo.create()
83                                     .setIntervalMs(TimeUnit.MINUTES.toMillis(200)).build();
84 TaskInfo taskInfo = TaskInfo.createTask(TaskIds.YOUR_FEATURE,
85                             periodicInfo).build();
86 ```
87
88 Typically you will also set other required parameters such as what type of
89 network conditions are necessary and whether the task requires the device to
90 be charging. They can be set on the builder like this:
91
92 ```java
93 TaskInfo.TimingInfo oneOffInfo = TaskInfo.OneOffInfo.create()
94                                     .setWindowStartTimeMs(TimeUnit.MINUTES.toMillis(100))
95                                     .setWindowEndTimeMs(TimeUnit.MINUTES.toMillis(200)).build();
96 TaskInfo taskInfo = TaskInfo.createTask(TaskIds.YOUR_FEATURE,
97                             oneOffInfo)
98                           .setRequiresCharging(true)
99                           .setRequiredNetworkType(
100                             TaskInfo.NETWORK_TYPE_UNMETERED)
101                           .build();
102 ```
103
104 Note that the task will be run after `windowEndTimeMs` regardless of whether the
105 prerequisite conditions are met. To work around this, mark the `windowEndTimeMs`
106 to `Integer.MAX_VALUE`.
107
108 When the task is ready for scheduling, you use the
109 `BackgroundTaskSchedulerFactory` to get the current instance of the
110 `BackgroundTaskScheduler` and use it to schedule the job.
111
112 ```java
113 BackgroundTaskSchedulerFactory.getScheduler().schedule(myTaskInfo);
114 ```
115
116 If you ever need to cancel a task, you can do that by calling `cancel`, and
117 passing in the task ID:
118
119 ```java
120 BackgroundTaskSchedulerFactory.getScheduler().cancel(TaskIds.YOUR_FEATURE);
121 ```
122
123 ## Passing task arguments
124
125 A `TaskInfo` supports passing in arguments through a `Bundle`, but only values
126 that can be part of an Android `BaseBundle` are allowed. You can pass them in
127 using the `TaskInfo.Builder`:
128
129 ```java
130 Bundle myBundle = new Bundle();
131 myBundle.putString("foo", "bar");
132 myBundle.putLong("number", 1337L);
133
134 TaskInfo.TimingInfo oneOffInfo = TaskInfo.OneOffInfo.create()
135                                     .setWindowStartTimeMs(TimeUnit.MINUTES.toMillis(100))
136                                     .setWindowEndTimeMs(TimeUnit.MINUTES.toMillis(200)).build();
137 TaskInfo taskInfo = TaskInfo.createTask(TaskIds.YOUR_FEATURE,
138                             oneOffInfo)
139                           .setExtras(myBundle)
140                           .build();
141 ```
142
143 These arguments will be readable for the task through the `TaskParameters`
144 object that is passed to both `onStartTask(...)` and `onStopTask(...)`, by
145 doing the following:
146
147 ```java
148 boolean onStartTask(Context context,
149                     TaskParameters taskParameters,
150                     TaskFinishedCallback callback) {
151   Bundle myExtras = taskParameters.getExtras();
152   // Use |myExtras|.
153   ...
154 }
155 ```
156 For native tasks, the extras are packed into a std::string, It's the caller's
157 responsibility to pack and unpack the task extras correctly into the std::string.
158 We recommend using a proto for consistency.
159
160 ## Performing actions over TimingInfo objects
161
162 To perform actions over the `TimingInfo` objects, based on their implementation, the Visitor design
163 pattern was used. A public interface is exposed for this: `TimingInfoVisitor`. To use this
164 interface, someone should create a class that would look like this:
165
166 ```java
167 class ImplementedActionVisitor implements TaskInfo.TimingInfoVisitor {
168   @Override
169   public void visit(TaskInfo.OneOffInfo oneOffInfo) { ... }
170
171   @Override
172   public void visit(TaskInfo.PeriodicInfo periodicInfo) { ... }
173 }
174 ```
175
176 To use this visitor, someone would make the following calls:
177
178 ```java
179 ImplementedActionVisitor visitor = new ImplementedActionVisitor();
180 myTimingInfo.accept(visitor);
181 ```
182
183 ## Loading Native parts
184
185 Some of the tasks running in the background require native parts of the browser
186 to be initialized. In order to simplify implementation of such tasks, we provide
187 a base `NativeBackgroundTask`
188 [implementation](https://cs.chromium.org/chromium/src/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTask.java)
189 in the browser layer. It requires extending classes to implement 4 methods:
190
191  * `onStartTaskBeforeNativeLoaded(...)` where the background task can decide
192    whether conditions are correct to proceed with native initialization;
193  * `onStartTaskWithNative(...)` where the background task can be sure that
194    native initialization was completed, therefore it can depend on that part of
195    the browser;
196  * `onStopTaskBeforeNativeLoaded(...)` which is delivered to the background task
197    just like `onStopTask(...)` and the native parts of the browser are not
198    loaded;
199  * `onStopTaskWithNative(...)` which is delivered to the background task just
200    like `onStopTask(...)` and the native parts of the browser are loaded.
201
202 While in a normal execution, both `onStart...` methods are called, only one of
203 the stopping methods will be triggered, depending on whether the native parts of
204 the browser are loaded at the time the underlying scheduler decides to stop the
205 task.
206
207 ## Launching Browser process
208
209 After the advent of servicfication in chrome, we have the option of launching a
210 background task in a reduced service manager only mode without the need to
211 launch the full browser process. In order to enable this, you have to override
212 `NativeBackgroundTask#supportsMinimalBrowser` and return true or false
213 depending on whether you want to launch service-manager only mode or full
214 browser.
215
216 ## Background processing
217
218 Even though the `BackgroundTaskScheduler` provides functionality for invoking
219 code while the application is in the background, the `BackgroundTask` instance
220 is still invoked on the application's main thread.
221
222 This means that unless the operation is extremely quick, processing must happen
223 asynchronously, and the call to `onStartTask*(...)` must return before the task
224 has finished processing. In that case, the method should return once the
225 asychronous processing has begun, and invoke the `TaskFinishedCallback` when the
226 processing is finished, which typically happens on a different `Thread`,
227 `Handler`, or by using an `AsyncTask`.
228
229 If at any time the constraints given through the `TaskInfo` object do not hold
230 anymore, or if the system deems it necessary, `onStopTask*(...)` will be
231 invoked, requiring all activity to cease immediately. The task can return true
232 if the task needs to be rescheduled since it was canceled, or false otherwise.
233 Note that onStopTask*() is not invoked if the task itself invokes
234 `TaskFinishedCallback` or if the task is cancelled by the caller.
235
236 **The system will hold a wakelock from the time
237 `onStartTaskBeforeNativeLoaded(...)` is invoked until either the task itself
238 invokes the `TaskFinishedCallback`, or `onStopTask*(...)` is invoked.**