summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/android/unit_tests_apk/AndroidManifest.xml1
-rw-r--r--components/test/DEPS2
-rw-r--r--components/test/run_all_unittests.cc4
-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
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_jni.gypi1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java109
-rw-r--r--testing/android/native_test/java/AndroidManifest.xml1
16 files changed, 393 insertions, 25 deletions
diff --git a/chrome/test/android/unit_tests_apk/AndroidManifest.xml b/chrome/test/android/unit_tests_apk/AndroidManifest.xml
index fc0124c..3fdebe5 100644
--- a/chrome/test/android/unit_tests_apk/AndroidManifest.xml
+++ b/chrome/test/android/unit_tests_apk/AndroidManifest.xml
@@ -11,6 +11,7 @@ found in the LICENSE file.
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
diff --git a/components/test/DEPS b/components/test/DEPS
index 640fa0a..7bd6a58 100644
--- a/components/test/DEPS
+++ b/components/test/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+components/policy/core/browser/android/component_jni_registrar.h",
"+components/safe_json/android/component_jni_registrar.h",
"+components/signin/core/browser/android/component_jni_registrar.h",
+ "+content/browser/android/browser_jni_registrar.h",
"+content/public/android/java/src/org/chromium/content/browser",
"+content/public/app/content_jni_onload.h",
"+content/public/app/content_main.h",
@@ -16,6 +17,7 @@ include_rules = [
"+content/shell/app/shell_main_delegate.h",
"+jni",
"+media/base/media_switches.h",
+ "+net/android/net_jni_registrar.h",
"+ui/android/java/src/org/chromium/ui/base",
"+ui/base/android/ui_base_jni_registrar.h",
"+ui/base/resource/resource_bundle.h",
diff --git a/components/test/run_all_unittests.cc b/components/test/run_all_unittests.cc
index d04085e..ef7d826 100644
--- a/components/test/run_all_unittests.cc
+++ b/components/test/run_all_unittests.cc
@@ -26,6 +26,8 @@
#include "components/policy/core/browser/android/component_jni_registrar.h"
#include "components/safe_json/android/component_jni_registrar.h"
#include "components/signin/core/browser/android/component_jni_registrar.h"
+#include "content/browser/android/browser_jni_registrar.h"
+#include "net/android/net_jni_registrar.h"
#include "ui/base/android/ui_base_jni_registrar.h"
#include "ui/gfx/android/gfx_jni_registrar.h"
#endif
@@ -57,6 +59,8 @@ class ComponentsTestSuite : public base::TestSuite {
ASSERT_TRUE(policy::android::RegisterPolicy(env));
ASSERT_TRUE(safe_json::android::RegisterSafeJsonJni(env));
ASSERT_TRUE(signin::android::RegisterSigninJni(env));
+ ASSERT_TRUE(net::android::RegisterJni(env));
+ ASSERT_TRUE(content::android::RegisterBrowserJni(env));
#endif
ui::RegisterPathProvider();
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);
};
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 0f43540..c7ad01f 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -346,6 +346,8 @@
'browser/android/animation_utils.h',
'browser/android/background_sync_launcher_android.cc',
'browser/android/background_sync_launcher_android.h',
+ 'browser/android/background_sync_network_observer_android.cc',
+ 'browser/android/background_sync_network_observer_android.h',
'browser/android/browser_jni_registrar.cc',
'browser/android/browser_jni_registrar.h',
'browser/android/browser_startup_controller.cc',
diff --git a/content/content_jni.gypi b/content/content_jni.gypi
index c93e4ef..3a154d4 100644
--- a/content/content_jni.gypi
+++ b/content/content_jni.gypi
@@ -12,6 +12,7 @@
'public/android/java/src/org/chromium/content/app/ContentMain.java',
'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java',
'public/android/java/src/org/chromium/content/browser/BackgroundSyncLauncher.java',
+ 'public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java',
'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java',
'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java',
'public/android/java/src/org/chromium/content/browser/ContentReadbackHandler.java',
diff --git a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java
new file mode 100644
index 0000000..25c2846
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java
@@ -0,0 +1,109 @@
+// 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.
+
+package org.chromium.content.browser;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Process;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeClassQualifiedName;
+import org.chromium.net.NetworkChangeNotifierAutoDetect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contains the Java code used by the BackgroundSyncNetworkObserverAndroid C++ class.
+ *
+ * The purpose of this class is to listen for and forward network connectivity events to the
+ * BackgroundSyncNetworkObserverAndroid objects even when the application is paused. The standard
+ * NetworkChangeNotifier does not listen for connectivity events when the application is paused.
+ *
+ * This class maintains a NetworkChangeNotifierAutoDetect, which exists for as long as any
+ * BackgroundSyncNetworkObserverAndroid objects are registered.
+ *
+ * This class lives on the main thread.
+ */
+@JNINamespace("content")
+class BackgroundSyncNetworkObserver implements NetworkChangeNotifierAutoDetect.Observer {
+ private static final String TAG = "cr_BgSyncNetObserver";
+
+ private NetworkChangeNotifierAutoDetect mNotifier;
+ private Context mContext;
+
+ // The singleton instance.
+ private static BackgroundSyncNetworkObserver sInstance = null;
+
+ // List of native observers. These are each called when the network state changes.
+ private List<Long> mNativePtrs;
+
+ private BackgroundSyncNetworkObserver(Context ctx) {
+ ThreadUtils.assertOnUiThread();
+ mContext = ctx;
+ mNativePtrs = new ArrayList<Long>();
+ }
+
+ private static boolean canCreateObserver(Context ctx) {
+ return ctx.checkPermission(
+ Manifest.permission.ACCESS_NETWORK_STATE, Process.myPid(), Process.myUid())
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ @CalledByNative
+ private static BackgroundSyncNetworkObserver createObserver(Context ctx, long nativePtr) {
+ ThreadUtils.assertOnUiThread();
+ if (sInstance == null) {
+ sInstance = new BackgroundSyncNetworkObserver(ctx);
+ }
+ sInstance.registerObserver(nativePtr);
+ return sInstance;
+ }
+
+ private void registerObserver(final long nativePtr) {
+ ThreadUtils.assertOnUiThread();
+ if (!canCreateObserver(mContext)) {
+ return;
+ }
+
+ // Create the NetworkChangeNotifierAutoDetect if it does not exist already.
+ if (mNotifier == null) {
+ mNotifier =
+ new NetworkChangeNotifierAutoDetect(this, mContext, true /* always listen */);
+ }
+ mNativePtrs.add(nativePtr);
+
+ nativeNotifyConnectionTypeChanged(
+ nativePtr, mNotifier.getCurrentConnectionType(mNotifier.getCurrentNetworkState()));
+ }
+
+ @CalledByNative
+ private void removeObserver(long nativePtr) {
+ ThreadUtils.assertOnUiThread();
+ mNativePtrs.remove(nativePtr);
+ // Destroy the NetworkChangeNotifierAutoDetect if there are no more observers.
+ if (mNativePtrs.size() == 0 && mNotifier != null) {
+ mNotifier.destroy();
+ mNotifier = null;
+ }
+ }
+
+ @Override
+ public void onConnectionTypeChanged(int newConnectionType) {
+ ThreadUtils.assertOnUiThread();
+ for (Long nativePtr : mNativePtrs) {
+ nativeNotifyConnectionTypeChanged(nativePtr, newConnectionType);
+ }
+ }
+
+ @Override
+ public void onMaxBandwidthChanged(double maxBandwidthMbps) {}
+
+ @NativeClassQualifiedName("BackgroundSyncNetworkObserverAndroid::Observer")
+ private native void nativeNotifyConnectionTypeChanged(long nativePtr, int newConnectionType);
+}
diff --git a/testing/android/native_test/java/AndroidManifest.xml b/testing/android/native_test/java/AndroidManifest.xml
index 6de21b1..a50ffcd 100644
--- a/testing/android/native_test/java/AndroidManifest.xml
+++ b/testing/android/native_test/java/AndroidManifest.xml
@@ -11,6 +11,7 @@ found in the LICENSE file.
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.CAMERA" />