[BackgroundSync] Componentize BackgroundSyncControllerImpl.
Bug: 1087486, 1091211
Change-Id: I9c4ed3d09cce8c9e4fc7e708f1c94b990d8e93af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2454169
Reviewed-by: Alexei Svitkine <[email protected]>
Reviewed-by: Colin Blundell <[email protected]>
Reviewed-by: Josh Karlin <[email protected]>
Commit-Queue: Alexei Svitkine <[email protected]>
Auto-Submit: Mugdha Lakhani <[email protected]>
Cr-Commit-Position: refs/heads/master@{#815153}
diff --git a/components/background_sync/BUILD.gn b/components/background_sync/BUILD.gn
index 3b0f0745..6a3f3309 100644
--- a/components/background_sync/BUILD.gn
+++ b/components/background_sync/BUILD.gn
@@ -4,6 +4,8 @@
static_library("background_sync") {
sources = [
+ "background_sync_controller_impl.cc",
+ "background_sync_controller_impl.h",
"background_sync_delegate.h",
"background_sync_metrics.cc",
"background_sync_metrics.h",
@@ -15,9 +17,14 @@
"//components/content_settings/core/browser",
"//components/content_settings/core/common",
"//components/permissions",
+ "//components/variations",
+ "//content/public/browser",
"//services/metrics/public/cpp:ukm_builders",
"//third_party/blink/public/common:headers",
]
+ if (!is_android) {
+ deps += [ "//components/keep_alive_registry" ]
+ }
}
source_set("unit_tests") {
diff --git a/components/background_sync/DEPS b/components/background_sync/DEPS
index 563121c..189c93c 100644
--- a/components/background_sync/DEPS
+++ b/components/background_sync/DEPS
@@ -1,5 +1,8 @@
include_rules = [
"+components/content_settings/core",
+ "+components/keep_alive_registry",
+ "+components/keyed_service/core",
+ "+components/variations",
"+components/permissions",
"+content/public/browser",
"+content/public/test",
diff --git a/components/background_sync/background_sync_controller_impl.cc b/components/background_sync/background_sync_controller_impl.cc
new file mode 100644
index 0000000..8fe72bb
--- /dev/null
+++ b/components/background_sync/background_sync_controller_impl.cc
@@ -0,0 +1,408 @@
+// Copyright 2015 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.
+
+#include "components/background_sync/background_sync_controller_impl.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/time/time.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings.h"
+#include "components/keep_alive_registry/keep_alive_registry.h"
+#include "components/variations/variations_associated_data.h"
+#include "content/public/browser/background_sync_context.h"
+#include "content/public/browser/background_sync_controller.h"
+#include "content/public/browser/background_sync_parameters.h"
+#include "content/public/browser/background_sync_registration.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/storage_partition.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+// static
+const char BackgroundSyncControllerImpl::kFieldTrialName[] = "BackgroundSync";
+const char BackgroundSyncControllerImpl::kDisabledParameterName[] = "disabled";
+#if defined(OS_ANDROID)
+const char BackgroundSyncControllerImpl::kRelyOnAndroidNetworkDetection[] =
+ "rely_on_android_network_detection";
+#endif
+const char BackgroundSyncControllerImpl::kKeepBrowserAwakeParameterName[] =
+ "keep_browser_awake_till_events_complete";
+const char BackgroundSyncControllerImpl::kSkipPermissionsCheckParameterName[] =
+ "skip_permissions_check_for_testing";
+const char BackgroundSyncControllerImpl::kMaxAttemptsParameterName[] =
+ "max_sync_attempts";
+const char BackgroundSyncControllerImpl::
+ kMaxAttemptsWithNotificationPermissionParameterName[] =
+ "max_sync_attempts_with_notification_permission";
+const char BackgroundSyncControllerImpl::kInitialRetryParameterName[] =
+ "initial_retry_delay_sec";
+const char BackgroundSyncControllerImpl::kRetryDelayFactorParameterName[] =
+ "retry_delay_factor";
+const char BackgroundSyncControllerImpl::kMinSyncRecoveryTimeName[] =
+ "min_recovery_time_sec";
+const char BackgroundSyncControllerImpl::kMaxSyncEventDurationName[] =
+ "max_sync_event_duration_sec";
+const char BackgroundSyncControllerImpl::kMinPeriodicSyncEventsInterval[] =
+ "min_periodic_sync_events_interval_sec";
+
+BackgroundSyncControllerImpl::BackgroundSyncControllerImpl(
+ content::BrowserContext* browser_context,
+ std::unique_ptr<background_sync::BackgroundSyncDelegate> delegate)
+ : browser_context_(browser_context), delegate_(std::move(delegate)) {
+ DCHECK(browser_context_);
+ DCHECK(delegate_);
+
+ background_sync_metrics_ =
+ std::make_unique<BackgroundSyncMetrics>(delegate_.get());
+ delegate_->GetHostContentSettingsMap()->AddObserver(this);
+}
+
+BackgroundSyncControllerImpl::~BackgroundSyncControllerImpl() = default;
+
+void BackgroundSyncControllerImpl::OnContentSettingChanged(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const std::string& resource_identifier) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (content_type != ContentSettingsType::BACKGROUND_SYNC &&
+ content_type != ContentSettingsType::PERIODIC_BACKGROUND_SYNC) {
+ return;
+ }
+
+ std::vector<url::Origin> affected_origins;
+ for (const auto& origin : periodic_sync_origins_) {
+ if (!IsContentSettingBlocked(origin))
+ continue;
+
+ auto* storage_partition =
+ content::BrowserContext::GetStoragePartitionForSite(
+ browser_context_, origin.GetURL(), /* can_create= */ false);
+ if (!storage_partition)
+ continue;
+
+ auto* background_sync_context =
+ storage_partition->GetBackgroundSyncContext();
+ if (!background_sync_context)
+ continue;
+
+ background_sync_context->UnregisterPeriodicSyncForOrigin(origin);
+ affected_origins.push_back(origin);
+ }
+
+ // Stop tracking affected origins.
+ for (const auto& origin : affected_origins) {
+ periodic_sync_origins_.erase(origin);
+ }
+}
+
+void BackgroundSyncControllerImpl::GetParameterOverrides(
+ content::BackgroundSyncParameters* parameters) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+#if defined(OS_ANDROID)
+ if (delegate_->ShouldDisableBackgroundSync())
+ parameters->disable = true;
+#endif
+
+ std::map<std::string, std::string> field_params;
+ if (!variations::GetVariationParams(kFieldTrialName, &field_params))
+ return;
+
+ if (base::LowerCaseEqualsASCII(field_params[kDisabledParameterName],
+ "true")) {
+ parameters->disable = true;
+ }
+
+ if (base::LowerCaseEqualsASCII(field_params[kKeepBrowserAwakeParameterName],
+ "true")) {
+ parameters->keep_browser_awake_till_events_complete = true;
+ }
+
+ if (base::LowerCaseEqualsASCII(
+ field_params[kSkipPermissionsCheckParameterName], "true")) {
+ parameters->skip_permissions_check_for_testing = true;
+ }
+
+ if (base::Contains(field_params,
+ kMaxAttemptsWithNotificationPermissionParameterName)) {
+ int max_attempts;
+ if (base::StringToInt(
+ field_params[kMaxAttemptsWithNotificationPermissionParameterName],
+ &max_attempts)) {
+ parameters->max_sync_attempts_with_notification_permission = max_attempts;
+ }
+ }
+
+ if (base::Contains(field_params, kMaxAttemptsParameterName)) {
+ int max_attempts;
+ if (base::StringToInt(field_params[kMaxAttemptsParameterName],
+ &max_attempts)) {
+ parameters->max_sync_attempts = max_attempts;
+ }
+ }
+
+ if (base::Contains(field_params, kInitialRetryParameterName)) {
+ int initial_retry_delay_sec;
+ if (base::StringToInt(field_params[kInitialRetryParameterName],
+ &initial_retry_delay_sec)) {
+ parameters->initial_retry_delay =
+ base::TimeDelta::FromSeconds(initial_retry_delay_sec);
+ }
+ }
+
+ if (base::Contains(field_params, kRetryDelayFactorParameterName)) {
+ int retry_delay_factor;
+ if (base::StringToInt(field_params[kRetryDelayFactorParameterName],
+ &retry_delay_factor)) {
+ parameters->retry_delay_factor = retry_delay_factor;
+ }
+ }
+
+ if (base::Contains(field_params, kMinSyncRecoveryTimeName)) {
+ int min_sync_recovery_time_sec;
+ if (base::StringToInt(field_params[kMinSyncRecoveryTimeName],
+ &min_sync_recovery_time_sec)) {
+ parameters->min_sync_recovery_time =
+ base::TimeDelta::FromSeconds(min_sync_recovery_time_sec);
+ }
+ }
+
+ if (base::Contains(field_params, kMaxSyncEventDurationName)) {
+ int max_sync_event_duration_sec;
+ if (base::StringToInt(field_params[kMaxSyncEventDurationName],
+ &max_sync_event_duration_sec)) {
+ parameters->max_sync_event_duration =
+ base::TimeDelta::FromSeconds(max_sync_event_duration_sec);
+ }
+ }
+
+ if (base::Contains(field_params, kMinPeriodicSyncEventsInterval)) {
+ int min_periodic_sync_events_interval_sec;
+ if (base::StringToInt(field_params[kMinPeriodicSyncEventsInterval],
+ &min_periodic_sync_events_interval_sec)) {
+ parameters->min_periodic_sync_events_interval =
+ base::TimeDelta::FromSeconds(min_periodic_sync_events_interval_sec);
+ }
+ }
+
+ return;
+}
+
+void BackgroundSyncControllerImpl::NotifyOneShotBackgroundSyncRegistered(
+ const url::Origin& origin,
+ bool can_fire,
+ bool is_reregistered) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ background_sync_metrics_->MaybeRecordOneShotSyncRegistrationEvent(
+ origin, can_fire, is_reregistered);
+}
+
+void BackgroundSyncControllerImpl::NotifyPeriodicBackgroundSyncRegistered(
+ const url::Origin& origin,
+ int min_interval,
+ bool is_reregistered) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ background_sync_metrics_->MaybeRecordPeriodicSyncRegistrationEvent(
+ origin, min_interval, is_reregistered);
+}
+
+void BackgroundSyncControllerImpl::NotifyOneShotBackgroundSyncCompleted(
+ const url::Origin& origin,
+ blink::ServiceWorkerStatusCode status_code,
+ int num_attempts,
+ int max_attempts) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ background_sync_metrics_->MaybeRecordOneShotSyncCompletionEvent(
+ origin, status_code, num_attempts, max_attempts);
+}
+
+void BackgroundSyncControllerImpl::NotifyPeriodicBackgroundSyncCompleted(
+ const url::Origin& origin,
+ blink::ServiceWorkerStatusCode status_code,
+ int num_attempts,
+ int max_attempts) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ background_sync_metrics_->MaybeRecordPeriodicSyncEventCompletion(
+ origin, status_code, num_attempts, max_attempts);
+}
+
+void BackgroundSyncControllerImpl::ScheduleBrowserWakeUpWithDelay(
+ blink::mojom::BackgroundSyncType sync_type,
+ base::TimeDelta delay) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (delegate_->IsProfileOffTheRecord())
+ return;
+
+#if defined(OS_ANDROID)
+ delegate_->ScheduleBrowserWakeUpWithDelay(sync_type, delay);
+#endif
+}
+
+void BackgroundSyncControllerImpl::CancelBrowserWakeup(
+ blink::mojom::BackgroundSyncType sync_type) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (delegate_->IsProfileOffTheRecord())
+ return;
+
+#if defined(OS_ANDROID)
+ delegate_->CancelBrowserWakeup(sync_type);
+#endif
+}
+
+int BackgroundSyncControllerImpl::GetSiteEngagementPenalty(const GURL& url) {
+ return delegate_->GetSiteEngagementPenalty(url);
+}
+
+base::TimeDelta BackgroundSyncControllerImpl::SnapToMaxOriginFrequency(
+ int64_t min_interval,
+ int64_t min_gap_for_origin) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ DCHECK_GE(min_gap_for_origin, 0);
+ DCHECK_GE(min_interval, 0);
+
+ if (min_interval < min_gap_for_origin)
+ return base::TimeDelta::FromMilliseconds(min_gap_for_origin);
+ if (min_interval % min_gap_for_origin == 0)
+ return base::TimeDelta::FromMilliseconds(min_interval);
+ return base::TimeDelta::FromMilliseconds(
+ (min_interval / min_gap_for_origin + 1) * min_gap_for_origin);
+}
+
+base::TimeDelta BackgroundSyncControllerImpl::ApplyMinGapForOrigin(
+ base::TimeDelta delay,
+ base::TimeDelta time_till_next_scheduled_event_for_origin,
+ base::TimeDelta min_gap_for_origin) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (time_till_next_scheduled_event_for_origin.is_max())
+ return delay;
+
+ if (delay <= time_till_next_scheduled_event_for_origin - min_gap_for_origin)
+ return delay;
+
+ if (delay <= time_till_next_scheduled_event_for_origin)
+ return time_till_next_scheduled_event_for_origin;
+
+ if (delay <= time_till_next_scheduled_event_for_origin + min_gap_for_origin)
+ return time_till_next_scheduled_event_for_origin + min_gap_for_origin;
+
+ return delay;
+}
+
+bool BackgroundSyncControllerImpl::IsContentSettingBlocked(
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ auto* host_content_settings_map = delegate_->GetHostContentSettingsMap();
+ DCHECK(host_content_settings_map);
+
+ auto url = origin.GetURL();
+ return CONTENT_SETTING_ALLOW != host_content_settings_map->GetContentSetting(
+ /* primary_url= */ url,
+ /* secondary_url= */ url,
+ ContentSettingsType::BACKGROUND_SYNC,
+ /* resource_identifier= */ std::string());
+}
+
+void BackgroundSyncControllerImpl::Shutdown() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ delegate_->GetHostContentSettingsMap()->RemoveObserver(this);
+ delegate_->Shutdown();
+}
+
+base::TimeDelta BackgroundSyncControllerImpl::GetNextEventDelay(
+ const content::BackgroundSyncRegistration& registration,
+ content::BackgroundSyncParameters* parameters,
+ base::TimeDelta time_till_soonest_scheduled_event_for_origin) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(parameters);
+
+ int num_attempts = registration.num_attempts();
+
+ if (!num_attempts) {
+ // First attempt.
+ switch (registration.sync_type()) {
+ case blink::mojom::BackgroundSyncType::ONE_SHOT:
+ return base::TimeDelta();
+ case blink::mojom::BackgroundSyncType::PERIODIC:
+ int site_engagement_factor =
+ delegate_->GetSiteEngagementPenalty(registration.origin().GetURL());
+ if (!site_engagement_factor)
+ return base::TimeDelta::Max();
+
+ int64_t effective_gap_ms =
+ site_engagement_factor *
+ parameters->min_periodic_sync_events_interval.InMilliseconds();
+ return ApplyMinGapForOrigin(
+ SnapToMaxOriginFrequency(registration.options()->min_interval,
+ effective_gap_ms),
+ time_till_soonest_scheduled_event_for_origin,
+ parameters->min_periodic_sync_events_interval);
+ }
+ }
+
+ // After a sync event has been fired.
+ DCHECK_LT(num_attempts, parameters->max_sync_attempts);
+ return parameters->initial_retry_delay *
+ pow(parameters->retry_delay_factor, num_attempts - 1);
+}
+
+std::unique_ptr<content::BackgroundSyncController::BackgroundSyncEventKeepAlive>
+BackgroundSyncControllerImpl::CreateBackgroundSyncEventKeepAlive() {
+#if !defined(OS_ANDROID)
+ if (!KeepAliveRegistry::GetInstance()->IsShuttingDown())
+ return std::make_unique<BackgroundSyncEventKeepAliveImpl>();
+#endif
+ return nullptr;
+}
+
+#if !defined(OS_ANDROID)
+BackgroundSyncControllerImpl::BackgroundSyncEventKeepAliveImpl::
+ BackgroundSyncEventKeepAliveImpl() {
+ keepalive_ = std::unique_ptr<ScopedKeepAlive,
+ content::BrowserThread::DeleteOnUIThread>(
+ new ScopedKeepAlive(KeepAliveOrigin::BACKGROUND_SYNC,
+ KeepAliveRestartOption::DISABLED));
+}
+
+BackgroundSyncControllerImpl::BackgroundSyncEventKeepAliveImpl::
+ ~BackgroundSyncEventKeepAliveImpl() = default;
+#endif
+
+void BackgroundSyncControllerImpl::NoteSuspendedPeriodicSyncOrigins(
+ std::set<url::Origin> suspended_origins) {
+ delegate_->NoteSuspendedPeriodicSyncOrigins(std::move(suspended_origins));
+}
+
+void BackgroundSyncControllerImpl::NoteRegisteredPeriodicSyncOrigins(
+ std::set<url::Origin> registered_origins) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ for (auto& origin : registered_origins)
+ periodic_sync_origins_.insert(std::move(origin));
+}
+
+void BackgroundSyncControllerImpl::AddToTrackedOrigins(
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ periodic_sync_origins_.insert(origin);
+}
+
+void BackgroundSyncControllerImpl::RemoveFromTrackedOrigins(
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ periodic_sync_origins_.erase(origin);
+}
diff --git a/components/background_sync/background_sync_controller_impl.h b/components/background_sync/background_sync_controller_impl.h
new file mode 100644
index 0000000..5190de9
--- /dev/null
+++ b/components/background_sync/background_sync_controller_impl.h
@@ -0,0 +1,156 @@
+// Copyright 2015 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.
+
+#ifndef COMPONENTS_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_IMPL_H_
+#define COMPONENTS_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_IMPL_H_
+
+#include "content/public/browser/background_sync_controller.h"
+
+#include <stdint.h>
+
+#include <set>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "components/background_sync/background_sync_delegate.h"
+#include "components/background_sync/background_sync_metrics.h"
+#include "components/content_settings/core/browser/content_settings_observer.h"
+#include "components/keep_alive_registry/keep_alive_types.h"
+#include "components/keep_alive_registry/scoped_keep_alive.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/background_sync_registration.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/mojom/background_sync/background_sync.mojom-forward.h"
+
+namespace content {
+struct BackgroundSyncParameters;
+class BrowserContext;
+} // namespace content
+
+namespace url {
+class Origin;
+} // namespace url
+
+class GURL;
+
+class BackgroundSyncControllerImpl : public content::BackgroundSyncController,
+ public KeyedService,
+ public content_settings::Observer {
+ public:
+ static const char kFieldTrialName[];
+ static const char kDisabledParameterName[];
+ static const char kKeepBrowserAwakeParameterName[];
+ static const char kSkipPermissionsCheckParameterName[];
+ static const char kMaxAttemptsParameterName[];
+ static const char kRelyOnAndroidNetworkDetection[];
+ static const char kMaxAttemptsWithNotificationPermissionParameterName[];
+ static const char kInitialRetryParameterName[];
+ static const char kRetryDelayFactorParameterName[];
+ static const char kMinSyncRecoveryTimeName[];
+ static const char kMaxSyncEventDurationName[];
+ static const char kMinPeriodicSyncEventsInterval[];
+
+#if !defined(OS_ANDROID)
+ class BackgroundSyncEventKeepAliveImpl : public BackgroundSyncEventKeepAlive {
+ public:
+ ~BackgroundSyncEventKeepAliveImpl() override;
+ BackgroundSyncEventKeepAliveImpl();
+
+ private:
+ std::unique_ptr<ScopedKeepAlive, content::BrowserThread::DeleteOnUIThread>
+ keepalive_ = nullptr;
+ };
+#endif
+
+ BackgroundSyncControllerImpl(
+ content::BrowserContext* browser_context,
+ std::unique_ptr<background_sync::BackgroundSyncDelegate> delegate);
+ ~BackgroundSyncControllerImpl() override;
+
+ // content::BackgroundSyncController overrides.
+ void GetParameterOverrides(
+ content::BackgroundSyncParameters* parameters) override;
+ void NotifyOneShotBackgroundSyncRegistered(const url::Origin& origin,
+ bool can_fire,
+ bool is_reregistered) override;
+ void NotifyPeriodicBackgroundSyncRegistered(const url::Origin& origin,
+ int min_interval,
+ bool is_reregistered) override;
+ void NotifyOneShotBackgroundSyncCompleted(
+ const url::Origin& origin,
+ blink::ServiceWorkerStatusCode status_code,
+ int num_attempts,
+ int max_attempts) override;
+ void NotifyPeriodicBackgroundSyncCompleted(
+ const url::Origin& origin,
+ blink::ServiceWorkerStatusCode status_code,
+ int num_attempts,
+ int max_attempts) override;
+ void ScheduleBrowserWakeUpWithDelay(
+ blink::mojom::BackgroundSyncType sync_type,
+ base::TimeDelta delay) override;
+ void CancelBrowserWakeup(blink::mojom::BackgroundSyncType sync_type) override;
+
+ base::TimeDelta GetNextEventDelay(
+ const content::BackgroundSyncRegistration& registration,
+ content::BackgroundSyncParameters* parameters,
+ base::TimeDelta time_till_soonest_scheduled_event_for_origin) override;
+
+ std::unique_ptr<BackgroundSyncEventKeepAlive>
+ CreateBackgroundSyncEventKeepAlive() override;
+ void NoteSuspendedPeriodicSyncOrigins(
+ std::set<url::Origin> suspended_origins) override;
+ void NoteRegisteredPeriodicSyncOrigins(
+ std::set<url::Origin> registered_origins) override;
+ void AddToTrackedOrigins(const url::Origin& origin) override;
+ void RemoveFromTrackedOrigins(const url::Origin& origin) override;
+
+ // content_settings::Observer overrides.
+ void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const std::string& resource_identifier) override;
+
+ bool IsOriginTracked(const url::Origin& origin) {
+ return periodic_sync_origins_.find(origin) != periodic_sync_origins_.end();
+ }
+
+ private:
+ // Gets the site engagement penalty for |url|, which is inversely proportional
+ // to the engagement level. The lower the engagement levels with the site,
+ // the less often periodic sync events will be fired.
+ // Returns kEngagementLevelNonePenalty if the engagement level is
+ // blink::mojom::EngagementLevel::NONE.
+ virtual int GetSiteEngagementPenalty(const GURL& url);
+
+ // Once we've identified the minimum number of hours between each periodicsync
+ // event for an origin, every delay calculated for the origin should be a
+ // multiple of the same.
+ base::TimeDelta SnapToMaxOriginFrequency(int64_t min_interval,
+ int64_t min_gap_for_origin);
+
+ // Returns an updated delay for a Periodic Background Sync registration -- one
+ // that ensures the |min_gap_for_origin|.
+ base::TimeDelta ApplyMinGapForOrigin(
+ base::TimeDelta delay,
+ base::TimeDelta time_till_next_scheduled_event_for_origin,
+ base::TimeDelta min_gap_for_origin);
+
+ bool IsContentSettingBlocked(const url::Origin& origin);
+
+ // KeyedService implementation.
+ void Shutdown() override;
+
+ content::BrowserContext* browser_context_;
+
+ std::unique_ptr<background_sync::BackgroundSyncDelegate> delegate_;
+ std::unique_ptr<BackgroundSyncMetrics> background_sync_metrics_;
+
+ std::set<url::Origin> periodic_sync_origins_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundSyncControllerImpl);
+};
+
+#endif // COMPONENTS_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_IMPL_H_