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.chrome.browser.background_task_scheduler; | |
6 | |
7 import android.content.Context; | |
8 import android.support.annotation.IntDef; | |
9 | |
10 import org.chromium.base.Log; | |
11 import org.chromium.base.ThreadUtils; | |
12 import org.chromium.base.library_loader.LibraryProcessType; | |
13 import org.chromium.base.library_loader.ProcessInitException; | |
14 import org.chromium.chrome.browser.init.BrowserParts; | |
15 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | |
16 import org.chromium.chrome.browser.init.EmptyBrowserParts; | |
17 import org.chromium.components.background_task_scheduler.BackgroundTask; | |
18 import org.chromium.components.background_task_scheduler.TaskParameters; | |
19 import org.chromium.content.browser.BrowserStartupController; | |
20 | |
21 import java.lang.annotation.Retention; | |
22 import java.lang.annotation.RetentionPolicy; | |
23 | |
24 /** | |
25 * Base class implementing {@link BackgroundTask} that adds native initializatio n, ensuring that | |
26 * tasks are run after Chrome is successfully started. | |
27 * Background tasks that require native parts of browser to be started should ex tend this class | |
28 * instead of implementing the interface directly. {@link #onStartTaskWithNative (Context, | |
29 * TaskParameters, TaskFinishedCallback)} method should be implemented instead o f {@link | |
30 * #onStartTask(Context, TaskParameters, TaskFinishedCallback)}. | |
Ted C
2017/05/23 20:52:55
I'd argue the last sentence isn't necessary, onSta
fgorski
2017/05/23 21:35:02
Done.
| |
31 */ | |
32 public abstract class NativeBackgroundTask implements BackgroundTask { | |
33 private static final String TAG = "BTS_NativeBkgrdTask"; | |
34 | |
35 /** Specifies which action to take following onStartTaskBeforeNativeLoaded. */ | |
36 @Retention(RetentionPolicy.SOURCE) | |
37 @IntDef({LOAD_NATIVE, RESCHEDULE, DONE}) | |
38 public @interface StartBeforeNativeResult {} | |
39 /** Task should continue to load native parts of browser. */ | |
40 public static final int LOAD_NATIVE = 0; | |
41 /** Task should request rescheduling, without loading native parts of browse r. */ | |
42 public static final int RESCHEDULE = 1; | |
43 /** Task should neither load native parts of browser nor reschedule. */ | |
44 public static final int DONE = 2; | |
45 | |
46 protected NativeBackgroundTask() {} | |
47 | |
48 private boolean mTaskStopped; | |
nyquist
2017/05/23 20:14:28
Nit: Could you add a comment that this must only e
fgorski
2017/05/23 21:35:02
Done.
| |
49 | |
50 @Override | |
51 public final boolean onStartTask( | |
52 Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { | |
53 @StartBeforeNativeResult | |
54 int beforeNativeResult = onStartTaskBeforeNativeLoaded(context, taskPara meters, callback); | |
55 | |
56 if (beforeNativeResult == DONE) return false; | |
57 | |
58 if (beforeNativeResult == RESCHEDULE) { | |
59 ThreadUtils.postOnUiThread(buildRescheduleRunnable(callback)); | |
60 return true; | |
61 } | |
62 | |
63 assert beforeNativeResult == LOAD_NATIVE; | |
64 runWithNative(context, buildStartWithNativeRunnable(context, taskParamet ers, callback), | |
65 buildRescheduleRunnable(callback)); | |
66 return true; | |
67 } | |
68 | |
69 @Override | |
70 public final boolean onStopTask(Context context, TaskParameters taskParamete rs) { | |
71 mTaskStopped = true; | |
72 if (isNativeLoaded()) { | |
73 return onStopTaskWithNative(context, taskParameters); | |
74 } else { | |
75 return onStopTaskBeforeNativeLoaded(context, taskParameters); | |
76 } | |
77 } | |
78 | |
79 /** | |
80 * Ensure that native is started before running the task. If native fails to start, the task is | |
81 * going to be rescheduled, by issuing a {@see TaskFinishedCallback} with pa rameter set to | |
82 * <c>true</c>. | |
83 * | |
84 * @param context the current context | |
85 * @param startWithNativeRunnable A runnable that will execute #onStartTaskW ithNative, after the | |
86 * native is loaded. | |
87 * @param rescheduleRunnable A runnable that will be called to reschedule th e task in case | |
88 * native initialization fails. | |
89 */ | |
90 protected final void runWithNative(final Context context, | |
91 final Runnable startWithNativeRunnable, final Runnable rescheduleRun nable) { | |
92 if (isNativeLoaded()) { | |
93 ThreadUtils.postOnUiThread(startWithNativeRunnable); | |
94 return; | |
95 } | |
96 | |
97 final BrowserParts parts = new EmptyBrowserParts() { | |
98 @Override | |
99 public void finishNativeInitialization() { | |
100 startWithNativeRunnable.run(); | |
101 } | |
102 @Override | |
103 public void onStartupFailure() { | |
104 rescheduleRunnable.run(); | |
105 } | |
106 }; | |
107 | |
108 ThreadUtils.postOnUiThread(new Runnable() { | |
109 @Override | |
110 public void run() { | |
111 try { | |
112 ChromeBrowserInitializer.getInstance(context).handlePreNativ eStartup(parts); | |
Ted C
2017/05/23 20:52:55
Should this do:
if (mTaskStopped) return;
fgorski
2017/05/23 21:35:02
I am putting it before the try, presuming you didn
Ted C
2017/05/23 22:06:43
Nope, that's right
| |
113 ChromeBrowserInitializer.getInstance(context).handlePostNati veStartup( | |
114 true /* isAsync */, parts); | |
115 } catch (ProcessInitException e) { | |
116 Log.e(TAG, "ProcessInitException while starting the browser process."); | |
117 if (!mTaskStopped) { | |
118 rescheduleRunnable.run(); | |
119 } | |
120 return; | |
121 } | |
122 } | |
123 }); | |
124 } | |
125 | |
126 /** | |
127 * Method that should be implemented in derived classes to provide implement ation of {@link | |
128 * BackgroundTask#onStartTask(Context, TaskParameters, TaskFinishedCallback) } run before native | |
129 * is loaded. Task implementing the method may decide to not load native if it hasn't been | |
130 * loaded yet, by returning DONE, meaning no more work is required for the t ask, or RESCHEDULE, | |
131 * meaning task needs to be immediately rescheduled. | |
132 * This method is guaranteed to be called before {@link #onStartTaskWithNati ve}. | |
133 */ | |
134 @StartBeforeNativeResult | |
135 protected abstract int onStartTaskBeforeNativeLoaded( | |
136 Context context, TaskParameters taskParameters, TaskFinishedCallback callback); | |
137 | |
138 /** | |
139 * Method that should be implemented in derived classes to provide implement ation of {@link | |
140 * BackgroundTask#onStartTask(Context, TaskParameters, TaskFinishedCallback) } when native is | |
141 * loaded. | |
142 * This method will not be called unless {@link #onStartTaskBeforeNativeLoad ed} returns | |
143 * LOAD_NATIVE. | |
144 */ | |
145 protected abstract void onStartTaskWithNative( | |
146 Context context, TaskParameters taskParameters, TaskFinishedCallback callback); | |
147 | |
148 /** Called by {@link #onStopTask} if native part of browser was not loaded. */ | |
149 protected abstract boolean onStopTaskBeforeNativeLoaded( | |
150 Context context, TaskParameters taskParameters); | |
151 | |
152 /** Called by {@link #onStopTask} if native part of browser was loaded. */ | |
153 protected abstract boolean onStopTaskWithNative(Context context, TaskParamet ers taskParameters); | |
154 | |
155 /** Builds a runnable rescheduling task. */ | |
156 private Runnable buildRescheduleRunnable(final TaskFinishedCallback callback ) { | |
157 return new Runnable() { | |
158 @Override | |
159 public void run() { | |
160 callback.taskFinished(true); | |
Ted C
2017/05/23 20:52:55
Same question as above. Should this do:
if (mTas
fgorski
2017/05/23 21:35:02
Done.
Good point. I went ahead and added checks in
| |
161 } | |
162 }; | |
163 } | |
164 | |
165 /** Builds a runnable starting task with native portion. */ | |
166 private Runnable buildStartWithNativeRunnable(final Context context, | |
167 final TaskParameters taskParameters, final TaskFinishedCallback call back) { | |
168 return new Runnable() { | |
169 @Override | |
170 public void run() { | |
171 onStartTaskWithNative(context, taskParameters, callback); | |
Ted C
2017/05/23 20:52:55
same about mTaskStopped?
fgorski
2017/05/23 21:35:02
Done.
| |
172 } | |
173 }; | |
174 } | |
175 | |
176 /** Whether the native part of the browser is loaded. */ | |
177 private boolean isNativeLoaded() { | |
178 return BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) | |
179 .isStartupSuccessfullyCompleted(); | |
180 } | |
181 } | |
OLD | NEW |