1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/mojo/keep_alive_impl.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "content/public/browser/notification_service.h"
10 #include "extensions/browser/extension_registry.h"
11 #include "extensions/browser/extensions_test.h"
12 #include "extensions/browser/process_manager.h"
13 #include "extensions/common/extension_builder.h"
15 namespace extensions
{
17 class KeepAliveTest
: public ExtensionsTest
{
20 : notification_service_(content::NotificationService::Create()) {}
21 ~KeepAliveTest() override
{}
23 void SetUp() override
{
24 ExtensionsTest::SetUp();
25 message_loop_
.reset(new base::MessageLoop
);
32 .Set("manifest_version", 2)
34 DictionaryBuilder().Set(
36 DictionaryBuilder().Set(
38 ListBuilder().Append("background.js")))))
39 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
43 void TearDown() override
{
44 message_loop_
.reset();
45 ExtensionsTest::TearDown();
48 void WaitUntilLazyKeepAliveChanges() {
49 int initial_keep_alive_count
= GetKeepAliveCount();
50 while (GetKeepAliveCount() == initial_keep_alive_count
) {
51 base::RunLoop().RunUntilIdle();
55 void CreateKeepAlive(mojo::InterfaceRequest
<KeepAlive
> request
) {
56 KeepAliveImpl::Create(browser_context(), extension_
.get(), request
.Pass());
59 const Extension
* extension() { return extension_
.get(); }
61 int GetKeepAliveCount() {
62 return ProcessManager::Get(browser_context())
63 ->GetLazyKeepaliveCount(extension());
67 scoped_ptr
<base::MessageLoop
> message_loop_
;
68 scoped_ptr
<content::NotificationService
> notification_service_
;
69 scoped_refptr
<const Extension
> extension_
;
71 DISALLOW_COPY_AND_ASSIGN(KeepAliveTest
);
74 TEST_F(KeepAliveTest
, Basic
) {
75 mojo::InterfacePtr
<KeepAlive
> keep_alive
;
76 CreateKeepAlive(mojo::GetProxy(&keep_alive
));
77 EXPECT_EQ(1, GetKeepAliveCount());
80 WaitUntilLazyKeepAliveChanges();
81 EXPECT_EQ(0, GetKeepAliveCount());
84 TEST_F(KeepAliveTest
, TwoKeepAlives
) {
85 mojo::InterfacePtr
<KeepAlive
> keep_alive
;
86 CreateKeepAlive(mojo::GetProxy(&keep_alive
));
87 EXPECT_EQ(1, GetKeepAliveCount());
89 mojo::InterfacePtr
<KeepAlive
> other_keep_alive
;
90 CreateKeepAlive(mojo::GetProxy(&other_keep_alive
));
91 EXPECT_EQ(2, GetKeepAliveCount());
94 WaitUntilLazyKeepAliveChanges();
95 EXPECT_EQ(1, GetKeepAliveCount());
97 other_keep_alive
.reset();
98 WaitUntilLazyKeepAliveChanges();
99 EXPECT_EQ(0, GetKeepAliveCount());
102 TEST_F(KeepAliveTest
, UnloadExtension
) {
103 mojo::InterfacePtr
<KeepAlive
> keep_alive
;
104 CreateKeepAlive(mojo::GetProxy(&keep_alive
));
105 EXPECT_EQ(1, GetKeepAliveCount());
107 scoped_refptr
<const Extension
> other_extension
=
113 .Set("manifest_version", 2)
114 .Set("app", DictionaryBuilder().Set(
116 DictionaryBuilder().Set(
118 ListBuilder().Append("background.js")))))
119 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
122 ExtensionRegistry::Get(browser_context())
123 ->TriggerOnUnloaded(other_extension
.get(),
124 UnloadedExtensionInfo::REASON_DISABLE
);
125 EXPECT_EQ(1, GetKeepAliveCount());
127 ExtensionRegistry::Get(browser_context())
128 ->TriggerOnUnloaded(extension(), UnloadedExtensionInfo::REASON_DISABLE
);
129 // When its extension is unloaded, the KeepAliveImpl should not modify the
130 // keep-alive count for its extension. However, ProcessManager resets its
131 // keep-alive count for an unloaded extension.
132 EXPECT_EQ(0, GetKeepAliveCount());
134 // Wait for |keep_alive| to disconnect.
135 base::RunLoop run_loop
;
136 keep_alive
.set_connection_error_handler(run_loop
.QuitClosure());
140 TEST_F(KeepAliveTest
, Shutdown
) {
141 mojo::InterfacePtr
<KeepAlive
> keep_alive
;
142 CreateKeepAlive(mojo::GetProxy(&keep_alive
));
143 EXPECT_EQ(1, GetKeepAliveCount());
145 ExtensionRegistry::Get(browser_context())->Shutdown();
146 // After a shutdown event, the KeepAliveImpl should not access its
147 // ProcessManager and so the keep-alive count should remain unchanged.
148 EXPECT_EQ(1, GetKeepAliveCount());
150 // Wait for |keep_alive| to disconnect.
151 base::RunLoop run_loop
;
152 keep_alive
.set_connection_error_handler(run_loop
.QuitClosure());
156 } // namespace extensions