diff options
author | jkarlin <jkarlin@chromium.org> | 2015-11-06 05:18:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-06 13:19:28 +0000 |
commit | fe08f137f867befed12f1b9c0c1ed8e5c2d59e80 (patch) | |
tree | d1ccce2ae2e9464d7be01fab970d5cdf168fc9c6 /content/browser/background_sync | |
parent | 9919d1bdb281d1a0ef47786818536d90bc18ef4e (diff) | |
download | chromium_src-fe08f137f867befed12f1b9c0c1ed8e5c2d59e80.zip chromium_src-fe08f137f867befed12f1b9c0c1ed8e5c2d59e80.tar.gz chromium_src-fe08f137f867befed12f1b9c0c1ed8e5c2d59e80.tar.bz2 |
[BackgroundSync] Unify relaunching browser API for all platforms
Creates BackgroundSyncController::RunInBackground(bool) which can be used on all platforms. On Android it will forward to LaunchBrowserWhenNextOnline and on other platforms it will enable background mode.
Adds content_unittests for the BackgroundSyncController to verify that it's being called correctly by the BackgroundSyncManager. This requires access to a BrowserContext from tests (hence the switch to using the single argument EmbeddedWorkerTestHelper constructor).
BUG=549550,489705,549826,548052
Review URL: https://codereview.chromium.org/1422583003
Cr-Commit-Position: refs/heads/master@{#358313}
Diffstat (limited to 'content/browser/background_sync')
4 files changed, 119 insertions, 38 deletions
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index 5624239..df3fcb6 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc @@ -91,6 +91,18 @@ void NotifyBackgroundSyncRegisteredOnUIThread( background_sync_controller->NotifyBackgroundSyncRegistered(origin); } +void RunInBackgroundOnUIThread( + const scoped_refptr<ServiceWorkerContextWrapper>& sw_context_wrapper, + bool enabled) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + BackgroundSyncController* background_sync_controller = + GetBackgroundSyncControllerOnUIThread(sw_context_wrapper); + if (background_sync_controller) { + background_sync_controller->RunInBackground(enabled); + } +} + } // namespace BackgroundSyncManager::BackgroundSyncRegistrations:: @@ -973,7 +985,6 @@ bool BackgroundSyncManager::IsRegistrationReadyToFire( } void BackgroundSyncManager::SchedulePendingRegistrations() { -#if defined(OS_ANDROID) bool keep_browser_alive_for_one_shot = false; for (const auto& sw_id_and_registrations : active_registrations_) { @@ -994,26 +1005,8 @@ void BackgroundSyncManager::SchedulePendingRegistrations() { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&BackgroundSyncManager::SchedulePendingRegistrationsOnUIThread, - base::Unretained(this), keep_browser_alive_for_one_shot)); - -#else -// TODO(jkarlin): Toggle Chrome's background mode. -#endif -} - -void BackgroundSyncManager::SchedulePendingRegistrationsOnUIThread( - bool keep_browser_alive_for_one_shot) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - BackgroundSyncController* background_sync_controller = - GetBackgroundSyncControllerOnUIThread(service_worker_context_); - if (background_sync_controller) { - // TODO(jkarlin): Use the context's path instead of the 'this' pointer as an - // identifier. See crbug.com/489705. - background_sync_controller->LaunchBrowserWhenNextOnline( - this, keep_browser_alive_for_one_shot); - } + base::Bind(RunInBackgroundOnUIThread, service_worker_context_, + keep_browser_alive_for_one_shot)); } void BackgroundSyncManager::FireReadyEvents() { @@ -1058,7 +1051,7 @@ void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) { // If there are no registrations currently ready, then just run |callback|. // Otherwise, fire them all, and record the result when done. - if (sw_id_and_keys_to_fire.size() == 0) { + if (sw_id_and_keys_to_fire.empty()) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(callback)); } else { diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index ff6994e..236f832 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h @@ -274,10 +274,9 @@ class CONTENT_EXPORT BackgroundSyncManager // seen (on Android the browser is instead woken up the next time it goes // online). For periodic syncs this means creating an alarm. void SchedulePendingRegistrations(); - void SchedulePendingRegistrationsOnUIThread( - bool keep_browser_alive_for_one_shot); - // FireReadyEvents and callbacks + // FireReadyEvents scans the list of available events and fires those that are + // ready to fire. For those that can't yet be fired, wakeup alarms are set. void FireReadyEvents(); void FireReadyEventsImpl(const base::Closure& callback); void FireReadyEventsDidFindRegistration( diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc index de8a37c..0cc7152 100644 --- a/content/browser/background_sync/background_sync_manager_unittest.cc +++ b/content/browser/background_sync/background_sync_manager_unittest.cc @@ -22,6 +22,9 @@ #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_storage.h" +#include "content/browser/storage_partition_impl.h" +#include "content/public/browser/background_sync_controller.h" +#include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/network_change_notifier.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,7 +37,6 @@ const char kPattern1[] = "https://example.com/a"; const char kPattern2[] = "https://example.com/b"; const char kScript1[] = "https://example.com/a/script.js"; const char kScript2[] = "https://example.com/b/script.js"; -const int kRenderProcessId = 99; const int kProviderId1 = 1; const int kProviderId2 = 2; @@ -109,6 +111,35 @@ class TestPowerSource : public base::PowerMonitorSource { bool test_on_battery_power_ = false; }; +class CountingBackgroundSyncController : public BackgroundSyncController { + public: + CountingBackgroundSyncController() = default; + + // BackgroundSyncController Overrides + void NotifyBackgroundSyncRegistered(const GURL& origin) override { + registration_count_ += 1; + registration_origin_ = origin; + } + void RunInBackground(bool enabled) override { + run_in_background_count_ += 1; + run_in_background_enabled_ = enabled; + } + + int registration_count() const { return registration_count_; } + GURL registration_origin() const { return registration_origin_; } + int run_in_background_count() const { return run_in_background_count_; } + bool run_in_background_enabled() const { return run_in_background_enabled_; } + + private: + int registration_count_ = 0; + GURL registration_origin_; + + int run_in_background_count_ = 0; + bool run_in_background_enabled_ = true; + + DISALLOW_COPY_AND_ASSIGN(CountingBackgroundSyncController); +}; + } // namespace // A BackgroundSyncManager that can simulate delaying and corrupting the backend @@ -221,6 +252,7 @@ class BackgroundSyncManagerTest : public testing::Test { : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), network_change_notifier_(net::NetworkChangeNotifier::CreateMock()), test_background_sync_manager_(nullptr), + counting_controller_(nullptr), callback_status_(BACKGROUND_SYNC_STATUS_OK), callback_sw_status_code_(SERVICE_WORKER_OK), sync_events_called_(0) { @@ -239,8 +271,19 @@ class BackgroundSyncManagerTest : public testing::Test { // Don't let the tests be confused by the real-world device connectivity BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(true); - helper_.reset( - new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId)); + // TODO(jkarlin): Create a new object with all of the necessary SW calls + // so that we can inject test versions instead of bringing up all of this + // extra SW stuff. + helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); + + // Create a StoragePartition with the correct BrowserContext so that the + // BackgroundSyncManager can find the BrowserContext through it. + storage_partition_impl_.reset(new StoragePartitionImpl( + helper_->browser_context(), base::FilePath(), nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr)); + helper_->context_wrapper()->set_storage_partition( + storage_partition_impl_.get()); power_monitor_source_ = new TestPowerSource(); // power_monitor_ takes ownership of power_monitor_source. @@ -251,6 +294,12 @@ class BackgroundSyncManagerTest : public testing::Test { SetupBackgroundSyncManager(); + scoped_ptr<CountingBackgroundSyncController> background_sync_controller( + new CountingBackgroundSyncController()); + counting_controller_ = background_sync_controller.get(); + helper_->browser_context()->SetBackgroundSyncController( + background_sync_controller.Pass()); + // Wait for storage to finish initializing before registering service // workers. base::RunLoop().RunUntilIdle(); @@ -281,13 +330,14 @@ class BackgroundSyncManagerTest : public testing::Test { // Register window clients for the service workers ServiceWorkerProviderHost* host_1 = new ServiceWorkerProviderHost( - kRenderProcessId, MSG_ROUTING_NONE /* render_frame_id */, kProviderId1, + helper_->mock_render_process_id(), + MSG_ROUTING_NONE /* render_frame_id */, kProviderId1, SERVICE_WORKER_PROVIDER_FOR_WINDOW, helper_->context()->AsWeakPtr(), nullptr); host_1->SetDocumentUrl(GURL(kPattern1)); ServiceWorkerProviderHost* host_2 = new ServiceWorkerProviderHost( - kRenderProcessId /* dummy render proces id */, + helper_->mock_render_process_id(), MSG_ROUTING_NONE /* render_frame_id */, kProviderId2, SERVICE_WORKER_PROVIDER_FOR_WINDOW, helper_->context()->AsWeakPtr(), nullptr); @@ -311,7 +361,8 @@ class BackgroundSyncManagerTest : public testing::Test { } void RemoveWindowClients() { - helper_->context()->RemoveAllProviderHostsForProcess(kRenderProcessId); + helper_->context()->RemoveAllProviderHostsForProcess( + helper_->mock_render_process_id()); } void SetNetwork(net::NetworkChangeNotifier::ConnectionType connection_type) { @@ -562,7 +613,9 @@ class BackgroundSyncManagerTest : public testing::Test { scoped_ptr<base::PowerMonitor> power_monitor_; scoped_ptr<EmbeddedWorkerTestHelper> helper_; scoped_ptr<BackgroundSyncManager> background_sync_manager_; + scoped_ptr<StoragePartitionImpl> storage_partition_impl_; TestBackgroundSyncManager* test_background_sync_manager_; + CountingBackgroundSyncController* counting_controller_; int64 sw_registration_id_1_; int64 sw_registration_id_2_; @@ -1688,9 +1741,9 @@ TEST_F(BackgroundSyncManagerTest, KillManagerMidSync) { TEST_F(BackgroundSyncManagerTest, RegisterWithClientWindowForWrongOrigin) { RemoveWindowClients(); ServiceWorkerProviderHost* host = new ServiceWorkerProviderHost( - kRenderProcessId, MSG_ROUTING_NONE /* render_frame_id */, kProviderId1, - SERVICE_WORKER_PROVIDER_FOR_WINDOW, helper_->context()->AsWeakPtr(), - nullptr); + helper_->mock_render_process_id(), MSG_ROUTING_NONE /* render_frame_id */, + kProviderId1, SERVICE_WORKER_PROVIDER_FOR_WINDOW, + helper_->context()->AsWeakPtr(), nullptr); host->SetDocumentUrl(GURL("http://example.com:9999")); helper_->context()->AddProviderHost(make_scoped_ptr(host)); EXPECT_FALSE(Register(sync_options_1_)); @@ -1741,4 +1794,40 @@ TEST_F(BackgroundSyncManagerTest, FieldTrialDisablesManager) { EXPECT_EQ(BACKGROUND_SYNC_STATUS_STORAGE_ERROR, callback_status_); } +TEST_F(BackgroundSyncManagerTest, NotifyBackgroundSyncRegistered) { + // Verify that the BackgroundSyncController is informed of registrations. + EXPECT_EQ(0, counting_controller_->registration_count()); + EXPECT_TRUE(Register(sync_options_1_)); + EXPECT_EQ(1, counting_controller_->registration_count()); + EXPECT_EQ(GURL(kPattern1).GetOrigin().spec(), + counting_controller_->registration_origin().spec()); +} + +TEST_F(BackgroundSyncManagerTest, WakeBrowserCalled) { + InitDelayedSyncEventTest(); + + // The BackgroundSyncManager should declare in initialization + // that it doesn't need to be woken up since it has no registrations. + EXPECT_LT(0, counting_controller_->run_in_background_count()); + EXPECT_FALSE(counting_controller_->run_in_background_enabled()); + + SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE); + EXPECT_FALSE(counting_controller_->run_in_background_enabled()); + + // Register a one-shot but it can't fire due to lack of network, wake up is + // required. + Register(sync_options_1_); + EXPECT_TRUE(counting_controller_->run_in_background_enabled()); + + // Start the event but it will pause mid-sync due to + // InitDelayedSyncEventTest() above. + SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI); + EXPECT_FALSE(counting_controller_->run_in_background_enabled()); + + // Finish the sync. + sync_fired_callback_.Run(SERVICE_WORKER_OK); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(counting_controller_->run_in_background_enabled()); +} + } // namespace content diff --git a/content/browser/background_sync/background_sync_service_impl_unittest.cc b/content/browser/background_sync/background_sync_service_impl_unittest.cc index 8ffded0..916c4cb 100644 --- a/content/browser/background_sync/background_sync_service_impl_unittest.cc +++ b/content/browser/background_sync/background_sync_service_impl_unittest.cc @@ -26,7 +26,6 @@ namespace { const char kServiceWorkerPattern[] = "https://example.com/a"; const char kServiceWorkerScript[] = "https://example.com/a/script.js"; -const int kRenderProcessId = 99; const int kProviderId = 1; // Callbacks from SetUp methods @@ -133,7 +132,7 @@ class BackgroundSyncServiceImplTest : public testing::Test { // SetUp helper methods void CreateTestHelper() { embedded_worker_helper_.reset( - new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId)); + new EmbeddedWorkerTestHelper(base::FilePath())); } void CreateBackgroundSyncContext() { @@ -175,7 +174,8 @@ class BackgroundSyncServiceImplTest : public testing::Test { // Register window client for the service worker ServiceWorkerProviderHost* provider_host = new ServiceWorkerProviderHost( - kRenderProcessId, MSG_ROUTING_NONE /* render_frame_id */, kProviderId, + embedded_worker_helper_->mock_render_process_id(), + MSG_ROUTING_NONE /* render_frame_id */, kProviderId, SERVICE_WORKER_PROVIDER_FOR_WINDOW, embedded_worker_helper_->context()->AsWeakPtr(), nullptr); provider_host->SetDocumentUrl(GURL(kServiceWorkerPattern)); @@ -185,7 +185,7 @@ class BackgroundSyncServiceImplTest : public testing::Test { void RemoveWindowClient() { embedded_worker_helper_->context()->RemoveAllProviderHostsForProcess( - kRenderProcessId); + embedded_worker_helper_->mock_render_process_id()); } void CreateBackgroundSyncServiceImpl() { |