Index: components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskGcmTaskService.java |
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskGcmTaskService.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskGcmTaskService.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4b4ab72d78a0ade447a2dc15b61d54c9496a15eb |
--- /dev/null |
+++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskGcmTaskService.java |
@@ -0,0 +1,114 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.components.background_task_scheduler; |
+ |
+import com.google.android.gms.gcm.GcmNetworkManager; |
+import com.google.android.gms.gcm.GcmTaskService; |
+import com.google.android.gms.gcm.TaskParams; |
+ |
+import org.chromium.base.ContextUtils; |
+import org.chromium.base.Log; |
+import org.chromium.base.ThreadUtils; |
+ |
+import java.util.concurrent.CountDownLatch; |
+import java.util.concurrent.TimeUnit; |
+ |
+/** Delegates calls out to various tasks that need to run in the background. */ |
+public class BackgroundTaskGcmTaskService extends GcmTaskService { |
+ private static final String TAG = "BkgrdTaskGcmTS"; |
+ |
+ /** Class that waits for the processing to be done. */ |
+ private static class Waiter { |
+ // Wakelock is only held for 3 minutes by default for GcmTaskService. |
+ private static final long MAX_TIMEOUT_SECONDS = 179; |
+ private final CountDownLatch mLatch; |
+ private long mWaiterTimeoutSeconds; |
+ private boolean mIsRescheduleNeeded; |
+ private boolean mHasTaskTimedOut; |
+ |
+ public Waiter(long waiterTimeoutSeconds) { |
+ mLatch = new CountDownLatch(1); |
+ mWaiterTimeoutSeconds = Math.min(waiterTimeoutSeconds, MAX_TIMEOUT_SECONDS); |
+ } |
+ |
+ /** Start waiting for the processing to finish. */ |
+ public void startWaiting() { |
+ try { |
+ mHasTaskTimedOut = !mLatch.await(mWaiterTimeoutSeconds, TimeUnit.SECONDS); |
+ } catch (InterruptedException e) { |
+ Log.d(TAG, "Waiter interrupted while waiting."); |
+ } |
+ } |
+ |
+ /** Called to finish waiting. */ |
+ public void onWaitDone(boolean needsRescheduling) { |
+ mIsRescheduleNeeded = needsRescheduling; |
+ mLatch.countDown(); |
+ } |
+ |
+ /** @return Whether last task timed out. */ |
+ public boolean hasTaskTimedOut() { |
+ return mHasTaskTimedOut; |
+ } |
+ |
+ /** @return Whether task needs to be rescheduled. */ |
+ public boolean isRescheduleNeeded() { |
+ return mIsRescheduleNeeded; |
+ } |
+ } |
+ |
+ private static class TaskFinishedCallbackGcmTaskService |
+ implements BackgroundTask.TaskFinishedCallback { |
+ private final Waiter mWaiter; |
+ |
+ public TaskFinishedCallbackGcmTaskService(Waiter waiter) { |
+ mWaiter = waiter; |
+ } |
+ |
+ @Override |
+ public void taskFinished(final boolean needsReschedule) { |
+ // TODO(fgorski): Does this need to happen on UI thread? |
fgorski
2017/04/11 19:42:10
Tommy?
nyquist
2017/04/18 21:58:28
This will set Waiter#mIsRescheduleNeeded, which is
fgorski
2017/04/20 05:54:15
I'll keep it consistent with conceptual presumptio
|
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
+ @Override |
+ public void run() { |
+ mWaiter.onWaitDone(needsReschedule); |
+ } |
+ }); |
+ } |
+ } |
+ |
+ @Override |
+ public int onRunTask(TaskParams params) { |
+ ThreadUtils.assertOnUiThread(); |
+ BackgroundTask backgroundTask = |
+ BackgroundTaskSchedulerGcmNetworkManager.getBackgroundTaskFromTaskParams(params); |
+ if (backgroundTask == null) { |
+ Log.w(TAG, "Failed to start task. Could not instantiate class."); |
+ return GcmNetworkManager.RESULT_FAILURE; |
+ } |
+ |
+ TaskParameters taskParams = |
+ BackgroundTaskSchedulerGcmNetworkManager.getTaskParametersFromTaskParams(params); |
+ Waiter waiter = new Waiter(Waiter.MAX_TIMEOUT_SECONDS); |
+ boolean taskNeedsBackgroundProcessing = |
+ backgroundTask.onStartTask(ContextUtils.getApplicationContext(), taskParams, |
+ new TaskFinishedCallbackGcmTaskService(waiter)); |
+ |
+ if (taskNeedsBackgroundProcessing) { |
nyquist
2017/04/18 21:58:28
I did try looking at making this less indented by:
fgorski
2017/04/20 05:54:15
I split the big if into 3 statements. Let me know
|
+ waiter.startWaiting(); |
nyquist
2017/04/18 21:58:28
I can't see from the documentation at https://deve
fgorski
2017/04/20 05:54:15
I'll test it and will get back to you. Perhaps my
nyquist
2017/04/25 20:44:15
Did you figure out which thread this runs on?
fgorski
2017/04/26 17:22:35
Done. Running on blocking ui thread now.
|
+ if (waiter.isRescheduleNeeded() |
+ || (waiter.hasTaskTimedOut() |
+ && backgroundTask.onStopTask( |
+ ContextUtils.getApplicationContext(), taskParams))) { |
+ return GcmNetworkManager.RESULT_RESCHEDULE; |
+ } |
+ } |
+ |
+ return GcmNetworkManager.RESULT_SUCCESS; |
+ } |
+ |
+ @Override |
+ public void onInitializeTasks() {} |
+} |