[BackgroundSync] Use BackgroundTaskScheduler.
Use BackgroundTaskScheduler to wake up Chrome for Android, if the
newly introduced feature flag is enabled.
Bug: 924490
Change-Id: Iaa42ff2c10af4fbb466e8d892ccf626ee1827cd6
Reviewed-on: https://chromium-review.googlesource.com/c/1432840
Commit-Queue: Mugdha Lakhani <[email protected]>
Reviewed-by: Peter Beverloo <[email protected]>
Reviewed-by: Rayan Kanso <[email protected]>
Reviewed-by: David Trainor <[email protected]>
Reviewed-by: Ilya Sherman <[email protected]>
Cr-Commit-Position: refs/heads/master@{#630285}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java
index 847bbbe..c9082077 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java
@@ -105,8 +105,7 @@
protected void onPostExecute(Boolean shouldLaunch) {
callback.run(shouldLaunch);
}
- }
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java
index d34b694..47c1ebe 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java
@@ -14,6 +14,7 @@
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.chrome.browser.background_sync.BackgroundSyncBackgroundTaskScheduler;
import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
import org.chromium.chrome.browser.init.ServiceManagerStartupUtils;
import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge;
@@ -70,6 +71,14 @@
}
private void handleBackgroundSyncEvent(Context context, String tag) {
+ if (ChromeFeatureList.isEnabled(
+ ChromeFeatureList.BACKGROUND_TASK_SCHEDULER_FOR_BACKGROUND_SYNC)) {
+ // If BackgroundTaskScheduler has been used to schedule a background
+ // task for Background Sync, we simply reschedule the existing task(s).
+ BackgroundSyncBackgroundTaskScheduler.getInstance().reschedule();
+ return;
+ }
+
if (!BackgroundSyncLauncher.hasInstance()) {
// Start the browser. The browser's BackgroundSyncManager (for the active profile) will
// start, check the network, and run any necessary sync events. This task runs with a
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 90ccb6b..e938ff6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -168,6 +168,8 @@
public static final String AUTOFILL_MANUAL_FALLBACK_ANDROID = "AutofillManualFallbackAndroid";
public static final String AUTOFILL_REFRESH_STYLE_ANDROID = "AutofillRefreshStyleAndroid";
public static final String AUTOFILL_KEYBOARD_ACCESSORY = "AutofillKeyboardAccessory";
+ public static final String BACKGROUND_TASK_SCHEDULER_FOR_BACKGROUND_SYNC =
+ "BackgroundTaskSchedulerForBackgroundSync";
public static final String CAPTIVE_PORTAL_CERTIFICATE_LIST = "CaptivePortalCertificateList";
public static final String CCT_BACKGROUND_TAB = "CCTBackgroundTab";
public static final String CCT_MODULE = "CCTModule";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java
new file mode 100644
index 0000000..674d4ba
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java
@@ -0,0 +1,76 @@
+// Copyright 2019 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.chrome.browser.background_sync;
+
+import android.content.Context;
+
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.background_task_scheduler.NativeBackgroundTask;
+import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFinishedCallback;
+import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerPrefs;
+import org.chromium.components.background_task_scheduler.TaskIds;
+import org.chromium.components.background_task_scheduler.TaskParameters;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Handles servicing of Background Sync background tasks coming via
+ * background_task_scheduler component.
+ */
+public class BackgroundSyncBackgroundTask extends NativeBackgroundTask {
+ @Override
+ public @StartBeforeNativeResult int onStartTaskBeforeNativeLoaded(
+ Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
+ assert taskParameters.getTaskId() == TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID;
+
+ return StartBeforeNativeResult.LOAD_NATIVE;
+ }
+
+ @Override
+ protected void onStartTaskWithNative(
+ Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
+ // Record the delay from soonest expected wakeup time.
+ long delayFromExpectedMs = System.currentTimeMillis()
+ - taskParameters.getExtras().getLong(
+ BackgroundSyncBackgroundTaskScheduler.SOONEST_EXPECTED_WAKETIME);
+ RecordHistogram.recordLongTimesHistogram(
+ "BackgroundSync.Wakeup.DelayTime", delayFromExpectedMs, TimeUnit.MILLISECONDS);
+
+ // Now that Chrome has been started, BackgroundSyncManager will
+ // eventually be created, and it'll fire any ready sync events.
+ // It'll also schedule a background task with the required delay.
+ // In case Chrome gets closed before native code gets to run,
+ // schedule a task to wake up Chrome with a delay, as a backup. This is
+ // done only if there isn't already a similar task scheduled. This'll
+ // be overwritten by a similar call from BackgroundSyncManager.
+ if (!BackgroundTaskSchedulerPrefs.getScheduledTasks().contains(
+ BackgroundSyncBackgroundTask.class.getName())) {
+ BackgroundSyncBackgroundTaskScheduler.getInstance().scheduleOneShotTask();
+ }
+ callback.taskFinished(true);
+ }
+
+ @Override
+ protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParameters taskParameters) {
+ assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JOB_ID;
+
+ // Native didn't complete loading, but it was supposed to.
+ // Presume we need to reschedule.
+ return true;
+ }
+
+ @Override
+ protected boolean onStopTaskWithNative(Context context, TaskParameters taskParameters) {
+ assert taskParameters.getTaskId() == TaskIds.OFFLINE_PAGES_BACKGROUND_JOB_ID;
+
+ // Don't reschedule again.
+ return false;
+ }
+
+ @Override
+ public void reschedule(Context context) {
+ BackgroundSyncBackgroundTaskScheduler.getInstance().reschedule();
+ }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java
new file mode 100644
index 0000000..75d2b4a
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java
@@ -0,0 +1,111 @@
+// Copyright 2019 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.chrome.browser.background_sync;
+
+import android.os.Bundle;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
+import org.chromium.components.background_task_scheduler.TaskIds;
+import org.chromium.components.background_task_scheduler.TaskInfo;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The {@link BackgroundSyncBackgroundTaskScheduler} singleton is responsible
+ * for scheduling and cancelling background tasks to wake Chrome up so that
+ * Background Sync events ready to be fired can be fired.
+ *
+ * Thread model: This class is to be run on the UI thread only.
+ */
+public class BackgroundSyncBackgroundTaskScheduler {
+ // Keep in sync with the default min_sync_recovery_time of
+ // BackgroundSyncParameters.
+ private static final long MIN_SYNC_RECOVERY_TIME = TimeUnit.MINUTES.toMillis(6);
+
+ // Bundle key for the timestamp of the soonest wakeup time expected for
+ // this task.
+ public static final String SOONEST_EXPECTED_WAKETIME = "SoonestWakeupTime";
+
+ private static class LazyHolder {
+ static final BackgroundSyncBackgroundTaskScheduler INSTANCE =
+ new BackgroundSyncBackgroundTaskScheduler();
+ }
+
+ @CalledByNative
+ public static BackgroundSyncBackgroundTaskScheduler getInstance() {
+ return LazyHolder.INSTANCE;
+ }
+
+ /**
+ * Cancels a task with Id BACKGROUND_SYNC_ONE_SHOT_JOB_ID, if there's one
+ * scheduled.
+ */
+ @VisibleForTesting
+ protected void cancelOneShotTask() {
+ BackgroundTaskSchedulerFactory.getScheduler().cancel(
+ ContextUtils.getApplicationContext(), TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID);
+ }
+
+ /**
+ * Schedules a one-off bakground task to wake the browser up on network
+ * connectivity. There is a delay of of six minutes before waking the
+ * browser.
+ */
+ protected boolean scheduleOneShotTask() {
+ return scheduleOneShotTask(MIN_SYNC_RECOVERY_TIME);
+ }
+
+ /**
+ * Schedules a one-off background task to wake the browser up on network
+ * connectivity and call into native code to fire ready Background Sync
+ * events.
+ * @param minDelayMs The minimum time to wait before waking the browser.
+ */
+ protected boolean scheduleOneShotTask(long minDelayMs) {
+ // Pack SOONEST_EXPECTED_WAKETIME in extras.
+ Bundle taskExtras = new Bundle();
+ taskExtras.putLong(SOONEST_EXPECTED_WAKETIME, System.currentTimeMillis() + minDelayMs);
+
+ TaskInfo taskInfo = TaskInfo.createOneOffTask(TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID,
+ BackgroundSyncBackgroundTask.class, minDelayMs)
+ .setRequiredNetworkType(TaskInfo.NetworkType.ANY)
+ .setUpdateCurrent(true)
+ .setIsPersisted(true)
+ .setExtras(taskExtras)
+ .build();
+ // This will overwrite any existing task with this ID.
+ return BackgroundTaskSchedulerFactory.getScheduler().schedule(
+ ContextUtils.getApplicationContext(), taskInfo);
+ }
+
+ /**
+ * Based on shouldLaunch, either creates or cancels a one-off background task
+ * to wake up Chrome upon network connectivity.
+ * @param shouldLaunch Whether to launch the browser in the background.
+ * @param minDelayMs The minimum time to wait before waking the browser.
+ */
+ @VisibleForTesting
+ @CalledByNative
+ protected void launchBrowserIfStopped(boolean shouldLaunch, long minDelayMs) {
+ if (!shouldLaunch) {
+ cancelOneShotTask();
+ return;
+ }
+
+ scheduleOneShotTask(minDelayMs);
+ }
+
+ /**
+ * Method for rescheduling a background task to wake up Chrome for processing
+ * one-shot Background Sync events in the event of an OS upgrade or
+ * Google Play Services upgrade.
+ */
+ public void reschedule() {
+ scheduleOneShotTask(MIN_SYNC_RECOVERY_TIME);
+ }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/OWNERS
new file mode 100644
index 0000000..59f4eacf
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/OWNERS
@@ -0,0 +1,4 @@
+file://chrome/browser/background_sync/OWNERS
+
+# COMPONENT: Blink>BackgroundSync
+# TEAM: [email protected]
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index b7ed9bbd..4530475 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -171,6 +171,8 @@
"java/src/org/chromium/chrome/browser/autofill_assistant/payment/AutofillAssistantPaymentRequest.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/payment/PaymentRequestBottomBar.java",
"java/src/org/chromium/chrome/browser/autofill_assistant/payment/PaymentRequestUI.java",
+ "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java",
+ "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java",
"java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java",
@@ -2395,6 +2397,7 @@
"junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryTabLayoutControllerTest.java",
"junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingControllerTest.java",
"junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetControllerTest.java",
+ "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskSchedulerTest.java",
"junit/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTaskTest.java",
"junit/src/org/chromium/chrome/browser/browseractions/BrowserActionsIntentTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorderTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BackgroundSyncLauncherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BackgroundSyncLauncherTest.java
index ba68340..47f4b599 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/BackgroundSyncLauncherTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BackgroundSyncLauncherTest.java
@@ -53,11 +53,10 @@
// Use a semaphore to wait for the callback to be called.
final Semaphore semaphore = new Semaphore(0);
- BackgroundSyncLauncher.ShouldLaunchCallback callback =
- shouldLaunch -> {
- mShouldLaunchResult = shouldLaunch;
- semaphore.release();
- };
+ BackgroundSyncLauncher.ShouldLaunchCallback callback = shouldLaunch -> {
+ mShouldLaunchResult = shouldLaunch;
+ semaphore.release();
+ };
BackgroundSyncLauncher.shouldLaunchBrowserIfStopped(callback);
// Wait on the callback to be called.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java
index c412172..c7e9d78 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java
@@ -23,6 +23,8 @@
import org.chromium.chrome.browser.ntp.snippets.SnippetsLauncher;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import java.util.HashMap;
+
/**
* Tests {@link ChromeBackgroundService}.
*/
@@ -78,9 +80,13 @@
@Before
public void setUp() throws Exception {
+ HashMap<String, Boolean> features = new HashMap<String, Boolean>();
+ features.put(ChromeFeatureList.BACKGROUND_TASK_SCHEDULER_FOR_BACKGROUND_SYNC, false);
+ ChromeFeatureList.setTestFeatures(features);
BackgroundSyncLauncher.setGCMEnabled(false);
- RecordHistogram.setDisabledForTests(true);
mSyncLauncher = BackgroundSyncLauncher.create();
+
+ RecordHistogram.setDisabledForTests(true);
mSnippetsLauncher = SnippetsLauncher.create();
mTaskService = new MockTaskService();
}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskSchedulerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskSchedulerTest.java
new file mode 100644
index 0000000..c0804bd
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskSchedulerTest.java
@@ -0,0 +1,151 @@
+// Copyright 2019 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.chrome.browser.background_sync;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.test.support.DisableHistogramsRule;
+import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler;
+import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
+import org.chromium.components.background_task_scheduler.TaskIds;
+import org.chromium.components.background_task_scheduler.TaskInfo;
+
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+
+/** Unit tests for BackgroundSyncBackgroundTaskScheduler. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class BackgroundSyncBackgroundTaskSchedulerTest {
+ @Rule
+ public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsRule();
+
+ @Mock
+ private BackgroundTaskScheduler mTaskScheduler;
+ @Captor
+ ArgumentCaptor<TaskInfo> mTaskInfo;
+
+ private static final long ONE_DAY_IN_MILLISECONDS = TimeUnit.DAYS.toMillis(1);
+ private static final long ONE_WEEK_IN_MILLISECONDS = TimeUnit.DAYS.toMillis(7);
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ BackgroundTaskSchedulerFactory.setSchedulerForTesting(mTaskScheduler);
+ HashMap<String, Boolean> features = new HashMap<String, Boolean>();
+ features.put(ChromeFeatureList.BACKGROUND_TASK_SCHEDULER_FOR_BACKGROUND_SYNC, true);
+ ChromeFeatureList.setTestFeatures(features);
+ doReturn(true)
+ .when(mTaskScheduler)
+ .schedule(eq(RuntimeEnvironment.application), mTaskInfo.capture());
+ }
+
+ private void verifyFixedTaskInfoValues(TaskInfo info) {
+ assertEquals(TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID, info.getTaskId());
+ assertEquals(BackgroundSyncBackgroundTask.class, info.getBackgroundTaskClass());
+ assertTrue(info.isPersisted());
+ assertFalse(info.isPeriodic());
+ assertEquals(TaskInfo.NetworkType.ANY, info.getRequiredNetworkType());
+
+ long expectedSoonestDelayTime = info.getExtras().getLong(
+ BackgroundSyncBackgroundTaskScheduler.SOONEST_EXPECTED_WAKETIME);
+ assertTrue(expectedSoonestDelayTime > 0L);
+ }
+
+ @Test
+ @Feature({"BackgroundSync"})
+ public void testLaunchBrowserIfStopped() {
+ BackgroundSyncBackgroundTaskScheduler.getInstance().launchBrowserIfStopped(
+ /* shouldLaunch= */ true,
+ /* minDelayMs= */ ONE_DAY_IN_MILLISECONDS);
+ verify(mTaskScheduler, times(1))
+ .schedule(eq(RuntimeEnvironment.application), eq(mTaskInfo.getValue()));
+
+ TaskInfo taskInfo = mTaskInfo.getValue();
+ verifyFixedTaskInfoValues(taskInfo);
+
+ assertEquals(ONE_DAY_IN_MILLISECONDS, taskInfo.getOneOffInfo().getWindowEndTimeMs());
+ }
+
+ @Test
+ @Feature({"BackgroundSync"})
+ public void testCancelOneShotTask() {
+ BackgroundSyncBackgroundTaskScheduler.getInstance().launchBrowserIfStopped(
+ /* shouldLaunch= */ true,
+ /* minDelayMs= */ ONE_DAY_IN_MILLISECONDS);
+ verify(mTaskScheduler, times(1))
+ .schedule(eq(RuntimeEnvironment.application), eq(mTaskInfo.getValue()));
+
+ doNothing()
+ .when(mTaskScheduler)
+ .cancel(eq(RuntimeEnvironment.application),
+ eq(TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID));
+
+ BackgroundSyncBackgroundTaskScheduler.getInstance().cancelOneShotTask();
+ verify(mTaskScheduler, times(1))
+ .cancel(eq(RuntimeEnvironment.application),
+ eq(TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID));
+ }
+
+ @Test
+ @Feature({"BackgroundSync"})
+ public void testLaunchBrowserCalledTwice() {
+ BackgroundSyncBackgroundTaskScheduler.getInstance().launchBrowserIfStopped(
+ /* shouldLaunch= */ true,
+ /* minDelayMs= */ ONE_DAY_IN_MILLISECONDS);
+ verify(mTaskScheduler, times(1))
+ .schedule(eq(RuntimeEnvironment.application), eq(mTaskInfo.getValue()));
+
+ TaskInfo taskInfo = mTaskInfo.getValue();
+ assertEquals(ONE_DAY_IN_MILLISECONDS, taskInfo.getOneOffInfo().getWindowEndTimeMs());
+
+ BackgroundSyncBackgroundTaskScheduler.getInstance().launchBrowserIfStopped(
+ /* shouldLaunch= */ true,
+ /* minDelayMs= */ ONE_WEEK_IN_MILLISECONDS);
+ verify(mTaskScheduler, times(1))
+ .schedule(eq(RuntimeEnvironment.application), eq(mTaskInfo.getValue()));
+
+ taskInfo = mTaskInfo.getValue();
+ assertEquals(ONE_WEEK_IN_MILLISECONDS, taskInfo.getOneOffInfo().getWindowEndTimeMs());
+ }
+
+ @Test
+ @Feature({"BackgroundSync"})
+ public void testLaunchBrowserThenCancel() {
+ BackgroundSyncBackgroundTaskScheduler.getInstance().launchBrowserIfStopped(
+ /* shouldLaunch= */ true,
+ /* minDelayMs= */ ONE_DAY_IN_MILLISECONDS);
+ BackgroundSyncBackgroundTaskScheduler.getInstance().launchBrowserIfStopped(
+ /* shouldLaunch= */ false,
+ /* minDelayMs= */ ONE_DAY_IN_MILLISECONDS);
+
+ verify(mTaskScheduler, times(1))
+ .schedule(eq(RuntimeEnvironment.application), eq(mTaskInfo.getValue()));
+ verify(mTaskScheduler, times(1))
+ .cancel(eq(RuntimeEnvironment.application),
+ eq(TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID));
+ }
+}
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index bffa23b..471e41ce 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4877,6 +4877,7 @@
"../android/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java",
"../android/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestDelegate.java",
"../android/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestModel.java",
+ "../android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java",
"../android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
"../android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java",
"../android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java",
diff --git a/chrome/browser/android/background_sync_launcher_android.cc b/chrome/browser/android/background_sync_launcher_android.cc
index e5f58674..7b182c6 100644
--- a/chrome/browser/android/background_sync_launcher_android.cc
+++ b/chrome/browser/android/background_sync_launcher_android.cc
@@ -4,7 +4,10 @@
#include "chrome/browser/android/background_sync_launcher_android.h"
+#include "base/feature_list.h"
+#include "chrome/browser/android/chrome_feature_list.h"
#include "content/public/browser/browser_thread.h"
+#include "jni/BackgroundSyncBackgroundTaskScheduler_jni.h"
#include "jni/BackgroundSyncLauncher_jni.h"
using content::BrowserThread;
@@ -42,8 +45,18 @@
DCHECK_CURRENTLY_ON(BrowserThread::UI);
JNIEnv* env = base::android::AttachCurrentThread();
- Java_BackgroundSyncLauncher_launchBrowserIfStopped(
- env, java_launcher_, launch_when_next_online, min_delay_ms);
+
+ if (!base::FeatureList::IsEnabled(
+ chrome::android::kBackgroundTaskSchedulerForBackgroundSync)) {
+ Java_BackgroundSyncLauncher_launchBrowserIfStopped(
+ env, java_gcm_network_manager_launcher_, launch_when_next_online,
+ min_delay_ms);
+ return;
+ }
+
+ Java_BackgroundSyncBackgroundTaskScheduler_launchBrowserIfStopped(
+ env, java_background_sync_background_task_scheduler_launcher_,
+ launch_when_next_online, min_delay_ms);
}
// static
@@ -67,12 +80,26 @@
DCHECK_CURRENTLY_ON(BrowserThread::UI);
JNIEnv* env = base::android::AttachCurrentThread();
- java_launcher_.Reset(Java_BackgroundSyncLauncher_create(env));
+
+ if (!base::FeatureList::IsEnabled(
+ chrome::android::kBackgroundTaskSchedulerForBackgroundSync)) {
+ java_gcm_network_manager_launcher_.Reset(
+ Java_BackgroundSyncLauncher_create(env));
+ return;
+ }
+
+ java_background_sync_background_task_scheduler_launcher_.Reset(
+ Java_BackgroundSyncBackgroundTaskScheduler_getInstance(env));
}
BackgroundSyncLauncherAndroid::~BackgroundSyncLauncherAndroid() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (base::FeatureList::IsEnabled(
+ chrome::android::kBackgroundTaskSchedulerForBackgroundSync)) {
+ return;
+ }
+
JNIEnv* env = base::android::AttachCurrentThread();
- Java_BackgroundSyncLauncher_destroy(env, java_launcher_);
+ Java_BackgroundSyncLauncher_destroy(env, java_gcm_network_manager_launcher_);
}
diff --git a/chrome/browser/android/background_sync_launcher_android.h b/chrome/browser/android/background_sync_launcher_android.h
index be547a8..0c93da7 100644
--- a/chrome/browser/android/background_sync_launcher_android.h
+++ b/chrome/browser/android/background_sync_launcher_android.h
@@ -40,7 +40,10 @@
void LaunchBrowserIfStoppedImpl(bool launch_when_next_online,
int64_t min_delay_ms);
- base::android::ScopedJavaGlobalRef<jobject> java_launcher_;
+ base::android::ScopedJavaGlobalRef<jobject>
+ java_gcm_network_manager_launcher_;
+ base::android::ScopedJavaGlobalRef<jobject>
+ java_background_sync_background_task_scheduler_launcher_;
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncLauncherAndroid);
};
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 722011e6..ed6aaea 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -92,6 +92,7 @@
&kAndroidPayIntegrationV2,
&kAndroidPaymentApps,
&kAndroidSiteSettingsUIRefresh,
+ &kBackgroundTaskSchedulerForBackgroundSync,
&kCastDeviceFilter,
&kCCTBackgroundTab,
&kCCTExternalLinkHandling,
@@ -229,6 +230,10 @@
const base::Feature kBackgroundTaskComponentUpdate{
"BackgroundTaskComponentUpdate", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kBackgroundTaskSchedulerForBackgroundSync{
+ "BackgroundTaskSchedulerForBackgroundSync",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Used in downstream code.
const base::Feature kCastDeviceFilter{"CastDeviceFilter",
base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index c7997f1..e527f3d 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -20,6 +20,7 @@
extern const base::Feature kAndroidPaymentApps;
extern const base::Feature kAndroidSiteSettingsUIRefresh;
extern const base::Feature kBackgroundTaskComponentUpdate;
+extern const base::Feature kBackgroundTaskSchedulerForBackgroundSync;
extern const base::Feature kCastDeviceFilter;
extern const base::Feature kCCTBackgroundTab;
extern const base::Feature kCCTExternalLinkHandling;