diff options
author | sammc <sammc@chromium.org> | 2014-10-23 00:49:41 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-23 07:50:00 +0000 |
commit | b2c4362a1ee5487aeeb37e975ffa8d0e17fa2585 (patch) | |
tree | 93f845e1fad1d49082520642fd8011fe52bbe74e /extensions/browser/mojo | |
parent | bfd84a128ad5eda2f46b4def0d5a809435f3d5f3 (diff) | |
download | chromium_src-b2c4362a1ee5487aeeb37e975ffa8d0e17fa2585.zip chromium_src-b2c4362a1ee5487aeeb37e975ffa8d0e17fa2585.tar.gz chromium_src-b2c4362a1ee5487aeeb37e975ffa8d0e17fa2585.tar.bz2 |
Add a keep-alive mojo service for extensions.
This will allow apps and extensions APIs implemented on mojo services to
match the existing behavior of keeping background pages alive while API
calls are in progress.
BUG=389016
Review URL: https://codereview.chromium.org/673623004
Cr-Commit-Position: refs/heads/master@{#300853}
Diffstat (limited to 'extensions/browser/mojo')
-rw-r--r-- | extensions/browser/mojo/keep_alive_impl.cc | 35 | ||||
-rw-r--r-- | extensions/browser/mojo/keep_alive_impl.h | 41 | ||||
-rw-r--r-- | extensions/browser/mojo/keep_alive_impl_unittest.cc | 127 |
3 files changed, 203 insertions, 0 deletions
diff --git a/extensions/browser/mojo/keep_alive_impl.cc b/extensions/browser/mojo/keep_alive_impl.cc new file mode 100644 index 0000000..4073ce1 --- /dev/null +++ b/extensions/browser/mojo/keep_alive_impl.cc @@ -0,0 +1,35 @@ +// Copyright 2014 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 "extensions/browser/mojo/keep_alive_impl.h" + +#include "extensions/browser/extension_system.h" +#include "extensions/browser/process_manager.h" + +namespace extensions { + +// static +void KeepAliveImpl::Create(content::BrowserContext* context, + const Extension* extension, + mojo::InterfaceRequest<KeepAlive> request) { + mojo::BindToRequest(new KeepAliveImpl(context, extension), &request); +} + +KeepAliveImpl::KeepAliveImpl(content::BrowserContext* context, + const Extension* extension) + : context_(context), extension_(extension) { + ExtensionSystem* system = ExtensionSystem::Get(context_); + if (!system) + return; + system->process_manager()->IncrementLazyKeepaliveCount(extension_); +} + +KeepAliveImpl::~KeepAliveImpl() { + ExtensionSystem* system = ExtensionSystem::Get(context_); + if (!system) + return; + system->process_manager()->DecrementLazyKeepaliveCount(extension_); +} + +} // namespace extensions diff --git a/extensions/browser/mojo/keep_alive_impl.h b/extensions/browser/mojo/keep_alive_impl.h new file mode 100644 index 0000000..0544f95 --- /dev/null +++ b/extensions/browser/mojo/keep_alive_impl.h @@ -0,0 +1,41 @@ +// Copyright 2014 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 EXTENSIONS_BROWSER_MOJO_KEEP_ALIVE_IMPL_H_ +#define EXTENSIONS_BROWSER_MOJO_KEEP_ALIVE_IMPL_H_ + +#include "base/callback.h" +#include "extensions/common/mojo/keep_alive.mojom.h" +#include "mojo/public/cpp/bindings/interface_request.h" + +namespace content { +class BrowserContext; +} + +namespace extensions { +class Extension; + +// An RAII mojo service implementation for extension keep alives. This adds a +// keep alive on construction and removes it on destruction. +class KeepAliveImpl : public mojo::InterfaceImpl<KeepAlive> { + public: + // Create a keep alive for |extension| running in |context| and connect it to + // |request|. When the requester closes its pipe, the keep alive ends. + static void Create(content::BrowserContext* context, + const Extension* extension, + mojo::InterfaceRequest<KeepAlive> request); + + private: + KeepAliveImpl(content::BrowserContext* context, const Extension* extension); + ~KeepAliveImpl() override; + + content::BrowserContext* context_; + const Extension* extension_; + + DISALLOW_COPY_AND_ASSIGN(KeepAliveImpl); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_MOJO_KEEP_ALIVE_IMPL_H_ diff --git a/extensions/browser/mojo/keep_alive_impl_unittest.cc b/extensions/browser/mojo/keep_alive_impl_unittest.cc new file mode 100644 index 0000000..eea8f83 --- /dev/null +++ b/extensions/browser/mojo/keep_alive_impl_unittest.cc @@ -0,0 +1,127 @@ +// Copyright 2014 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 "extensions/browser/mojo/keep_alive_impl.h" + +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "content/public/browser/notification_service.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extensions_test.h" +#include "extensions/browser/mock_extension_system.h" +#include "extensions/browser/process_manager.h" +#include "extensions/browser/test_extensions_browser_client.h" +#include "extensions/common/extension_builder.h" + +namespace extensions { + +namespace { + +class TestExtensionSystem : public MockExtensionSystem { + public: + explicit TestExtensionSystem(content::BrowserContext* context) + : MockExtensionSystem(context), + process_manager_(ProcessManager::Create(context)) {} + + ProcessManager* process_manager() override { return process_manager_.get(); } + + private: + scoped_ptr<ProcessManager> process_manager_; +}; + +} // namespace + +class KeepAliveTest : public ExtensionsTest { + public: + KeepAliveTest() + : notification_service_(content::NotificationService::Create()) {} + ~KeepAliveTest() override {} + + void SetUp() override { + ExtensionsTest::SetUp(); + message_loop_.reset(new base::MessageLoop); + browser_client_.reset(new TestExtensionsBrowserClient(browser_context())); + browser_client_->set_extension_system_factory(&extension_system_factory_); + ExtensionsBrowserClient::Set(browser_client_.get()); + extension_ = + ExtensionBuilder() + .SetManifest( + DictionaryBuilder() + .Set("name", "app") + .Set("version", "1") + .Set("manifest_version", 2) + .Set("app", + DictionaryBuilder().Set( + "background", + DictionaryBuilder().Set( + "scripts", + ListBuilder().Append("background.js"))))) + .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + .Build(); + } + + void TearDown() override { + message_loop_.reset(); + ExtensionsTest::TearDown(); + } + + void WaitUntilLazyKeepAliveChanges() { + int initial_keep_alive_count = GetKeepAliveCount(); + while (GetKeepAliveCount() == initial_keep_alive_count) { + base::RunLoop().RunUntilIdle(); + } + } + + void CreateKeepAlive(mojo::InterfaceRequest<KeepAlive> request) { + KeepAliveImpl::Create(browser_context(), extension_.get(), request.Pass()); + } + + const Extension* extension() { return extension_.get(); } + + int GetKeepAliveCount() { + return ExtensionSystem::Get(browser_context()) + ->process_manager() + ->GetLazyKeepaliveCount(extension()); + } + + private: + scoped_ptr<base::MessageLoop> message_loop_; + MockExtensionSystemFactory<TestExtensionSystem> extension_system_factory_; + scoped_ptr<content::NotificationService> notification_service_; + scoped_refptr<const Extension> extension_; + scoped_ptr<TestExtensionsBrowserClient> browser_client_; + + DISALLOW_COPY_AND_ASSIGN(KeepAliveTest); +}; + +TEST_F(KeepAliveTest, Basic) { + mojo::InterfacePtr<KeepAlive> keep_alive; + CreateKeepAlive(mojo::GetProxy(&keep_alive)); + EXPECT_EQ(1, GetKeepAliveCount()); + + keep_alive.reset(); + WaitUntilLazyKeepAliveChanges(); + EXPECT_EQ(0, GetKeepAliveCount()); +} + +TEST_F(KeepAliveTest, TwoKeepAlives) { + mojo::InterfacePtr<KeepAlive> keep_alive; + CreateKeepAlive(mojo::GetProxy(&keep_alive)); + EXPECT_EQ(1, GetKeepAliveCount()); + + mojo::InterfacePtr<KeepAlive> other_keep_alive; + CreateKeepAlive(mojo::GetProxy(&other_keep_alive)); + EXPECT_EQ(2, GetKeepAliveCount()); + + keep_alive.reset(); + WaitUntilLazyKeepAliveChanges(); + EXPECT_EQ(1, GetKeepAliveCount()); + + other_keep_alive.reset(); + WaitUntilLazyKeepAliveChanges(); + EXPECT_EQ(0, GetKeepAliveCount()); +} + +} // namespace extensions |