diff options
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) { |