Chromium Code Reviews| 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 |