Skip to content

Commit

Permalink
Reland of [Background Sync] Trigger Background Sync events when Chrom…
Browse files Browse the repository at this point in the history
  • Loading branch information
clelland authored and Commit bot committed Oct 2, 2015
1 parent 332b0ca commit 9c6db41
Show file tree
Hide file tree
Showing 16 changed files with 393 additions and 25 deletions.
1 change: 1 addition & 0 deletions chrome/test/android/unit_tests_apk/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"/>
Expand Down
2 changes: 2 additions & 0 deletions components/test/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions components/test/run_all_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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
80 changes: 80 additions & 0 deletions content/browser/android/background_sync_network_observer_android.h
Original file line number Diff line number Diff line change
@@ -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_
4 changes: 4 additions & 0 deletions content/browser/android/browser_jni_registrar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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},
Expand Down
50 changes: 35 additions & 15 deletions content/browser/background_sync/background_sync_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -92,27 +93,28 @@ 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();
}

void SetIncognitoMode(bool incognito) {
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.
Expand All @@ -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();
Expand All @@ -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.
Expand All @@ -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) {
Expand Down Expand Up @@ -513,6 +535,4 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallDoneAfterSyncFails) {
EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - delay result: false"));
}

} // namespace

} // namespace content
7 changes: 7 additions & 0 deletions content/browser/background_sync/background_sync_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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())));
}
Expand Down
4 changes: 4 additions & 0 deletions content/browser/background_sync/background_sync_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 9c6db41

Please sign in to comment.