OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser; | 5 package org.chromium.chrome.browser; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.os.Bundle; | |
9 | 8 |
10 import com.google.android.gms.gcm.GcmNetworkManager; | 9 import com.google.android.gms.gcm.GcmNetworkManager; |
11 import com.google.android.gms.gcm.GcmTaskService; | 10 import com.google.android.gms.gcm.GcmTaskService; |
12 import com.google.android.gms.gcm.TaskParams; | 11 import com.google.android.gms.gcm.TaskParams; |
13 | 12 |
14 import org.chromium.base.Log; | 13 import org.chromium.base.Log; |
15 import org.chromium.base.ThreadUtils; | 14 import org.chromium.base.ThreadUtils; |
16 import org.chromium.base.VisibleForTesting; | 15 import org.chromium.base.VisibleForTesting; |
17 import org.chromium.base.annotations.SuppressFBWarnings; | 16 import org.chromium.base.annotations.SuppressFBWarnings; |
18 import org.chromium.base.library_loader.LibraryProcessType; | |
19 import org.chromium.base.library_loader.ProcessInitException; | 17 import org.chromium.base.library_loader.ProcessInitException; |
20 import org.chromium.chrome.browser.download.DownloadResumptionScheduler; | 18 import org.chromium.chrome.browser.download.DownloadResumptionScheduler; |
21 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | 19 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; |
22 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; | 20 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; |
23 import org.chromium.chrome.browser.ntp.snippets.SnippetsLauncher; | 21 import org.chromium.chrome.browser.ntp.snippets.SnippetsLauncher; |
24 import org.chromium.chrome.browser.offlinepages.BackgroundOfflinerTask; | |
25 import org.chromium.chrome.browser.offlinepages.BackgroundScheduler; | 22 import org.chromium.chrome.browser.offlinepages.BackgroundScheduler; |
26 import org.chromium.chrome.browser.offlinepages.BackgroundSchedulerProcessorImpl ; | |
27 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; | 23 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; |
28 import org.chromium.chrome.browser.precache.PrecacheController; | 24 import org.chromium.chrome.browser.precache.PrecacheController; |
29 import org.chromium.chrome.browser.precache.PrecacheUMA; | 25 import org.chromium.chrome.browser.precache.PrecacheUMA; |
30 import org.chromium.content.browser.BrowserStartupController; | |
31 | 26 |
32 /** | 27 /** |
33 * {@link ChromeBackgroundService} is scheduled through the {@link GcmNetworkMan ager} when the | 28 * {@link ChromeBackgroundService} is scheduled through the {@link GcmNetworkMan ager} when the |
34 * browser needs to be launched for scheduled tasks, or in response to changing network or power | 29 * browser needs to be launched for scheduled tasks, or in response to changing network or power |
35 * conditions. | 30 * conditions. |
36 * | |
37 * If HOLD_WAKELOCK is set to true in a bundle in the task params, then the Chro meBackgroundService | |
Pete Williamson
2017/05/24 21:41:02
How come we don't need a wakelock anymore? (and w
fgorski
2017/05/24 23:10:12
Offline pages was the only code that used it and c
| |
38 * will wait until the task reports done before returning control to the {@link GcmNetworkManager}. | |
39 * This both guarantees that the wakelock keeps chrome awake and that the GcmNet workManager does not | |
40 * start another task in place of the one just started. The GcmNetworkManager c an start more than | |
41 * one task concurrently, thought, so it does not guarantee that a different tas k won't start. | |
42 */ | 31 */ |
43 public class ChromeBackgroundService extends GcmTaskService { | 32 public class ChromeBackgroundService extends GcmTaskService { |
44 private static final String TAG = "BackgroundService"; | 33 private static final String TAG = "BackgroundService"; |
45 /** Bundle key to use to specify we should block the GcmNetworkManager threa d until the task on | |
46 * the UI thread is done before returning to the GcmNetworkManager. | |
47 */ | |
48 public static final String HOLD_WAKELOCK = "HoldWakelock"; | |
49 // GCM will return our wakelock after 3 minutes, we should be a second less than that. | |
50 private static final int WAKELOCK_TIMEOUT_SECONDS = 3 * 60 - 1; | |
51 | |
52 private BackgroundOfflinerTask mBackgroundOfflinerTask; | |
53 | 34 |
54 @Override | 35 @Override |
55 @VisibleForTesting | 36 @VisibleForTesting |
56 public int onRunTask(final TaskParams params) { | 37 public int onRunTask(final TaskParams params) { |
57 final String taskTag = params.getTag(); | 38 final String taskTag = params.getTag(); |
58 Log.i(TAG, "[" + taskTag + "] Woken up at " + new java.util.Date().toStr ing()); | 39 Log.i(TAG, "[" + taskTag + "] Woken up at " + new java.util.Date().toStr ing()); |
59 final ChromeBackgroundServiceWaiter waiter = getWaiterIfNeeded(params.ge tExtras()); | |
60 final Context context = this; | 40 final Context context = this; |
61 ThreadUtils.runOnUiThread(new Runnable() { | 41 ThreadUtils.runOnUiThread(new Runnable() { |
62 @Override | 42 @Override |
63 public void run() { | 43 public void run() { |
64 switch (taskTag) { | 44 switch (taskTag) { |
65 case BackgroundSyncLauncher.TASK_TAG: | 45 case BackgroundSyncLauncher.TASK_TAG: |
66 handleBackgroundSyncEvent(context, taskTag); | 46 handleBackgroundSyncEvent(context, taskTag); |
67 break; | 47 break; |
68 | 48 |
69 case OfflinePageUtils.TASK_TAG: | 49 case OfflinePageUtils.TASK_TAG: |
70 handleOfflinePageBackgroundLoad( | 50 // Offline pages are migrating to BackgroundTaskSchedule r, therefor getting |
Pete Williamson
2017/05/24 21:41:02
nit: therefor -> therefore
fgorski
2017/05/24 23:10:12
Done.
| |
71 context, params.getExtras(), waiter, taskTag); | 51 // a task through ChromeBackgroundSerivce should cause a rescheduling using |
52 // the new component. | |
53 rescheduleOfflinePages(); | |
72 break; | 54 break; |
73 | 55 |
74 case SnippetsLauncher.TASK_TAG_WIFI: | 56 case SnippetsLauncher.TASK_TAG_WIFI: |
75 case SnippetsLauncher.TASK_TAG_FALLBACK: | 57 case SnippetsLauncher.TASK_TAG_FALLBACK: |
76 handleFetchSnippets(context, taskTag); | 58 handleFetchSnippets(context, taskTag); |
77 break; | 59 break; |
78 | 60 |
79 case PrecacheController.PERIODIC_TASK_TAG: | 61 case PrecacheController.PERIODIC_TASK_TAG: |
80 case PrecacheController.CONTINUATION_TASK_TAG: | 62 case PrecacheController.CONTINUATION_TASK_TAG: |
81 handlePrecache(context, taskTag); | 63 handlePrecache(context, taskTag); |
82 break; | 64 break; |
83 | 65 |
84 case DownloadResumptionScheduler.TASK_TAG: | 66 case DownloadResumptionScheduler.TASK_TAG: |
85 DownloadResumptionScheduler.getDownloadResumptionSchedul er( | 67 DownloadResumptionScheduler.getDownloadResumptionSchedul er( |
86 context.getApplicationContext()).handleDownloadR esumption(); | 68 context.getApplicationContext()).handleDownloadR esumption(); |
87 break; | 69 break; |
88 | 70 |
89 default: | 71 default: |
90 Log.i(TAG, "Unknown task tag " + taskTag); | 72 Log.i(TAG, "Unknown task tag " + taskTag); |
91 break; | 73 break; |
92 } | 74 } |
93 } | 75 } |
94 }); | 76 }); |
95 // If needed, block the GcmNetworkManager thread until the UI thread has finished its work. | |
96 waitForTaskIfNeeded(waiter); | |
97 | 77 |
98 return GcmNetworkManager.RESULT_SUCCESS; | 78 return GcmNetworkManager.RESULT_SUCCESS; |
99 } | 79 } |
100 | 80 |
101 private void handleBackgroundSyncEvent(Context context, String tag) { | 81 private void handleBackgroundSyncEvent(Context context, String tag) { |
102 if (!BackgroundSyncLauncher.hasInstance()) { | 82 if (!BackgroundSyncLauncher.hasInstance()) { |
103 // Start the browser. The browser's BackgroundSyncManager (for the a ctive profile) will | 83 // Start the browser. The browser's BackgroundSyncManager (for the a ctive profile) will |
104 // start, check the network, and run any necessary sync events. This task runs with a | 84 // start, check the network, and run any necessary sync events. This task runs with a |
105 // wake lock, but has a three minute timeout, so we need to start th e browser in its | 85 // wake lock, but has a three minute timeout, so we need to start th e browser in its |
106 // own task. | 86 // own task. |
(...skipping 30 matching lines...) Expand all Loading... | |
137 @VisibleForTesting | 117 @VisibleForTesting |
138 protected boolean hasPrecacheInstance() { | 118 protected boolean hasPrecacheInstance() { |
139 return PrecacheController.hasInstance(); | 119 return PrecacheController.hasInstance(); |
140 } | 120 } |
141 | 121 |
142 @VisibleForTesting | 122 @VisibleForTesting |
143 protected void precache(Context context, String tag) { | 123 protected void precache(Context context, String tag) { |
144 PrecacheController.get(context).precache(tag); | 124 PrecacheController.get(context).precache(tag); |
145 } | 125 } |
146 | 126 |
147 private void handleOfflinePageBackgroundLoad( | |
148 Context context, Bundle bundle, ChromeBackgroundServiceWaiter waiter , String tag) { | |
149 if (!BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) | |
150 .isStartupSuccessfullyCompleted()) { | |
151 launchBrowser(context, tag); | |
152 } | |
153 | |
154 // Call BackgroundTask, provide context. | |
155 if (mBackgroundOfflinerTask == null) { | |
156 mBackgroundOfflinerTask = | |
157 new BackgroundOfflinerTask(new BackgroundSchedulerProcessorI mpl()); | |
158 } | |
159 mBackgroundOfflinerTask.startBackgroundRequests(context, bundle, waiter) ; | |
160 } | |
161 | |
162 /** | |
163 * If the bundle contains the special HOLD_WAKELOCK key set to true, then we create a | |
164 * CountDownLatch for use later in the wait step, and set its initial count to one. | |
165 */ | |
166 @VisibleForTesting | |
167 public ChromeBackgroundServiceWaiter getWaiterIfNeeded(Bundle bundle) { | |
168 // If wait_needed is set to true, wait. | |
169 if (bundle != null && bundle.getBoolean(HOLD_WAKELOCK, false)) { | |
170 return new ChromeBackgroundServiceWaiter(WAKELOCK_TIMEOUT_SECONDS); | |
171 } | |
172 return null; | |
173 } | |
174 | |
175 /** | |
176 * Some tasks need to block the GcmNetworkManager thread (and thus hold the wake lock) until the | |
177 * task is done. If we have a waiter, then start waiting. | |
178 */ | |
179 @VisibleForTesting | |
180 public void waitForTaskIfNeeded(ChromeBackgroundServiceWaiter waiter) { | |
181 if (waiter != null) { | |
182 // Block current thread until the onWaitDone method is called, or a timeout occurs. | |
183 waiter.startWaiting(); | |
184 } | |
185 } | |
186 | |
187 @VisibleForTesting | 127 @VisibleForTesting |
188 @SuppressFBWarnings("DM_EXIT") | 128 @SuppressFBWarnings("DM_EXIT") |
189 protected void launchBrowser(Context context, String tag) { | 129 protected void launchBrowser(Context context, String tag) { |
190 Log.i(TAG, "Launching browser"); | 130 Log.i(TAG, "Launching browser"); |
191 try { | 131 try { |
192 ChromeBrowserInitializer.getInstance(this).handleSynchronousStartup( ); | 132 ChromeBrowserInitializer.getInstance(this).handleSynchronousStartup( ); |
193 } catch (ProcessInitException e) { | 133 } catch (ProcessInitException e) { |
194 Log.e(TAG, "ProcessInitException while starting the browser process" ); | 134 Log.e(TAG, "ProcessInitException while starting the browser process" ); |
195 switch (tag) { | 135 switch (tag) { |
196 case PrecacheController.PERIODIC_TASK_TAG: | 136 case PrecacheController.PERIODIC_TASK_TAG: |
(...skipping 23 matching lines...) Expand all Loading... | |
220 | 160 |
221 private void rescheduleSnippetsTasksOnUpgrade() { | 161 private void rescheduleSnippetsTasksOnUpgrade() { |
222 if (SnippetsLauncher.shouldRescheduleTasksOnUpgrade()) { | 162 if (SnippetsLauncher.shouldRescheduleTasksOnUpgrade()) { |
223 if (!SnippetsLauncher.hasInstance()) { | 163 if (!SnippetsLauncher.hasInstance()) { |
224 launchBrowser(this, /*tag=*/""); // The |tag| doesn't matter her e. | 164 launchBrowser(this, /*tag=*/""); // The |tag| doesn't matter her e. |
225 } | 165 } |
226 rescheduleFetching(); | 166 rescheduleFetching(); |
227 } | 167 } |
228 } | 168 } |
229 | 169 |
230 protected void rescheduleOfflinePagesTasksOnUpgrade() { | 170 /** Reschedules offline pages (using appropriate version of Background Task Scheduler). */ |
231 BackgroundScheduler.getInstance(this).rescheduleOfflinePagesTasksOnUpgra de(); | 171 protected void rescheduleOfflinePages() { |
172 BackgroundScheduler.getInstance().reschedule(); | |
232 } | 173 } |
233 | 174 |
234 @Override | 175 @Override |
235 public void onInitializeTasks() { | 176 public void onInitializeTasks() { |
236 rescheduleBackgroundSyncTasksOnUpgrade(); | 177 rescheduleBackgroundSyncTasksOnUpgrade(); |
237 reschedulePrecacheTasksOnUpgrade(); | 178 reschedulePrecacheTasksOnUpgrade(); |
238 rescheduleSnippetsTasksOnUpgrade(); | 179 rescheduleSnippetsTasksOnUpgrade(); |
239 rescheduleOfflinePagesTasksOnUpgrade(); | |
240 } | 180 } |
241 } | 181 } |
OLD | NEW |