summaryrefslogtreecommitdiffstats
path: root/extensions/browser/mojo
diff options
context:
space:
mode:
authorsammc <sammc@chromium.org>2014-10-23 00:49:41 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-23 07:50:00 +0000
commitb2c4362a1ee5487aeeb37e975ffa8d0e17fa2585 (patch)
tree93f845e1fad1d49082520642fd8011fe52bbe74e /extensions/browser/mojo
parentbfd84a128ad5eda2f46b4def0d5a809435f3d5f3 (diff)
downloadchromium_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.cc35
-rw-r--r--extensions/browser/mojo/keep_alive_impl.h41
-rw-r--r--extensions/browser/mojo/keep_alive_impl_unittest.cc127
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