Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: extensions/browser/renderer_startup_helper_unittest.cc

Issue 2766063003: Extensions: Keep track of loaded extensions in RendererStartupHelper. (Closed)
Patch Set: Address review Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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.
4
5 #include "extensions/browser/renderer_startup_helper.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/stl_util.h"
9 #include "content/public/browser/notification_service.h"
10 #include "content/public/browser/notification_types.h"
11 #include "content/public/test/mock_render_process_host.h"
12 #include "extensions/browser/extension_registry.h"
13 #include "extensions/browser/extension_registry_factory.h"
14 #include "extensions/browser/extensions_test.h"
15 #include "extensions/common/extension_builder.h"
16 #include "extensions/common/extension_messages.h"
17
18 namespace extensions {
19
20 class RendererStartupHelperTest : public ExtensionsTest {
21 public:
22 RendererStartupHelperTest() {}
23 ~RendererStartupHelperTest() override {}
24
25 void SetUp() override {
26 ExtensionsTest::SetUp();
27 helper_ = base::MakeUnique<RendererStartupHelper>(browser_context());
28 registry_ =
29 ExtensionRegistryFactory::GetForBrowserContext(browser_context());
30 render_process_host_ =
31 base::MakeUnique<content::MockRenderProcessHost>(browser_context());
32 extension_ = CreateExtension("ext_1");
33 }
34
35 void TearDown() override {
36 render_process_host_.reset();
37 helper_.reset();
38 ExtensionsTest::TearDown();
39 }
40
41 protected:
42 void SimulateRenderProcessCreated(content::RenderProcessHost* rph) {
43 content::NotificationService::current()->Notify(
44 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
45 content::Source<content::RenderProcessHost>(rph),
46 content::NotificationService::NoDetails());
47 }
48
49 void SimulateRenderProcessTerminated(content::RenderProcessHost* rph) {
50 content::NotificationService::current()->Notify(
51 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
52 content::Source<content::RenderProcessHost>(rph),
53 content::NotificationService::NoDetails());
54 }
55
56 scoped_refptr<Extension> CreateExtension(const std::string& extension_id) {
57 std::unique_ptr<base::DictionaryValue> manifest =
58 DictionaryBuilder()
59 .Set("name", "extension")
60 .Set("description", "an extension")
61 .Set("manifest_version", 2)
62 .Set("version", "0.1")
63 .Build();
64 return ExtensionBuilder()
65 .SetManifest(std::move(manifest))
66 .SetID(extension_id)
67 .Build();
68 }
69
70 scoped_refptr<Extension> CreateTheme(const std::string& extension_id) {
71 std::unique_ptr<base::DictionaryValue> manifest =
72 DictionaryBuilder()
73 .Set("name", "theme")
74 .Set("description", "a theme")
75 .Set("theme", DictionaryBuilder().Build())
76 .Set("manifest_version", 2)
77 .Set("version", "0.1")
78 .Build();
79 return ExtensionBuilder()
80 .SetManifest(std::move(manifest))
81 .SetID(extension_id)
82 .Build();
83 }
84
85 void AddExtensionToRegistry(scoped_refptr<Extension> extension) {
86 registry_->AddEnabled(extension);
87 }
88
89 void RemoveExtensionFromRegistry(scoped_refptr<Extension> extension) {
90 registry_->RemoveEnabled(extension->id());
91 }
92
93 bool IsProcessInitialized(content::RenderProcessHost* rph) {
94 return base::ContainsKey(helper_->initialized_processes_, rph);
95 }
96
97 bool IsExtensionLoaded(const Extension& extension) {
98 return base::ContainsKey(helper_->extension_process_map_, extension.id());
99 }
100
101 bool IsExtensionLoadedInProcess(const Extension& extension,
102 content::RenderProcessHost* rph) {
103 return IsExtensionLoaded(extension) &&
104 base::ContainsKey(helper_->extension_process_map_[extension.id()],
105 rph);
106 }
107
108 bool IsExtensionPendingActivationInProcess(const Extension& extension,
109 content::RenderProcessHost* rph) {
110 return base::ContainsKey(helper_->pending_active_extensions_, rph) &&
111 base::ContainsKey(helper_->pending_active_extensions_[rph],
112 extension.id());
113 }
114
115 std::unique_ptr<RendererStartupHelper> helper_;
116 ExtensionRegistry* registry_; // Weak.
117 std::unique_ptr<content::MockRenderProcessHost> render_process_host_;
118 scoped_refptr<Extension> extension_;
119
120 private:
121 DISALLOW_COPY_AND_ASSIGN(RendererStartupHelperTest);
122 };
123
124 // Tests extension loading, unloading and activation and render process creation
125 // and termination.
126 TEST_F(RendererStartupHelperTest, NormalExtensionLifecycle) {
127 // Initialize render process.
128 EXPECT_FALSE(IsProcessInitialized(render_process_host_.get()));
129 SimulateRenderProcessCreated(render_process_host_.get());
130 EXPECT_TRUE(IsProcessInitialized(render_process_host_.get()));
131
132 IPC::TestSink& sink = render_process_host_->sink();
133
134 // Enable extension.
135 sink.ClearMessages();
136 EXPECT_FALSE(IsExtensionLoaded(*extension_));
137 AddExtensionToRegistry(extension_);
138 helper_->OnExtensionLoaded(*extension_);
139 EXPECT_TRUE(
140 IsExtensionLoadedInProcess(*extension_, render_process_host_.get()));
141 EXPECT_FALSE(IsExtensionPendingActivationInProcess(
142 *extension_, render_process_host_.get()));
143 ASSERT_EQ(1u, sink.message_count());
144 EXPECT_EQ(ExtensionMsg_Loaded::ID, sink.GetMessageAt(0)->type());
145
146 // Activate extension.
147 sink.ClearMessages();
148 helper_->ActivateExtensionInProcess(*extension_, render_process_host_.get());
149 EXPECT_FALSE(IsExtensionPendingActivationInProcess(
150 *extension_, render_process_host_.get()));
151 ASSERT_EQ(1u, sink.message_count());
152 EXPECT_EQ(ExtensionMsg_ActivateExtension::ID, sink.GetMessageAt(0)->type());
153
154 // Disable extension.
155 sink.ClearMessages();
156 RemoveExtensionFromRegistry(extension_);
157 helper_->OnExtensionUnloaded(*extension_);
158 EXPECT_FALSE(IsExtensionLoaded(*extension_));
159 ASSERT_EQ(1u, sink.message_count());
160 EXPECT_EQ(ExtensionMsg_Unloaded::ID, sink.GetMessageAt(0)->type());
161
162 // Extension enabled again.
163 sink.ClearMessages();
164 AddExtensionToRegistry(extension_);
165 helper_->OnExtensionLoaded(*extension_);
166 EXPECT_TRUE(
167 IsExtensionLoadedInProcess(*extension_, render_process_host_.get()));
168 EXPECT_FALSE(IsExtensionPendingActivationInProcess(
169 *extension_, render_process_host_.get()));
170 ASSERT_EQ(1u, sink.message_count());
171 EXPECT_EQ(ExtensionMsg_Loaded::ID, sink.GetMessageAt(0)->type());
172
173 // Render Process terminated.
174 SimulateRenderProcessTerminated(render_process_host_.get());
175 EXPECT_FALSE(IsProcessInitialized(render_process_host_.get()));
176 EXPECT_TRUE(IsExtensionLoaded(*extension_));
177 EXPECT_FALSE(
178 IsExtensionLoadedInProcess(*extension_, render_process_host_.get()));
179 EXPECT_FALSE(IsExtensionPendingActivationInProcess(
180 *extension_, render_process_host_.get()));
181 }
182
183 // Tests that activating an extension in an uninitialized render process works
184 // fine.
185 TEST_F(RendererStartupHelperTest, EnabledBeforeProcessInitialized) {
186 EXPECT_FALSE(IsProcessInitialized(render_process_host_.get()));
187 IPC::TestSink& sink = render_process_host_->sink();
188
189 // Enable extension. The render process isn't initialized yet, so the
190 // extension should be added to the list of extensions awaiting activation.
191 sink.ClearMessages();
192 AddExtensionToRegistry(extension_);
193 helper_->OnExtensionLoaded(*extension_);
194 helper_->ActivateExtensionInProcess(*extension_, render_process_host_.get());
195 EXPECT_EQ(0u, sink.message_count());
196 EXPECT_TRUE(IsExtensionLoaded(*extension_));
197 EXPECT_FALSE(
198 IsExtensionLoadedInProcess(*extension_, render_process_host_.get()));
199 EXPECT_TRUE(IsExtensionPendingActivationInProcess(
200 *extension_, render_process_host_.get()));
201
202 // Initialize the render process.
203 SimulateRenderProcessCreated(render_process_host_.get());
204 // The renderer would have been sent multiple initialization messages
205 // including the loading and activation messages for the extension.
206 EXPECT_LE(2u, sink.message_count());
207 EXPECT_TRUE(IsProcessInitialized(render_process_host_.get()));
208 EXPECT_TRUE(
209 IsExtensionLoadedInProcess(*extension_, render_process_host_.get()));
210 EXPECT_FALSE(IsExtensionPendingActivationInProcess(
211 *extension_, render_process_host_.get()));
212 }
213
214 // Tests that themes aren't loaded in a renderer process.
215 TEST_F(RendererStartupHelperTest, LoadTheme) {
216 // Initialize render process.
217 EXPECT_FALSE(IsProcessInitialized(render_process_host_.get()));
218 SimulateRenderProcessCreated(render_process_host_.get());
219 EXPECT_TRUE(IsProcessInitialized(render_process_host_.get()));
220
221 scoped_refptr<Extension> extension(CreateTheme("theme"));
222 ASSERT_TRUE(extension->is_theme());
223
224 IPC::TestSink& sink = render_process_host_->sink();
225
226 // Enable the theme. Verify it isn't loaded and activated in the renderer.
227 sink.ClearMessages();
228 EXPECT_FALSE(IsExtensionLoaded(*extension));
229 AddExtensionToRegistry(extension_);
230 helper_->OnExtensionLoaded(*extension);
231 EXPECT_EQ(0u, sink.message_count());
232 EXPECT_TRUE(IsExtensionLoaded(*extension));
233 EXPECT_FALSE(
234 IsExtensionLoadedInProcess(*extension, render_process_host_.get()));
235
236 helper_->ActivateExtensionInProcess(*extension, render_process_host_.get());
237 EXPECT_EQ(0u, sink.message_count());
238 EXPECT_FALSE(IsExtensionPendingActivationInProcess(
239 *extension, render_process_host_.get()));
240
241 helper_->OnExtensionUnloaded(*extension);
242 EXPECT_EQ(0u, sink.message_count());
243 EXPECT_FALSE(IsExtensionLoaded(*extension));
244 }
245
246 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/renderer_startup_helper.cc ('k') | extensions/shell/browser/shell_extension_system.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698