summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authoriclelland <iclelland@chromium.org>2015-10-02 06:35:01 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-02 13:35:51 +0000
commit9c6db4187afa85c03bd7a0e697cc7ff1986e4b77 (patch)
treea006869b9296ce3352f8647ec3a8f5271fe5814b /content/browser
parent332b0ca94e72e4bfde35f5b6e86810843902fbb7 (diff)
downloadchromium_src-9c6db4187afa85c03bd7a0e697cc7ff1986e4b77.zip
chromium_src-9c6db4187afa85c03bd7a0e697cc7ff1986e4b77.tar.gz
chromium_src-9c6db4187afa85c03bd7a0e697cc7ff1986e4b77.tar.bz2
Reland of [Background Sync] Trigger Background Sync events when Chrome is backgrounded on Android
Original review: https://codereview.chromium.org/1294603003/ (Committed as https://crrev.com/a5fb97d6fb9c3831994aadebea4664e2acc3c356) Reverted in https://codereview.chromium.org/1376563003/ (as https://crrev.com/c532c674b657426cb733c2b735bbf5741bcbea48) BUG=511129 Review URL: https://codereview.chromium.org/1383663004 Cr-Commit-Position: refs/heads/master@{#352019}
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/android/background_sync_network_observer_android.cc86
-rw-r--r--content/browser/android/background_sync_network_observer_android.h80
-rw-r--r--content/browser/android/browser_jni_registrar.cc4
-rw-r--r--content/browser/background_sync/background_sync_browsertest.cc50
-rw-r--r--content/browser/background_sync/background_sync_manager.cc7
-rw-r--r--content/browser/background_sync/background_sync_manager.h4
-rw-r--r--content/browser/background_sync/background_sync_manager_unittest.cc17
-rw-r--r--content/browser/background_sync/background_sync_network_observer.cc27
-rw-r--r--content/browser/background_sync/background_sync_network_observer.h23
9 files changed, 273 insertions, 25 deletions
diff --git a/content/browser/android/background_sync_network_observer_android.cc b/content/browser/android/background_sync_network_observer_android.cc
new file mode 100644
index 0000000..533fc36
--- /dev/null
+++ b/content/browser/android/background_sync_network_observer_android.cc
@@ -0,0 +1,86 @@
+// 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 "content/browser/android/background_sync_network_observer_android.h"
+
+#include "jni/BackgroundSyncNetworkObserver_jni.h"
+
+namespace content {
+
+// static
+bool BackgroundSyncNetworkObserverAndroid::Observer::RegisterNetworkObserver(
+ JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+// static
+scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer>
+BackgroundSyncNetworkObserverAndroid::Observer::Create(
+ base::Callback<void(net::NetworkChangeNotifier::ConnectionType)> callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer> observer(
+ new BackgroundSyncNetworkObserverAndroid::Observer(callback));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&BackgroundSyncNetworkObserverAndroid::Observer::Init,
+ observer));
+ return observer;
+}
+
+void BackgroundSyncNetworkObserverAndroid::Observer::Init() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Attach a Java BackgroundSyncNetworkObserver object. Its lifetime will be
+ // scoped to the lifetime of this object.
+ JNIEnv* env = base::android::AttachCurrentThread();
+ base::android::ScopedJavaGlobalRef<jobject> obj(
+ Java_BackgroundSyncNetworkObserver_createObserver(
+ env, base::android::GetApplicationContext(),
+ reinterpret_cast<jlong>(this)));
+ j_observer_.Reset(obj);
+}
+
+BackgroundSyncNetworkObserverAndroid::Observer::~Observer() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_BackgroundSyncNetworkObserver_removeObserver(
+ env, j_observer_.obj(), reinterpret_cast<jlong>(this));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ j_observer_.Release();
+}
+
+void BackgroundSyncNetworkObserverAndroid::Observer::
+ NotifyConnectionTypeChanged(JNIEnv* env,
+ jobject jcaller,
+ jint new_connection_type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(callback_,
+ static_cast<net::NetworkChangeNotifier::ConnectionType>(
+ new_connection_type)));
+}
+
+BackgroundSyncNetworkObserverAndroid::Observer::Observer(
+ base::Callback<void(net::NetworkChangeNotifier::ConnectionType)> callback)
+ : callback_(callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
+BackgroundSyncNetworkObserverAndroid::BackgroundSyncNetworkObserverAndroid(
+ const base::Closure& network_changed_callback)
+ : BackgroundSyncNetworkObserver(network_changed_callback),
+ weak_ptr_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Remove the observer attached by the NetworkObserver constructor
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+
+ observer_ = Observer::Create(
+ base::Bind(&BackgroundSyncNetworkObserverAndroid::OnNetworkChanged,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+BackgroundSyncNetworkObserverAndroid::~BackgroundSyncNetworkObserverAndroid() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+} // namespace content
diff --git a/content/browser/android/background_sync_network_observer_android.h b/content/browser/android/background_sync_network_observer_android.h
new file mode 100644
index 0000000..49e8b0a
--- /dev/null
+++ b/content/browser/android/background_sync_network_observer_android.h
@@ -0,0 +1,80 @@
+// 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 CONTENT_BROWSER_ANDROID_BACKGROUND_SYNC_NETWORK_OBSERVER_ANDROID_H_
+#define CONTENT_BROWSER_ANDROID_BACKGROUND_SYNC_NETWORK_OBSERVER_ANDROID_H_
+
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/background_sync/background_sync_network_observer.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+// BackgroundSyncNetworkObserverAndroid is a specialized
+// BackgroundSyncNetworkObserver which is backed by a NetworkChangeNotifier
+// that listens for network events even when the browser is paused, unlike the
+// standard NetworkChangeNotifier. This ensures that sync events can be fired
+// even when the browser is backgrounded, and other network observers are
+// disabled.
+class BackgroundSyncNetworkObserverAndroid
+ : public BackgroundSyncNetworkObserver {
+ public:
+ // Creates a BackgroundSyncNetworkObserver. |network_changed_callback| is
+ // called via PostMessage when the network connection changes.
+ BackgroundSyncNetworkObserverAndroid(
+ const base::Closure& network_changed_callback);
+
+ ~BackgroundSyncNetworkObserverAndroid() override;
+
+ // This class lives on the UI thread and mediates all access to the Java
+ // BackgroundSyncNetworkObserver, which it creates and owns. It is in turn
+ // owned by the BackgroundSyncNetworkObserverAndroid.
+ class Observer : public base::RefCountedThreadSafe<
+ BackgroundSyncNetworkObserverAndroid::Observer,
+ content::BrowserThread::DeleteOnUIThread> {
+ public:
+ static scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer> Create(
+ base::Callback<void(net::NetworkChangeNotifier::ConnectionType)>
+ callback);
+
+ static bool RegisterNetworkObserver(JNIEnv* env);
+
+ // Called from BackgroundSyncNetworkObserver.java over JNI whenever the
+ // connection type changes. This updates the current connection type seen by
+ // this class and calls the |network_changed_callback| provided to the
+ // constructor, on the IO thread, with the new connection type.
+ void NotifyConnectionTypeChanged(JNIEnv* env,
+ jobject jcaller,
+ jint new_connection_type);
+
+ private:
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
+ friend class base::DeleteHelper<
+ BackgroundSyncNetworkObserverAndroid::Observer>;
+
+ Observer(base::Callback<void(net::NetworkChangeNotifier::ConnectionType)>
+ callback);
+ void Init();
+ ~Observer();
+
+ // This callback is to be run on the IO thread whenever the connection type
+ // changes.
+ base::Callback<void(net::NetworkChangeNotifier::ConnectionType)> callback_;
+ base::android::ScopedJavaGlobalRef<jobject> j_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(Observer);
+ };
+
+ private:
+ // Accessed on UI Thread
+ scoped_refptr<Observer> observer_;
+
+ base::WeakPtrFactory<BackgroundSyncNetworkObserverAndroid> weak_ptr_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_BACKGROUND_SYNC_NETWORK_OBSERVER_ANDROID_H_
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 43adba8..bea2065 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -9,6 +9,7 @@
#include "content/browser/accessibility/browser_accessibility_android.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/browser/android/background_sync_launcher_android.h"
+#include "content/browser/android/background_sync_network_observer_android.h"
#include "content/browser/android/browser_startup_controller.h"
#include "content/browser/android/child_process_launcher_android.h"
#include "content/browser/android/composited_touch_handle_drawable.h"
@@ -50,6 +51,9 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
content::AndroidLocationApiAdapter::RegisterGeolocationService},
{"BackgroundSyncLauncherAndroid",
content::BackgroundSyncLauncherAndroid::RegisterLauncher},
+ {"BackgroundSyncNetworkObserverAndroid",
+ content::BackgroundSyncNetworkObserverAndroid::Observer::
+ RegisterNetworkObserver},
{"BrowserAccessibilityManager",
content::RegisterBrowserAccessibilityManager},
{"BrowserStartupController", content::RegisterBrowserStartupController},
diff --git a/content/browser/background_sync/background_sync_browsertest.cc b/content/browser/background_sync/background_sync_browsertest.cc
index eb79df9..ae1ccc9 100644
--- a/content/browser/background_sync/background_sync_browsertest.cc
+++ b/content/browser/background_sync/background_sync_browsertest.cc
@@ -11,6 +11,7 @@
#include "base/strings/stringprintf.h"
#include "base/task_runner_util.h"
#include "content/browser/background_sync/background_sync_manager.h"
+#include "content/browser/background_sync/background_sync_network_observer.h"
#include "content/browser/background_sync/background_sync_registration_handle.h"
#include "content/browser/background_sync/background_sync_status.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -92,20 +93,15 @@ void OneShotPendingOnIOThread(
callback));
}
+} // namespace
+
class BackgroundSyncBrowserTest : public ContentBrowserTest {
public:
BackgroundSyncBrowserTest() {}
~BackgroundSyncBrowserTest() override {}
void SetUp() override {
- NetworkChangeNotifier::SetTestNotificationsOnly(true);
-
-#if defined(OS_CHROMEOS)
- // ChromeOS's NetworkChangeNotifier doesn't get created in
- // content_browsertests, so make one now.
- net::NetworkChangeNotifier::CreateMock();
-#endif
-
+ BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(true);
ContentBrowserTest::SetUp();
}
@@ -113,6 +109,12 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
shell_ = incognito ? CreateOffTheRecordBrowser() : shell();
}
+ BackgroundSyncContext* GetSyncContextFromShell(Shell* shell) {
+ StoragePartition* storage = BrowserContext::GetDefaultStoragePartition(
+ shell_->web_contents()->GetBrowserContext());
+ return storage->GetBackgroundSyncContext();
+ }
+
void SetUpCommandLine(base::CommandLine* command_line) override {
// TODO(jkarlin): Remove this once background sync is no longer
// experimental.
@@ -128,10 +130,10 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
base::FilePath(FILE_PATH_LITERAL("content/test/data/"))));
ASSERT_TRUE(https_server_->Start());
- SetOnline(true);
-
SetIncognitoMode(false);
+ SetOnline(true);
+
ASSERT_TRUE(LoadTestPage(kDefaultTestURL));
ContentBrowserTest::SetUpOnMainThread();
@@ -148,7 +150,13 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
script, result);
}
+ // This runs asynchronously on the IO thread, but we don't need to wait for it
+ // to complete before running a background sync operation, since those also
+ // run on the IO thread.
void SetOnline(bool online);
+ void SetOnlineOnIOThread(
+ const scoped_refptr<BackgroundSyncContext>& sync_context,
+ bool online);
// Returns true if the one-shot sync with tag is currently pending. Fails
// (assertion failure) if the tag isn't registered.
@@ -175,14 +183,28 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
};
void BackgroundSyncBrowserTest::SetOnline(bool online) {
+ ASSERT_TRUE(shell_);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BackgroundSyncBrowserTest::SetOnlineOnIOThread,
+ base::Unretained(this),
+ base::Unretained(GetSyncContextFromShell(shell_)), online));
+ base::RunLoop().RunUntilIdle();
+}
+
+void BackgroundSyncBrowserTest::SetOnlineOnIOThread(
+ const scoped_refptr<BackgroundSyncContext>& sync_context,
+ bool online) {
+ BackgroundSyncManager* sync_manager = sync_context->background_sync_manager();
+ BackgroundSyncNetworkObserver* network_observer =
+ sync_manager->GetNetworkObserverForTesting();
if (online) {
- NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ network_observer->NotifyManagerIfNetworkChanged(
NetworkChangeNotifier::CONNECTION_WIFI);
} else {
- NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ network_observer->NotifyManagerIfNetworkChanged(
NetworkChangeNotifier::CONNECTION_NONE);
}
- base::RunLoop().RunUntilIdle();
}
bool BackgroundSyncBrowserTest::OneShotPending(const std::string& tag) {
@@ -513,6 +535,4 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallDoneAfterSyncFails) {
EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - delay result: false"));
}
-} // namespace
-
} // namespace content
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 07ac7d8..477b31f 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -21,6 +21,7 @@
#if defined(OS_ANDROID)
#include "content/browser/android/background_sync_launcher_android.h"
+#include "content/browser/android/background_sync_network_observer_android.h"
#endif
namespace content {
@@ -221,9 +222,15 @@ BackgroundSyncManager::BackgroundSyncManager(
service_worker_context_->AddObserver(this);
+#if defined(OS_ANDROID)
+ network_observer_.reset(new BackgroundSyncNetworkObserverAndroid(
+ base::Bind(&BackgroundSyncManager::OnNetworkChanged,
+ weak_ptr_factory_.GetWeakPtr())));
+#else
network_observer_.reset(new BackgroundSyncNetworkObserver(
base::Bind(&BackgroundSyncManager::OnNetworkChanged,
weak_ptr_factory_.GetWeakPtr())));
+#endif
power_observer_.reset(new BackgroundSyncPowerObserver(base::Bind(
&BackgroundSyncManager::OnPowerChanged, weak_ptr_factory_.GetWeakPtr())));
}
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h
index 999b310..a845dd3 100644
--- a/content/browser/background_sync/background_sync_manager.h
+++ b/content/browser/background_sync/background_sync_manager.h
@@ -99,6 +99,10 @@ class CONTENT_EXPORT BackgroundSyncManager
const GURL& pattern) override;
void OnStorageWiped() override;
+ BackgroundSyncNetworkObserver* GetNetworkObserverForTesting() {
+ return network_observer_.get();
+ }
+
protected:
// A registration might be referenced by the client longer than
// the BackgroundSyncManager needs to keep track of it (e.g., the event has
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
index 4817b0c..72db49f 100644
--- a/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -14,6 +14,7 @@
#include "base/single_thread_task_runner.h"
#include "base/test/mock_entropy_provider.h"
#include "base/thread_task_runner_handle.h"
+#include "content/browser/background_sync/background_sync_network_observer.h"
#include "content/browser/background_sync/background_sync_registration_handle.h"
#include "content/browser/background_sync/background_sync_status.h"
#include "content/browser/browser_thread_impl.h"
@@ -233,6 +234,9 @@ class BackgroundSyncManagerTest : public testing::Test {
}
void SetUp() override {
+ // Don't let the tests be confused by the real-world device connectivity
+ BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(true);
+
helper_.reset(
new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId));
@@ -251,6 +255,12 @@ class BackgroundSyncManagerTest : public testing::Test {
RegisterServiceWorkers();
}
+ void TearDown() override {
+ // Restore the network observer functionality for subsequent tests
+ BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(
+ false);
+ }
+
void RegisterServiceWorkers() {
bool called_1 = false;
bool called_2 = false;
@@ -304,7 +314,12 @@ class BackgroundSyncManagerTest : public testing::Test {
void SetNetwork(net::NetworkChangeNotifier::ConnectionType connection_type) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
connection_type);
- base::RunLoop().RunUntilIdle();
+ if (test_background_sync_manager_) {
+ BackgroundSyncNetworkObserver* network_observer =
+ test_background_sync_manager_->GetNetworkObserverForTesting();
+ network_observer->NotifyManagerIfNetworkChanged(connection_type);
+ base::RunLoop().RunUntilIdle();
+ }
}
void SetOnBatteryPower(bool on_battery_power) {
diff --git a/content/browser/background_sync/background_sync_network_observer.cc b/content/browser/background_sync/background_sync_network_observer.cc
index 1c6f2bd..a08e7d8 100644
--- a/content/browser/background_sync/background_sync_network_observer.cc
+++ b/content/browser/background_sync/background_sync_network_observer.cc
@@ -11,6 +11,15 @@
namespace content {
+// static
+bool BackgroundSyncNetworkObserver::ignore_network_change_notifier_ = false;
+
+// static
+void BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(
+ bool ignore) {
+ ignore_network_change_notifier_ = ignore;
+}
+
BackgroundSyncNetworkObserver::BackgroundSyncNetworkObserver(
const base::Closure& network_changed_callback)
: connection_type_(net::NetworkChangeNotifier::GetConnectionType()),
@@ -47,17 +56,18 @@ bool BackgroundSyncNetworkObserver::NetworkSufficient(
return false;
}
-void BackgroundSyncNetworkObserver::NotifyNetworkChanged() {
+void BackgroundSyncNetworkObserver::OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- network_changed_callback_);
+ if (ignore_network_change_notifier_)
+ return;
+ NotifyManagerIfNetworkChanged(connection_type);
}
-void BackgroundSyncNetworkObserver::OnNetworkChanged(
+void BackgroundSyncNetworkObserver::NotifyManagerIfNetworkChanged(
net::NetworkChangeNotifier::ConnectionType connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
if (connection_type == connection_type_)
return;
@@ -65,4 +75,11 @@ void BackgroundSyncNetworkObserver::OnNetworkChanged(
NotifyNetworkChanged();
}
+void BackgroundSyncNetworkObserver::NotifyNetworkChanged() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ network_changed_callback_);
+}
+
} // namespace content
diff --git a/content/browser/background_sync/background_sync_network_observer.h b/content/browser/background_sync/background_sync_network_observer.h
index 7c81f738..4d47cc6 100644
--- a/content/browser/background_sync/background_sync_network_observer.h
+++ b/content/browser/background_sync/background_sync_network_observer.h
@@ -13,7 +13,7 @@
namespace content {
class CONTENT_EXPORT BackgroundSyncNetworkObserver
- : net::NetworkChangeNotifier::NetworkChangeObserver {
+ : public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
// Creates a BackgroundSyncNetworkObserver. |network_changed_callback| is
// called when the network connection changes asynchronously via PostMessage.
@@ -21,22 +21,37 @@ class CONTENT_EXPORT BackgroundSyncNetworkObserver
~BackgroundSyncNetworkObserver() override;
+ // Enable or disable notifications coming from the NetworkChangeNotifier. (For
+ // preventing flakes in tests)
+ static void SetIgnoreNetworkChangeNotifierForTests(bool ignore);
+
// Returns true if the state of the network meets the needs of
// |network_state|.
bool NetworkSufficient(SyncNetworkState network_state);
- private:
- void NotifyNetworkChanged();
-
// NetworkChangeObserver overrides
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType connection_type) override;
+ private:
+ friend class BackgroundSyncBrowserTest;
+ friend class BackgroundSyncManagerTest;
+
+ // Calls NotifyNetworkChanged if the connection type has changed.
+ void NotifyManagerIfNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType connection_type);
+
+ void NotifyNetworkChanged();
+
net::NetworkChangeNotifier::ConnectionType connection_type_;
// The callback to run when the network changes.
base::Closure network_changed_callback_;
+ // Set true to ignore notifications coming from the NetworkChangeNotifier
+ // (to prevent flakes in tests).
+ static bool ignore_network_change_notifier_;
+
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncNetworkObserver);
};