[Background Sync] Allow native processing to finish
sending any pending Background Sync events, before exiting the
background task that woke up the browser.
Bug: 924490
Change-Id: Id63b2d9edeb6e9255dff616ea06f02c9f77cc0d3
Reviewed-on: https://chromium-review.googlesource.com/c/1477707
Commit-Queue: Mugdha Lakhani <[email protected]>
Reviewed-by: Peter Beverloo <[email protected]>
Reviewed-by: Rayan Kanso <[email protected]>
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: David Trainor <[email protected]>
Cr-Commit-Position: refs/heads/master@{#636034}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 76b498f..59b230c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4918,6 +4918,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/BackgroundSyncBackgroundTask.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",
diff --git a/chrome/browser/android/background_sync_launcher_android.cc b/chrome/browser/android/background_sync_launcher_android.cc
index 7b182c6..8eaedf25 100644
--- a/chrome/browser/android/background_sync_launcher_android.cc
+++ b/chrome/browser/android/background_sync_launcher_android.cc
@@ -4,10 +4,19 @@
#include "chrome/browser/android/background_sync_launcher_android.h"
+#include <utility>
+
+#include "base/android/callback_android.h"
+#include "base/barrier_closure.h"
#include "base/feature_list.h"
#include "chrome/browser/android/chrome_feature_list.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "content/public/browser/background_sync_context.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
#include "jni/BackgroundSyncBackgroundTaskScheduler_jni.h"
+#include "jni/BackgroundSyncBackgroundTask_jni.h"
#include "jni/BackgroundSyncLauncher_jni.h"
using content::BrowserThread;
@@ -24,6 +33,18 @@
} // namespace
// static
+void JNI_BackgroundSyncBackgroundTask_FireBackgroundSyncEvents(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& j_runnable) {
+ if (!base::FeatureList::IsEnabled(
+ chrome::android::kBackgroundTaskSchedulerForBackgroundSync)) {
+ return;
+ }
+
+ BackgroundSyncLauncherAndroid::Get()->FireBackgroundSyncEvents(j_runnable);
+}
+
+// static
BackgroundSyncLauncherAndroid* BackgroundSyncLauncherAndroid::Get() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -39,6 +60,22 @@
Get()->LaunchBrowserIfStoppedImpl(launch_when_next_online, min_delay_ms);
}
+// static
+void BackgroundSyncLauncherAndroid::SetPlayServicesVersionCheckDisabledForTests(
+ bool disabled) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ disable_play_services_version_check_for_tests = disabled;
+}
+
+// static
+bool BackgroundSyncLauncherAndroid::ShouldDisableBackgroundSync() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (disable_play_services_version_check_for_tests)
+ return false;
+ return Java_BackgroundSyncLauncher_shouldDisableBackgroundSync(
+ base::android::AttachCurrentThread());
+}
+
void BackgroundSyncLauncherAndroid::LaunchBrowserIfStoppedImpl(
bool launch_when_next_online,
int64_t min_delay_ms) {
@@ -59,21 +96,57 @@
launch_when_next_online, min_delay_ms);
}
-// static
-void BackgroundSyncLauncherAndroid::SetPlayServicesVersionCheckDisabledForTests(
- bool disabled) {
+void BackgroundSyncLauncherAndroid::FireBackgroundSyncEvents(
+ const base::android::JavaParamRef<jobject>& j_runnable) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- disable_play_services_version_check_for_tests = disabled;
+
+ auto* profile = ProfileManager::GetLastUsedProfile();
+ DCHECK(profile);
+
+ int num_partitions = 0;
+ content::BrowserContext::ForEachStoragePartition(
+ profile, base::BindRepeating(
+ [](int* num_partitions,
+ content::StoragePartition* storage_partition) {
+ (*num_partitions)++;
+ },
+ &num_partitions));
+
+ // This class is a singleton, which is only destructed on program exit.
+ // Therefore, use of base::Unretained(this) is safe.
+ base::RepeatingClosure done_closure = base::BarrierClosure(
+ num_partitions,
+ base::BindOnce(base::android::RunRunnableAndroid,
+ base::android::ScopedJavaGlobalRef<jobject>(j_runnable)));
+
+ content::BrowserContext::ForEachStoragePartition(
+ profile,
+ base::BindRepeating(&BackgroundSyncLauncherAndroid::
+ FireBackgroundSyncEventsForStoragePartition,
+ base::Unretained(this), done_closure));
}
-// static
-bool BackgroundSyncLauncherAndroid::ShouldDisableBackgroundSync() {
+void BackgroundSyncLauncherAndroid::FireBackgroundSyncEventsForStoragePartition(
+ base::OnceClosure done_closure,
+ content::StoragePartition* storage_partition) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (disable_play_services_version_check_for_tests) {
- return false;
+
+ content::BackgroundSyncContext* sync_context =
+ storage_partition->GetBackgroundSyncContext();
+ if (!sync_context) {
+ std::move(done_closure).Run();
+ return;
}
- return Java_BackgroundSyncLauncher_shouldDisableBackgroundSync(
- base::android::AttachCurrentThread());
+
+ sync_context->FireBackgroundSyncEventsForStoragePartition(
+ storage_partition, std::move(done_closure));
+}
+
+void BackgroundSyncLauncherAndroid::OnFiredBackgroundSyncEvents(
+ base::android::ScopedJavaGlobalRef<jobject> j_runnable) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ base::android::RunRunnableAndroid(j_runnable);
}
BackgroundSyncLauncherAndroid::BackgroundSyncLauncherAndroid() {
diff --git a/chrome/browser/android/background_sync_launcher_android.h b/chrome/browser/android/background_sync_launcher_android.h
index 0c93da7..1afb9bae 100644
--- a/chrome/browser/android/background_sync_launcher_android.h
+++ b/chrome/browser/android/background_sync_launcher_android.h
@@ -10,9 +10,14 @@
#include <set>
#include "base/android/jni_android.h"
+#include "base/callback_forward.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
+namespace content {
+class StoragePartition;
+} // namespace content
+
// The BackgroundSyncLauncherAndroid singleton owns the Java
// BackgroundSyncLauncher object and is used to register interest in starting
// the browser the next time the device goes online. This class runs on the UI
@@ -30,6 +35,11 @@
// updated before every test run. (https://crbug.com/514449)
static void SetPlayServicesVersionCheckDisabledForTests(bool disabled);
+ // Fires all pending Background Sync events across all storage partitions
+ // for the last used profile.
+ void FireBackgroundSyncEvents(
+ const base::android::JavaParamRef<jobject>& j_runnable);
+
private:
friend struct base::LazyInstanceTraitsBase<BackgroundSyncLauncherAndroid>;
@@ -39,11 +49,17 @@
void LaunchBrowserIfStoppedImpl(bool launch_when_next_online,
int64_t min_delay_ms);
+ void FireBackgroundSyncEventsForStoragePartition(
+ base::OnceClosure done_closure,
+ content::StoragePartition* storage_partition);
+ void OnFiredBackgroundSyncEvents(
+ base::android::ScopedJavaGlobalRef<jobject> j_runnable);
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);
};