summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/background_sync/background_sync_browsertest.cc110
-rw-r--r--content/browser/service_worker/service_worker_context_core.cc3
-rw-r--r--content/child/background_sync/background_sync_provider.cc65
-rw-r--r--content/child/background_sync/background_sync_provider.h35
-rw-r--r--content/child/background_sync/background_sync_provider_thread_proxy.cc253
-rw-r--r--content/child/background_sync/background_sync_provider_thread_proxy.h95
-rw-r--r--content/child/blink_platform_impl.cc14
-rw-r--r--content/child/blink_platform_impl.h2
-rw-r--r--content/content_child.gypi2
-rw-r--r--content/renderer/background_sync/background_sync_client_impl.cc7
-rw-r--r--content/test/data/background_sync/background_sync_test_helpers.js32
-rw-r--r--content/test/data/background_sync/service_worker.js33
12 files changed, 262 insertions, 389 deletions
diff --git a/content/browser/background_sync/background_sync_browsertest.cc b/content/browser/background_sync/background_sync_browsertest.cc
index ae1ccc9..e90fd7f 100644
--- a/content/browser/background_sync/background_sync_browsertest.cc
+++ b/content/browser/background_sync/background_sync_browsertest.cc
@@ -162,13 +162,20 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
// (assertion failure) if the tag isn't registered.
bool OneShotPending(const std::string& tag);
+ std::string PopConsoleString();
bool PopConsole(const std::string& expected_msg);
bool RegisterServiceWorker();
bool RegisterOneShot(const std::string& tag);
+ bool RegisterOneShotFromServiceWorker(const std::string& tag);
bool UnregisterOneShot(const std::string& tag);
bool UnregisterOneShotTwice(const std::string& tag);
bool GetRegistrationOneShot(const std::string& tag);
+ bool GetRegistrationOneShotFromServiceWorker(const std::string& tag);
+ bool MatchRegistrations(const std::string& script_result,
+ const std::vector<std::string>& expected_tags);
bool GetRegistrationsOneShot(const std::vector<std::string>& expected_tags);
+ bool GetRegistrationsOneShotFromServiceWorker(
+ const std::vector<std::string>& expected_tags);
bool CompleteDelayedOneShot();
bool RejectDelayedOneShot();
bool NotifyWhenDoneOneShot(const std::string& tag);
@@ -233,9 +240,14 @@ bool BackgroundSyncBrowserTest::OneShotPending(const std::string& tag) {
return is_pending;
}
-bool BackgroundSyncBrowserTest::PopConsole(const std::string& expected_msg) {
+std::string BackgroundSyncBrowserTest::PopConsoleString() {
std::string script_result;
EXPECT_TRUE(RunScript("resultQueue.pop()", &script_result));
+ return script_result;
+}
+
+bool BackgroundSyncBrowserTest::PopConsole(const std::string& expected_msg) {
+ std::string script_result = PopConsoleString();
return script_result == expected_msg;
}
@@ -252,6 +264,15 @@ bool BackgroundSyncBrowserTest::RegisterOneShot(const std::string& tag) {
return script_result == BuildExpectedResult(tag, "registered");
}
+bool BackgroundSyncBrowserTest::RegisterOneShotFromServiceWorker(
+ const std::string& tag) {
+ std::string script_result;
+ EXPECT_TRUE(
+ RunScript(BuildScriptString("registerOneShotFromServiceWorker", tag),
+ &script_result));
+ return script_result == BuildExpectedResult(tag, "register sent to SW");
+}
+
bool BackgroundSyncBrowserTest::UnregisterOneShot(const std::string& tag) {
std::string script_result;
EXPECT_TRUE(
@@ -274,21 +295,49 @@ bool BackgroundSyncBrowserTest::GetRegistrationOneShot(const std::string& tag) {
return script_result == BuildExpectedResult(tag, "found");
}
-bool BackgroundSyncBrowserTest::GetRegistrationsOneShot(
- const std::vector<std::string>& expected_tags) {
+bool BackgroundSyncBrowserTest::GetRegistrationOneShotFromServiceWorker(
+ const std::string& tag) {
std::string script_result;
- EXPECT_TRUE(RunScript("getRegistrationsOneShot()", &script_result));
+ EXPECT_TRUE(RunScript(
+ BuildScriptString("getRegistrationOneShotFromServiceWorker", tag),
+ &script_result));
+ EXPECT_TRUE(script_result == "ok - getRegistration sent to SW");
+
+ return PopConsole(BuildExpectedResult(tag, "found"));
+}
+bool BackgroundSyncBrowserTest::MatchRegistrations(
+ const std::string& script_result,
+ const std::vector<std::string>& expected_tags) {
EXPECT_TRUE(base::StartsWith(script_result, kSuccessfulOperationPrefix,
base::CompareCase::INSENSITIVE_ASCII));
- script_result = script_result.substr(strlen(kSuccessfulOperationPrefix));
+ std::string tag_string =
+ script_result.substr(strlen(kSuccessfulOperationPrefix));
std::vector<std::string> result_tags = base::SplitString(
- script_result, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ tag_string, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
return std::set<std::string>(expected_tags.begin(), expected_tags.end()) ==
std::set<std::string>(result_tags.begin(), result_tags.end());
}
+bool BackgroundSyncBrowserTest::GetRegistrationsOneShot(
+ const std::vector<std::string>& expected_tags) {
+ std::string script_result;
+ EXPECT_TRUE(RunScript("getRegistrationsOneShot()", &script_result));
+
+ return MatchRegistrations(script_result, expected_tags);
+}
+
+bool BackgroundSyncBrowserTest::GetRegistrationsOneShotFromServiceWorker(
+ const std::vector<std::string>& expected_tags) {
+ std::string script_result;
+ EXPECT_TRUE(
+ RunScript("getRegistrationsOneShotFromServiceWorker()", &script_result));
+ EXPECT_TRUE(script_result == "ok - getRegistrations sent to SW");
+
+ return MatchRegistrations(PopConsoleString(), expected_tags);
+}
+
bool BackgroundSyncBrowserTest::CompleteDelayedOneShot() {
std::string script_result;
EXPECT_TRUE(RunScript("completeDelayedOneShot()", &script_result));
@@ -331,6 +380,18 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotFires) {
EXPECT_FALSE(GetRegistrationOneShot("foo"));
}
+// Verify that Register works in a service worker
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ OneShotFromServiceWorkerFires) {
+ EXPECT_TRUE(RegisterServiceWorker());
+ EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
+
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker("foo_sw"));
+ EXPECT_TRUE(PopConsole("ok - foo_sw registered in SW"));
+ EXPECT_TRUE(PopConsole("foo_sw fired"));
+ EXPECT_FALSE(GetRegistrationOneShot("foo_sw"));
+}
+
IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotDelaysForNetwork) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
@@ -435,6 +496,43 @@ IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, GetRegistrations) {
EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
}
+// Verify that GetRegistrations works in a service worker
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ GetRegistrationsFromServiceWorker) {
+ EXPECT_TRUE(RegisterServiceWorker());
+ EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
+
+ std::vector<std::string> registered_tags;
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
+
+ SetOnline(false);
+ registered_tags.push_back("foo_sw");
+ registered_tags.push_back("bar_sw");
+
+ for (const std::string& tag : registered_tags) {
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker(tag));
+ EXPECT_TRUE(PopConsole(BuildExpectedResult(tag, "registered in SW")));
+ }
+
+ EXPECT_TRUE(GetRegistrationsOneShotFromServiceWorker(registered_tags));
+}
+
+// Verify that GetRegistration works in a service worker
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
+ GetRegistrationFromServiceWorker) {
+ EXPECT_TRUE(RegisterServiceWorker());
+ EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
+
+ std::vector<std::string> registered_tags;
+ EXPECT_TRUE(GetRegistrationsOneShot(registered_tags));
+
+ SetOnline(false);
+
+ EXPECT_TRUE(RegisterOneShotFromServiceWorker("foo_sw"));
+ EXPECT_TRUE(PopConsole("ok - foo_sw registered in SW"));
+ EXPECT_TRUE(GetRegistrationOneShotFromServiceWorker("foo_sw"));
+}
+
IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, Unregister) {
EXPECT_TRUE(RegisterServiceWorker());
EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page.
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 72771b2..45f0a2d 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -59,7 +59,8 @@ bool IsSameOriginClientProviderHost(const GURL& origin,
bool IsSameOriginWindowProviderHost(const GURL& origin,
ServiceWorkerProviderHost* host) {
- return host->client_type() == blink::WebServiceWorkerClientTypeWindow &&
+ return host->provider_type() ==
+ ServiceWorkerProviderType::SERVICE_WORKER_PROVIDER_FOR_WINDOW &&
host->document_url().GetOrigin() == origin;
}
diff --git a/content/child/background_sync/background_sync_provider.cc b/content/child/background_sync/background_sync_provider.cc
index 57f3d56..fb93ed3 100644
--- a/content/child/background_sync/background_sync_provider.cc
+++ b/content/child/background_sync/background_sync_provider.cc
@@ -5,16 +5,21 @@
#include "content/child/background_sync/background_sync_provider.h"
#include "base/bind.h"
+#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_local.h"
#include "content/child/background_sync/background_sync_type_converters.h"
+#include "content/child/child_thread_impl.h"
#include "content/child/service_worker/web_service_worker_registration_impl.h"
-#include "content/child/worker_task_runner.h"
#include "content/public/common/background_sync.mojom.h"
#include "content/public/common/permission_status.mojom.h"
-#include "content/public/common/service_registry.h"
#include "third_party/WebKit/public/platform/modules/background_sync/WebSyncError.h"
#include "third_party/WebKit/public/platform/modules/background_sync/WebSyncRegistration.h"
+using base::LazyInstance;
+using base::ThreadLocalPointer;
+
namespace content {
namespace {
@@ -26,15 +31,54 @@ int64 GetServiceWorkerRegistrationId(
service_worker_registration)->registration_id();
}
+void ConnectToServiceOnMainThread(
+ mojo::InterfaceRequest<BackgroundSyncService> request) {
+ DCHECK(ChildThreadImpl::current());
+ ChildThreadImpl::current()->service_registry()->ConnectToRemoteService(
+ request.Pass());
+}
+
+LazyInstance<ThreadLocalPointer<BackgroundSyncProvider>>::Leaky
+ g_sync_provider_tls = LAZY_INSTANCE_INITIALIZER;
+
} // namespace
BackgroundSyncProvider::BackgroundSyncProvider(
- ServiceRegistry* service_registry)
- : service_registry_(service_registry) {
- DCHECK(service_registry);
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
+ : main_thread_task_runner_(main_task_runner) {
+ DCHECK(main_task_runner);
+ g_sync_provider_tls.Pointer()->Set(this);
}
BackgroundSyncProvider::~BackgroundSyncProvider() {
+ g_sync_provider_tls.Pointer()->Set(nullptr);
+}
+
+// static
+BackgroundSyncProvider*
+BackgroundSyncProvider::GetOrCreateThreadSpecificInstance(
+ base::SingleThreadTaskRunner* main_thread_task_runner) {
+ DCHECK(main_thread_task_runner);
+ if (g_sync_provider_tls.Pointer()->Get())
+ return g_sync_provider_tls.Pointer()->Get();
+
+ bool have_worker_id = (WorkerThread::GetCurrentId() > 0);
+ if (!main_thread_task_runner->BelongsToCurrentThread() && !have_worker_id) {
+ // On a worker thread, this could happen if this method is called
+ // very late (say by a garbage collected SyncRegistration).
+ return nullptr;
+ }
+
+ BackgroundSyncProvider* instance =
+ new BackgroundSyncProvider(main_thread_task_runner);
+
+ if (have_worker_id) {
+ // For worker threads, use the observer interface to clean up when workers
+ // are stopped.
+ WorkerThread::AddObserver(instance);
+ }
+
+ return instance;
}
void BackgroundSyncProvider::registerBackgroundSync(
@@ -163,6 +207,10 @@ void BackgroundSyncProvider::DuplicateRegistrationHandle(
callback);
}
+void BackgroundSyncProvider::WillStopCurrentWorkerThread() {
+ delete this;
+}
+
void BackgroundSyncProvider::RegisterCallback(
scoped_ptr<blink::WebSyncRegistrationCallbacks> callbacks,
BackgroundSyncError error,
@@ -376,8 +424,11 @@ void BackgroundSyncProvider::NotifyWhenDoneCallback(
BackgroundSyncServicePtr&
BackgroundSyncProvider::GetBackgroundSyncServicePtr() {
if (!background_sync_service_.get()) {
- service_registry_->ConnectToRemoteService(
- mojo::GetProxy(&background_sync_service_));
+ mojo::InterfaceRequest<BackgroundSyncService> request =
+ mojo::GetProxy(&background_sync_service_);
+ main_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&ConnectToServiceOnMainThread, base::Passed(&request)));
}
return background_sync_service_;
}
diff --git a/content/child/background_sync/background_sync_provider.h b/content/child/background_sync/background_sync_provider.h
index cb4f6af..66460cf 100644
--- a/content/child/background_sync/background_sync_provider.h
+++ b/content/child/background_sync/background_sync_provider.h
@@ -8,25 +8,39 @@
#include <string>
#include "base/memory/scoped_ptr.h"
-#include "content/child/worker_task_runner.h"
#include "content/common/background_sync_service.mojom.h"
+#include "content/public/child/worker_thread.h"
#include "third_party/WebKit/public/platform/modules/background_sync/WebSyncProvider.h"
-namespace content {
+namespace base {
+class SingleThreadTaskRunner;
+}
-class ServiceRegistry;
+namespace content {
// The BackgroundSyncProvider is called by the SyncManager and SyncRegistration
// objects (and their Periodic counterparts) and communicates with the
-// BackgroundSyncManager object in the browser process. This class is
-// instantiated on the main thread by BlinkPlatformImpl, and its methods can be
-// called directly from the main thread.
-class BackgroundSyncProvider : public blink::WebSyncProvider {
+// BackgroundSyncManager object in the browser process. Each thread will have
+// its own instance (e.g. main thread, worker threads), instantiated as needed
+// by BlinkPlatformImpl. Each instance of the provider creates a new mojo
+// connection to a new BackgroundSyncManagerImpl, which then talks to the
+// BackgroundSyncManager object.
+class BackgroundSyncProvider : public blink::WebSyncProvider,
+ public WorkerThread::Observer {
public:
- explicit BackgroundSyncProvider(ServiceRegistry* service_registry);
+ // Constructor made public to allow BlinkPlatformImpl to own a copy for the
+ // main thread. Everyone else should use GetOrCreateThreadSpecificInstance().
+ explicit BackgroundSyncProvider(
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
~BackgroundSyncProvider() override;
+ // Returns thread-specific instance (if exists). Otherwise, a new instance
+ // will be created for the thread, except when called for a worker thread that
+ // has already been stopped.
+ static BackgroundSyncProvider* GetOrCreateThreadSpecificInstance(
+ base::SingleThreadTaskRunner* main_thread_task_runner);
+
// blink::WebSyncProvider implementation
void registerBackgroundSync(
const blink::WebSyncRegistration* options,
@@ -61,6 +75,9 @@ class BackgroundSyncProvider : public blink::WebSyncProvider {
const BackgroundSyncService::DuplicateRegistrationHandleCallback&
callback);
+ // WorkerThread::Observer implementation.
+ void WillStopCurrentWorkerThread() override;
+
private:
// Callback handlers
void RegisterCallback(
@@ -90,8 +107,8 @@ class BackgroundSyncProvider : public blink::WebSyncProvider {
// Helper method that returns an initialized BackgroundSyncServicePtr.
BackgroundSyncServicePtr& GetBackgroundSyncServicePtr();
- ServiceRegistry* service_registry_;
BackgroundSyncServicePtr background_sync_service_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncProvider);
};
diff --git a/content/child/background_sync/background_sync_provider_thread_proxy.cc b/content/child/background_sync/background_sync_provider_thread_proxy.cc
deleted file mode 100644
index 021df27..0000000
--- a/content/child/background_sync/background_sync_provider_thread_proxy.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// 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/child/background_sync/background_sync_provider_thread_proxy.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/lazy_instance.h"
-#include "base/location.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_local.h"
-#include "content/child/background_sync/background_sync_provider.h"
-
-using base::LazyInstance;
-using base::ThreadLocalPointer;
-
-namespace content {
-
-namespace {
-
-template <typename T>
-struct WebCallbacksMatcher;
-
-template <typename Stype, typename Ttype>
-struct WebCallbacksMatcher<blink::WebCallbacks<Stype, Ttype>> {
- using S = Stype;
- using T = Ttype;
- using WebCallbacks = typename blink::WebCallbacks<S, T>;
-};
-
-// CallbackThreadAdapter<WebCallbacks<S, T>> is a wrapper for WebCallbacks<S, T>
-// which switches to a specific thread before calling the wrapped callback's
-// onSuccess or onError methods.
-//
-// Takes ownership of the WebCallbacks object which it wraps.
-template <typename X>
-class CallbackThreadAdapter : public WebCallbacksMatcher<X>::WebCallbacks {
- using S = typename WebCallbacksMatcher<X>::S;
- using T = typename WebCallbacksMatcher<X>::T;
- using OnSuccessType = void (blink::WebCallbacks<S, T>::*)(S);
- using OnErrorType = void (blink::WebCallbacks<S, T>::*)(T);
-
- public:
- CallbackThreadAdapter(scoped_ptr<blink::WebCallbacks<S, T>> callbacks,
- int worker_thread_id)
- : worker_thread_id_(worker_thread_id) {
- callbacks_.reset(callbacks.release());
- }
-
- virtual void onSuccess(S results) {
- OnSuccessType on_success = &blink::WebCallbacks<S, T>::onSuccess;
- // If the worker thread has been destroyed, then this task will be
- // silently discarded.
- WorkerTaskRunner::Instance()->PostTask(
- worker_thread_id_,
- base::Bind(on_success, base::Owned(callbacks_.release()), results));
- }
-
- virtual void onError(T error) {
- OnErrorType on_error = &blink::WebCallbacks<S, T>::onError;
- // If the worker thread has been destroyed, then this task will be
- // silently discarded.
- WorkerTaskRunner::Instance()->PostTask(
- worker_thread_id_,
- base::Bind(on_error, base::Owned(callbacks_.release()), error));
- }
-
- private:
- scoped_ptr<blink::WebCallbacks<S, T>> callbacks_;
- int worker_thread_id_;
-};
-
-LazyInstance<ThreadLocalPointer<BackgroundSyncProviderThreadProxy>>::Leaky
- g_sync_provider_tls = LAZY_INSTANCE_INITIALIZER;
-
-void DuplicateRegistrationHandleCallbackOnSWThread(
- const BackgroundSyncProviderThreadProxy::
- DuplicateRegistrationHandleCallback& callback,
- BackgroundSyncError error,
- SyncRegistrationPtr registration) {
- callback.Run(error, registration.Pass());
-}
-
-void DuplicateRegistrationHandleCallbackOnMainThread(
- int worker_thread_id,
- const BackgroundSyncProviderThreadProxy::
- DuplicateRegistrationHandleCallback& callback,
- BackgroundSyncError error,
- SyncRegistrationPtr registration) {
- WorkerTaskRunner::Instance()->PostTask(
- worker_thread_id,
- base::Bind(&DuplicateRegistrationHandleCallbackOnSWThread, callback,
- error, base::Passed(registration.Pass())));
-}
-
-} // anonymous namespace
-
-// static
-BackgroundSyncProviderThreadProxy*
-BackgroundSyncProviderThreadProxy::GetThreadInstance(
- base::SingleThreadTaskRunner* main_thread_task_runner,
- BackgroundSyncProvider* sync_provider) {
- if (g_sync_provider_tls.Pointer()->Get())
- return g_sync_provider_tls.Pointer()->Get();
-
- if (!WorkerThread::GetCurrentId()) {
- // This could happen if GetThreadInstance is called very late (say by a
- // garbage collected SyncRegistration).
- return nullptr;
- }
-
- BackgroundSyncProviderThreadProxy* instance =
- new BackgroundSyncProviderThreadProxy(main_thread_task_runner,
- sync_provider);
- WorkerThread::AddObserver(instance);
- return instance;
-}
-
-void BackgroundSyncProviderThreadProxy::registerBackgroundSync(
- const blink::WebSyncRegistration* options,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- bool requested_from_service_worker,
- blink::WebSyncRegistrationCallbacks* callbacks) {
- DCHECK(options);
- DCHECK(service_worker_registration);
- DCHECK(callbacks);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &BackgroundSyncProvider::registerBackgroundSync,
- base::Unretained(sync_provider_), options,
- service_worker_registration, requested_from_service_worker,
- new CallbackThreadAdapter<blink::WebSyncRegistrationCallbacks>(
- make_scoped_ptr(callbacks), WorkerThread::GetCurrentId())));
-}
-
-void BackgroundSyncProviderThreadProxy::unregisterBackgroundSync(
- int64_t handle_id,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncUnregistrationCallbacks* callbacks) {
- DCHECK(service_worker_registration);
- DCHECK(callbacks);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &BackgroundSyncProvider::unregisterBackgroundSync,
- base::Unretained(sync_provider_), handle_id,
- service_worker_registration,
- new CallbackThreadAdapter<blink::WebSyncUnregistrationCallbacks>(
- make_scoped_ptr(callbacks), WorkerThread::GetCurrentId())));
-}
-
-void BackgroundSyncProviderThreadProxy::getRegistration(
- blink::WebSyncRegistration::Periodicity periodicity,
- const blink::WebString& tag,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncRegistrationCallbacks* callbacks) {
- DCHECK(service_worker_registration);
- DCHECK(callbacks);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &BackgroundSyncProvider::getRegistration,
- base::Unretained(sync_provider_), periodicity,
- // We cast WebString to string16 before crossing threads
- // for thread-safety.
- static_cast<base::string16>(tag), service_worker_registration,
- new CallbackThreadAdapter<blink::WebSyncRegistrationCallbacks>(
- make_scoped_ptr(callbacks), WorkerThread::GetCurrentId())));
-}
-
-void BackgroundSyncProviderThreadProxy::getRegistrations(
- blink::WebSyncRegistration::Periodicity periodicity,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncGetRegistrationsCallbacks* callbacks) {
- DCHECK(service_worker_registration);
- DCHECK(callbacks);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &BackgroundSyncProvider::getRegistrations,
- base::Unretained(sync_provider_), periodicity,
- service_worker_registration,
- new CallbackThreadAdapter<blink::WebSyncGetRegistrationsCallbacks>(
- make_scoped_ptr(callbacks), WorkerThread::GetCurrentId())));
-}
-
-void BackgroundSyncProviderThreadProxy::getPermissionStatus(
- blink::WebSyncRegistration::Periodicity periodicity,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncGetPermissionStatusCallbacks* callbacks) {
- DCHECK(service_worker_registration);
- DCHECK(callbacks);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &BackgroundSyncProvider::getPermissionStatus,
- base::Unretained(sync_provider_), periodicity,
- service_worker_registration,
- new CallbackThreadAdapter<blink::WebSyncGetPermissionStatusCallbacks>(
- make_scoped_ptr(callbacks), WorkerThread::GetCurrentId())));
-}
-
-void BackgroundSyncProviderThreadProxy::releaseRegistration(int64_t handle_id) {
- main_thread_task_runner_->PostTask(
- FROM_HERE, base::Bind(&BackgroundSyncProvider::releaseRegistration,
- base::Unretained(sync_provider_), handle_id));
-}
-
-void BackgroundSyncProviderThreadProxy::notifyWhenDone(
- int64_t handle_id,
- blink::WebSyncNotifyWhenDoneCallbacks* callbacks) {
- DCHECK(callbacks);
-
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &BackgroundSyncProvider::notifyWhenDone,
- base::Unretained(sync_provider_), handle_id,
- new CallbackThreadAdapter<blink::WebSyncNotifyWhenDoneCallbacks>(
- make_scoped_ptr(callbacks), WorkerThread::GetCurrentId())));
-}
-
-void BackgroundSyncProviderThreadProxy::DuplicateRegistrationHandle(
- int64_t handle_id,
- const DuplicateRegistrationHandleCallback& callback) {
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&BackgroundSyncProvider::DuplicateRegistrationHandle,
- base::Unretained(sync_provider_), handle_id,
- base::Bind(&DuplicateRegistrationHandleCallbackOnMainThread,
- WorkerThread::GetCurrentId(), callback)));
-}
-
-void BackgroundSyncProviderThreadProxy::WillStopCurrentWorkerThread() {
- delete this;
-}
-
-BackgroundSyncProviderThreadProxy::BackgroundSyncProviderThreadProxy(
- base::SingleThreadTaskRunner* main_thread_task_runner,
- BackgroundSyncProvider* sync_provider)
- : main_thread_task_runner_(main_thread_task_runner),
- sync_provider_(sync_provider) {
- g_sync_provider_tls.Pointer()->Set(this);
-}
-
-BackgroundSyncProviderThreadProxy::~BackgroundSyncProviderThreadProxy() {
- g_sync_provider_tls.Pointer()->Set(nullptr);
-}
-
-} // namespace content
diff --git a/content/child/background_sync/background_sync_provider_thread_proxy.h b/content/child/background_sync/background_sync_provider_thread_proxy.h
deleted file mode 100644
index f48a479..0000000
--- a/content/child/background_sync/background_sync_provider_thread_proxy.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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_CHILD_BACKGROUND_SYNC_BACKGROUND_SYNC_PROVIDER_THREAD_PROXY_H_
-#define CONTENT_CHILD_BACKGROUND_SYNC_BACKGROUND_SYNC_PROVIDER_THREAD_PROXY_H_
-
-#include "base/macros.h"
-#include "content/child/worker_task_runner.h"
-#include "content/common/background_sync_service.mojom.h"
-#include "content/public/child/worker_thread.h"
-#include "third_party/WebKit/public/platform/modules/background_sync/WebSyncProvider.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace content {
-
-class BackgroundSyncProvider;
-
-// BackgroundSyncProviderThreadProxy is a proxy to the BackgroundSyncProvider
-// for callers running on a different thread than the main thread. There is one
-// instance per worker thread.
-//
-// This class handles all of the thread switching, jumping to the main thread to
-// call the WebSyncProvider methods, and wrapping the callbacks passed in with
-// code to switch back to the original calling thread.
-class BackgroundSyncProviderThreadProxy : public blink::WebSyncProvider,
- public WorkerThread::Observer {
- public:
- using DuplicateRegistrationHandleCallback =
- base::Callback<void(BackgroundSyncError, SyncRegistrationPtr)>;
-
- static BackgroundSyncProviderThreadProxy* GetThreadInstance(
- base::SingleThreadTaskRunner* main_thread_task_runner,
- BackgroundSyncProvider* permissions_dispatcher);
-
- // blink::WebSyncProvider implementation
- void registerBackgroundSync(
- const blink::WebSyncRegistration* options,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- bool requested_from_service_worker,
- blink::WebSyncRegistrationCallbacks* callbacks) override;
- void unregisterBackgroundSync(
- int64_t handle_id,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncUnregistrationCallbacks* callbacks) override;
- void getRegistration(
- blink::WebSyncRegistration::Periodicity,
- const blink::WebString& tag,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncRegistrationCallbacks* callbacks) override;
- void getRegistrations(
- blink::WebSyncRegistration::Periodicity periodicity,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncGetRegistrationsCallbacks* callbacks) override;
- void getPermissionStatus(
- blink::WebSyncRegistration::Periodicity periodicity,
- blink::WebServiceWorkerRegistration* service_worker_registration,
- blink::WebSyncGetPermissionStatusCallbacks* callbacks) override;
- void releaseRegistration(int64_t handle_id) override;
- void notifyWhenDone(
- int64_t handle_id,
- blink::WebSyncNotifyWhenDoneCallbacks* callbacks) override;
-
- // Given |handle_id|, ask the provider for a new handle with the same
- // underlying registration.
- void DuplicateRegistrationHandle(
- int64_t handle_id,
- const DuplicateRegistrationHandleCallback& callback);
-
- // WorkerThread::Observer implementation.
- void WillStopCurrentWorkerThread() override;
-
- private:
- BackgroundSyncProviderThreadProxy(
- base::SingleThreadTaskRunner* main_thread_task_runner,
- BackgroundSyncProvider* sync_provider);
-
- ~BackgroundSyncProviderThreadProxy() override;
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
-
- // This belongs to the renderer main thread, (created by BlinkPlatformImpl)
- // and so should outlive the BackgroundSyncProviderThreadProxy, which is
- // created for a worker thread.
- BackgroundSyncProvider* sync_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(BackgroundSyncProviderThreadProxy);
-};
-
-} // namespace content
-
-#endif // CONTENT_CHILD_BACKGROUND_SYNC_BACKGROUND_SYNC_PROVIDER_THREAD_PROXY_H_
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 3b26b61..16f06ad 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -39,7 +39,6 @@
#include "content/app/resources/grit/content_resources.h"
#include "content/app/strings/grit/content_strings.h"
#include "content/child/background_sync/background_sync_provider.h"
-#include "content/child/background_sync/background_sync_provider_thread_proxy.h"
#include "content/child/child_thread_impl.h"
#include "content/child/content_child_helpers.h"
#include "content/child/geofencing/web_geofencing_provider_impl.h"
@@ -460,8 +459,8 @@ void BlinkPlatformImpl::InternalInit() {
push_dispatcher_ = ChildThreadImpl::current()->push_dispatcher();
permission_client_.reset(new PermissionDispatcher(
ChildThreadImpl::current()->service_registry()));
- sync_provider_.reset(new BackgroundSyncProvider(
- ChildThreadImpl::current()->service_registry()));
+ main_thread_sync_provider_.reset(
+ new BackgroundSyncProvider(main_thread_task_runner_.get()));
}
}
@@ -1215,14 +1214,11 @@ blink::WebPermissionClient* BlinkPlatformImpl::permissionClient() {
}
blink::WebSyncProvider* BlinkPlatformImpl::backgroundSyncProvider() {
- if (!sync_provider_.get())
- return nullptr;
-
if (IsMainThread())
- return sync_provider_.get();
+ return main_thread_sync_provider_.get();
- return BackgroundSyncProviderThreadProxy::GetThreadInstance(
- main_thread_task_runner_.get(), sync_provider_.get());
+ return BackgroundSyncProvider::GetOrCreateThreadSpecificInstance(
+ main_thread_task_runner_.get());
}
WebThemeEngine* BlinkPlatformImpl::themeEngine() {
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index f9bf754..4f23575 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -209,7 +209,7 @@ class CONTENT_EXPORT BlinkPlatformImpl
scoped_refptr<NotificationDispatcher> notification_dispatcher_;
scoped_refptr<PushDispatcher> push_dispatcher_;
scoped_ptr<PermissionDispatcher> permission_client_;
- scoped_ptr<BackgroundSyncProvider> sync_provider_;
+ scoped_ptr<BackgroundSyncProvider> main_thread_sync_provider_;
};
} // namespace content
diff --git a/content/content_child.gypi b/content/content_child.gypi
index 377e8de..158f134 100644
--- a/content/content_child.gypi
+++ b/content/content_child.gypi
@@ -46,8 +46,6 @@
'child/appcache/web_application_cache_host_impl.cc',
'child/appcache/web_application_cache_host_impl.h',
'child/assert_matching_enums.cc',
- 'child/background_sync/background_sync_provider_thread_proxy.cc',
- 'child/background_sync/background_sync_provider_thread_proxy.h',
'child/background_sync/background_sync_provider.cc',
'child/background_sync/background_sync_provider.h',
'child/background_sync/background_sync_type_converters.cc',
diff --git a/content/renderer/background_sync/background_sync_client_impl.cc b/content/renderer/background_sync/background_sync_client_impl.cc
index 9ba8af3..b71f0f3 100644
--- a/content/renderer/background_sync/background_sync_client_impl.cc
+++ b/content/renderer/background_sync/background_sync_client_impl.cc
@@ -4,7 +4,7 @@
#include "content/renderer/background_sync/background_sync_client_impl.h"
-#include "content/child/background_sync/background_sync_provider_thread_proxy.h"
+#include "content/child/background_sync/background_sync_provider.h"
#include "content/child/background_sync/background_sync_type_converters.h"
#include "content/renderer/service_worker/service_worker_context_client.h"
#include "third_party/WebKit/public/platform/Platform.h"
@@ -38,9 +38,8 @@ void BackgroundSyncClientImpl::Sync(int64_t handle_id,
// it.
// TODO(jkarlin): Change the WebSyncPlatform to support
// DuplicateRegistrationHandle and then this cast can go.
- BackgroundSyncProviderThreadProxy* provider =
- static_cast<BackgroundSyncProviderThreadProxy*>(
- blink::Platform::current()->backgroundSyncProvider());
+ BackgroundSyncProvider* provider = static_cast<BackgroundSyncProvider*>(
+ blink::Platform::current()->backgroundSyncProvider());
DCHECK(provider);
// TODO(jkarlin): Find a way to claim the handle safely without requiring a
diff --git a/content/test/data/background_sync/background_sync_test_helpers.js b/content/test/data/background_sync/background_sync_test_helpers.js
index ac175df..b74694a 100644
--- a/content/test/data/background_sync/background_sync_test_helpers.js
+++ b/content/test/data/background_sync/background_sync_test_helpers.js
@@ -43,6 +43,15 @@ function registerOneShot(tag) {
.catch(sendErrorToTest);
}
+function registerOneShotFromServiceWorker(tag) {
+ navigator.serviceWorker.ready
+ .then(function(swRegistration) {
+ swRegistration.active.postMessage({action: 'registerOneShot', tag: tag});
+ sendResultToTest('ok - ' + tag + ' register sent to SW');
+ })
+ .catch(sendErrorToTest);
+}
+
function unregisterOneShot(tag) {
navigator.serviceWorker.ready
.then(function(swRegistration) {
@@ -97,6 +106,16 @@ function getRegistrationOneShot(tag) {
.catch(sendErrorToTest);
}
+function getRegistrationOneShotFromServiceWorker(tag) {
+ navigator.serviceWorker.ready
+ .then(function(swRegistration) {
+ swRegistration.active.postMessage(
+ {action: 'getRegistrationOneShot', tag: tag});
+ sendResultToTest('ok - getRegistration sent to SW');
+ })
+ .catch(sendErrorToTest);
+}
+
function getRegistrationsOneShot(tag) {
navigator.serviceWorker.ready
.then(function(swRegistration) {
@@ -111,6 +130,15 @@ function getRegistrationsOneShot(tag) {
.catch(sendErrorToTest);
}
+function getRegistrationsOneShotFromServiceWorker() {
+ navigator.serviceWorker.ready
+ .then(function(swRegistration) {
+ swRegistration.active.postMessage({action: 'getRegistrationsOneShot'});
+ sendResultToTest('ok - getRegistrations sent to SW');
+ })
+ .catch(sendErrorToTest);
+}
+
function completeDelayedOneShot() {
navigator.serviceWorker.ready
.then(function(swRegistration) {
@@ -203,6 +231,6 @@ ResultQueue.prototype.popImmediately = function() {
navigator.serviceWorker.addEventListener('message', function(event) {
var message = event.data;
- if (message.type == 'sync')
+ if (message.type == 'sync' || message.type === 'register')
resultQueue.push(message.data);
-}, false); \ No newline at end of file
+}, false);
diff --git a/content/test/data/background_sync/service_worker.js b/content/test/data/background_sync/service_worker.js
index 68f57b5..bcd0c7a 100644
--- a/content/test/data/background_sync/service_worker.js
+++ b/content/test/data/background_sync/service_worker.js
@@ -52,6 +52,39 @@ this.onmessage = function(event) {
})
.catch(sendSyncErrorToClients);
}
+
+ if (event.data['action'] === 'registerOneShot') {
+ var tag = event.data['tag'];
+ registration.sync.register({'tag': tag})
+ .then(function (syncRegistration) {
+ sendMessageToClients('register', 'ok - ' + tag + ' registered in SW');
+ })
+ .catch(sendSyncErrorToClients);
+ }
+
+ if (event.data['action'] === 'getRegistrationOneShot') {
+ var tag = event.data['tag'];
+ registration.sync.getRegistration(tag)
+ .then(function(syncRegistration) {
+ if (!syncRegistration) {
+ sendMessageToClients('register', 'error - ' + tag + ' not found');
+ return;
+ }
+ sendMessageToClients('register', 'ok - ' + tag + ' found');
+ })
+ .catch(sendSyncErrorToClients);
+ }
+
+ if (event.data['action'] === 'getRegistrationsOneShot') {
+ registration.sync.getRegistrations()
+ .then(function(syncRegistrations) {
+ var tags = syncRegistrations.map(function(syncRegistration) {
+ return syncRegistration.tag;
+ });
+ sendMessageToClients('register', 'ok - ' + tags.toString());
+ })
+ .catch(sendSyncErrorToClients);
+ }
}
this.onsync = function(event) {