karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 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 | |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 7 | #include "base/stl_util.h" |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 8 | #include "components/crx_file/id_util.h" |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 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" |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 12 | #include "extensions/browser/extension_prefs.h" |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 13 | #include "extensions/browser/extension_registry.h" |
| 14 | #include "extensions/browser/extension_registry_factory.h" |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 15 | #include "extensions/browser/extension_util.h" |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 16 | #include "extensions/browser/extensions_test.h" |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 17 | #include "extensions/browser/test_extensions_browser_client.h" |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 18 | #include "extensions/common/extension_builder.h" |
| 19 | #include "extensions/common/extension_messages.h" |
| 20 | |
| 21 | namespace extensions { |
| 22 | |
| 23 | class RendererStartupHelperTest : public ExtensionsTest { |
| 24 | public: |
| 25 | RendererStartupHelperTest() {} |
| 26 | ~RendererStartupHelperTest() override {} |
| 27 | |
| 28 | void SetUp() override { |
| 29 | ExtensionsTest::SetUp(); |
Jeremy Roman | 16529d0e | 2017-08-24 18:13:47 | [diff] [blame] | 30 | helper_ = std::make_unique<RendererStartupHelper>(browser_context()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 31 | registry_ = |
| 32 | ExtensionRegistryFactory::GetForBrowserContext(browser_context()); |
| 33 | render_process_host_ = |
Jeremy Roman | 16529d0e | 2017-08-24 18:13:47 | [diff] [blame] | 34 | std::make_unique<content::MockRenderProcessHost>(browser_context()); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 35 | incognito_render_process_host_ = |
Jeremy Roman | 16529d0e | 2017-08-24 18:13:47 | [diff] [blame] | 36 | std::make_unique<content::MockRenderProcessHost>(incognito_context()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 37 | extension_ = CreateExtension("ext_1"); |
| 38 | } |
| 39 | |
| 40 | void TearDown() override { |
| 41 | render_process_host_.reset(); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 42 | incognito_render_process_host_.reset(); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 43 | helper_.reset(); |
| 44 | ExtensionsTest::TearDown(); |
| 45 | } |
| 46 | |
| 47 | protected: |
| 48 | void SimulateRenderProcessCreated(content::RenderProcessHost* rph) { |
| 49 | content::NotificationService::current()->Notify( |
| 50 | content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| 51 | content::Source<content::RenderProcessHost>(rph), |
| 52 | content::NotificationService::NoDetails()); |
| 53 | } |
| 54 | |
| 55 | void SimulateRenderProcessTerminated(content::RenderProcessHost* rph) { |
| 56 | content::NotificationService::current()->Notify( |
| 57 | content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 58 | content::Source<content::RenderProcessHost>(rph), |
| 59 | content::NotificationService::NoDetails()); |
| 60 | } |
| 61 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 62 | scoped_refptr<const Extension> CreateExtension(const std::string& id_input) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 63 | std::unique_ptr<base::DictionaryValue> manifest = |
| 64 | DictionaryBuilder() |
| 65 | .Set("name", "extension") |
| 66 | .Set("description", "an extension") |
| 67 | .Set("manifest_version", 2) |
| 68 | .Set("version", "0.1") |
| 69 | .Build(); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 70 | return CreateExtension(id_input, std::move(manifest)); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 71 | } |
| 72 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 73 | scoped_refptr<const Extension> CreateTheme(const std::string& id_input) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 74 | std::unique_ptr<base::DictionaryValue> manifest = |
| 75 | DictionaryBuilder() |
| 76 | .Set("name", "theme") |
| 77 | .Set("description", "a theme") |
| 78 | .Set("theme", DictionaryBuilder().Build()) |
| 79 | .Set("manifest_version", 2) |
| 80 | .Set("version", "0.1") |
| 81 | .Build(); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 82 | return CreateExtension(id_input, std::move(manifest)); |
| 83 | } |
| 84 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 85 | scoped_refptr<const Extension> CreatePlatformApp( |
| 86 | const std::string& id_input) { |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 87 | std::unique_ptr<base::Value> background = |
| 88 | DictionaryBuilder() |
| 89 | .Set("scripts", ListBuilder().Append("background.js").Build()) |
| 90 | .Build(); |
| 91 | std::unique_ptr<base::DictionaryValue> manifest = |
| 92 | DictionaryBuilder() |
| 93 | .Set("name", "platform_app") |
| 94 | .Set("description", "a platform app") |
| 95 | .Set("app", DictionaryBuilder() |
| 96 | .Set("background", std::move(background)) |
| 97 | .Build()) |
| 98 | .Set("manifest_version", 2) |
| 99 | .Set("version", "0.1") |
| 100 | .Build(); |
| 101 | return CreateExtension(id_input, std::move(manifest)); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 102 | } |
| 103 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 104 | void AddExtensionToRegistry(scoped_refptr<const Extension> extension) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 105 | registry_->AddEnabled(extension); |
| 106 | } |
| 107 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 108 | void RemoveExtensionFromRegistry(scoped_refptr<const Extension> extension) { |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 109 | registry_->RemoveEnabled(extension->id()); |
| 110 | } |
| 111 | |
| 112 | bool IsProcessInitialized(content::RenderProcessHost* rph) { |
Jan Wilken Dörrie | 0fd53a2 | 2019-06-07 09:55:46 | [diff] [blame] | 113 | return base::Contains(helper_->initialized_processes_, rph); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 114 | } |
| 115 | |
| 116 | bool IsExtensionLoaded(const Extension& extension) { |
Jan Wilken Dörrie | 0fd53a2 | 2019-06-07 09:55:46 | [diff] [blame] | 117 | return base::Contains(helper_->extension_process_map_, extension.id()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | bool IsExtensionLoadedInProcess(const Extension& extension, |
| 121 | content::RenderProcessHost* rph) { |
| 122 | return IsExtensionLoaded(extension) && |
Jan Wilken Dörrie | 0fd53a2 | 2019-06-07 09:55:46 | [diff] [blame] | 123 | base::Contains(helper_->extension_process_map_[extension.id()], rph); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | bool IsExtensionPendingActivationInProcess(const Extension& extension, |
| 127 | content::RenderProcessHost* rph) { |
Jan Wilken Dörrie | 0fd53a2 | 2019-06-07 09:55:46 | [diff] [blame] | 128 | return base::Contains(helper_->pending_active_extensions_, rph) && |
| 129 | base::Contains(helper_->pending_active_extensions_[rph], |
| 130 | extension.id()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | std::unique_ptr<RendererStartupHelper> helper_; |
| 134 | ExtensionRegistry* registry_; // Weak. |
| 135 | std::unique_ptr<content::MockRenderProcessHost> render_process_host_; |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 136 | std::unique_ptr<content::MockRenderProcessHost> |
| 137 | incognito_render_process_host_; |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 138 | scoped_refptr<const Extension> extension_; |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 139 | |
| 140 | private: |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 141 | scoped_refptr<const Extension> CreateExtension( |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 142 | const std::string& id_input, |
| 143 | std::unique_ptr<base::DictionaryValue> manifest) { |
| 144 | return ExtensionBuilder() |
| 145 | .SetManifest(std::move(manifest)) |
| 146 | .SetID(crx_file::id_util::GenerateId(id_input)) |
| 147 | .Build(); |
| 148 | } |
| 149 | |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 150 | DISALLOW_COPY_AND_ASSIGN(RendererStartupHelperTest); |
| 151 | }; |
| 152 | |
| 153 | // Tests extension loading, unloading and activation and render process creation |
| 154 | // and termination. |
| 155 | TEST_F(RendererStartupHelperTest, NormalExtensionLifecycle) { |
| 156 | // Initialize render process. |
| 157 | EXPECT_FALSE(IsProcessInitialized(render_process_host_.get())); |
| 158 | SimulateRenderProcessCreated(render_process_host_.get()); |
| 159 | EXPECT_TRUE(IsProcessInitialized(render_process_host_.get())); |
| 160 | |
| 161 | IPC::TestSink& sink = render_process_host_->sink(); |
| 162 | |
| 163 | // Enable extension. |
| 164 | sink.ClearMessages(); |
| 165 | EXPECT_FALSE(IsExtensionLoaded(*extension_)); |
| 166 | AddExtensionToRegistry(extension_); |
| 167 | helper_->OnExtensionLoaded(*extension_); |
| 168 | EXPECT_TRUE( |
| 169 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 170 | EXPECT_FALSE(IsExtensionPendingActivationInProcess( |
| 171 | *extension_, render_process_host_.get())); |
| 172 | ASSERT_EQ(1u, sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 173 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID), |
| 174 | sink.GetMessageAt(0)->type()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 175 | |
| 176 | // Activate extension. |
| 177 | sink.ClearMessages(); |
| 178 | helper_->ActivateExtensionInProcess(*extension_, render_process_host_.get()); |
| 179 | EXPECT_FALSE(IsExtensionPendingActivationInProcess( |
| 180 | *extension_, render_process_host_.get())); |
| 181 | ASSERT_EQ(1u, sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 182 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_ActivateExtension::ID), |
| 183 | sink.GetMessageAt(0)->type()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 184 | |
| 185 | // Disable extension. |
| 186 | sink.ClearMessages(); |
| 187 | RemoveExtensionFromRegistry(extension_); |
| 188 | helper_->OnExtensionUnloaded(*extension_); |
| 189 | EXPECT_FALSE(IsExtensionLoaded(*extension_)); |
| 190 | ASSERT_EQ(1u, sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 191 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Unloaded::ID), |
| 192 | sink.GetMessageAt(0)->type()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 193 | |
| 194 | // Extension enabled again. |
| 195 | sink.ClearMessages(); |
| 196 | AddExtensionToRegistry(extension_); |
| 197 | helper_->OnExtensionLoaded(*extension_); |
| 198 | EXPECT_TRUE( |
| 199 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 200 | EXPECT_FALSE(IsExtensionPendingActivationInProcess( |
| 201 | *extension_, render_process_host_.get())); |
| 202 | ASSERT_EQ(1u, sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 203 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID), |
| 204 | sink.GetMessageAt(0)->type()); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 205 | |
| 206 | // Render Process terminated. |
| 207 | SimulateRenderProcessTerminated(render_process_host_.get()); |
| 208 | EXPECT_FALSE(IsProcessInitialized(render_process_host_.get())); |
| 209 | EXPECT_TRUE(IsExtensionLoaded(*extension_)); |
| 210 | EXPECT_FALSE( |
| 211 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 212 | EXPECT_FALSE(IsExtensionPendingActivationInProcess( |
| 213 | *extension_, render_process_host_.get())); |
| 214 | } |
| 215 | |
| 216 | // Tests that activating an extension in an uninitialized render process works |
| 217 | // fine. |
| 218 | TEST_F(RendererStartupHelperTest, EnabledBeforeProcessInitialized) { |
| 219 | EXPECT_FALSE(IsProcessInitialized(render_process_host_.get())); |
| 220 | IPC::TestSink& sink = render_process_host_->sink(); |
| 221 | |
| 222 | // Enable extension. The render process isn't initialized yet, so the |
| 223 | // extension should be added to the list of extensions awaiting activation. |
| 224 | sink.ClearMessages(); |
| 225 | AddExtensionToRegistry(extension_); |
| 226 | helper_->OnExtensionLoaded(*extension_); |
| 227 | helper_->ActivateExtensionInProcess(*extension_, render_process_host_.get()); |
| 228 | EXPECT_EQ(0u, sink.message_count()); |
| 229 | EXPECT_TRUE(IsExtensionLoaded(*extension_)); |
| 230 | EXPECT_FALSE( |
| 231 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 232 | EXPECT_TRUE(IsExtensionPendingActivationInProcess( |
| 233 | *extension_, render_process_host_.get())); |
| 234 | |
| 235 | // Initialize the render process. |
| 236 | SimulateRenderProcessCreated(render_process_host_.get()); |
| 237 | // The renderer would have been sent multiple initialization messages |
| 238 | // including the loading and activation messages for the extension. |
| 239 | EXPECT_LE(2u, sink.message_count()); |
| 240 | EXPECT_TRUE(IsProcessInitialized(render_process_host_.get())); |
| 241 | EXPECT_TRUE( |
| 242 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 243 | EXPECT_FALSE(IsExtensionPendingActivationInProcess( |
| 244 | *extension_, render_process_host_.get())); |
| 245 | } |
| 246 | |
| 247 | // Tests that themes aren't loaded in a renderer process. |
| 248 | TEST_F(RendererStartupHelperTest, LoadTheme) { |
| 249 | // Initialize render process. |
| 250 | EXPECT_FALSE(IsProcessInitialized(render_process_host_.get())); |
| 251 | SimulateRenderProcessCreated(render_process_host_.get()); |
| 252 | EXPECT_TRUE(IsProcessInitialized(render_process_host_.get())); |
| 253 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 254 | scoped_refptr<const Extension> extension(CreateTheme("theme")); |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 255 | ASSERT_TRUE(extension->is_theme()); |
| 256 | |
| 257 | IPC::TestSink& sink = render_process_host_->sink(); |
| 258 | |
| 259 | // Enable the theme. Verify it isn't loaded and activated in the renderer. |
| 260 | sink.ClearMessages(); |
| 261 | EXPECT_FALSE(IsExtensionLoaded(*extension)); |
| 262 | AddExtensionToRegistry(extension_); |
| 263 | helper_->OnExtensionLoaded(*extension); |
| 264 | EXPECT_EQ(0u, sink.message_count()); |
| 265 | EXPECT_TRUE(IsExtensionLoaded(*extension)); |
| 266 | EXPECT_FALSE( |
| 267 | IsExtensionLoadedInProcess(*extension, render_process_host_.get())); |
| 268 | |
| 269 | helper_->ActivateExtensionInProcess(*extension, render_process_host_.get()); |
| 270 | EXPECT_EQ(0u, sink.message_count()); |
| 271 | EXPECT_FALSE(IsExtensionPendingActivationInProcess( |
| 272 | *extension, render_process_host_.get())); |
| 273 | |
| 274 | helper_->OnExtensionUnloaded(*extension); |
| 275 | EXPECT_EQ(0u, sink.message_count()); |
| 276 | EXPECT_FALSE(IsExtensionLoaded(*extension)); |
| 277 | } |
| 278 | |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 279 | // Tests that only incognito-enabled extensions are loaded in an incognito |
| 280 | // context. |
| 281 | TEST_F(RendererStartupHelperTest, ExtensionInIncognitoRenderer) { |
| 282 | // Initialize the incognito renderer. |
| 283 | EXPECT_FALSE(IsProcessInitialized(incognito_render_process_host_.get())); |
| 284 | SimulateRenderProcessCreated(incognito_render_process_host_.get()); |
| 285 | EXPECT_TRUE(IsProcessInitialized(incognito_render_process_host_.get())); |
| 286 | |
| 287 | IPC::TestSink& sink = render_process_host_->sink(); |
| 288 | IPC::TestSink& incognito_sink = incognito_render_process_host_->sink(); |
| 289 | |
| 290 | // Enable the extension. It should not be loaded in the initialized incognito |
| 291 | // renderer. |
| 292 | sink.ClearMessages(); |
| 293 | incognito_sink.ClearMessages(); |
| 294 | EXPECT_FALSE(util::IsIncognitoEnabled(extension_->id(), browser_context())); |
| 295 | EXPECT_FALSE(IsExtensionLoaded(*extension_)); |
| 296 | AddExtensionToRegistry(extension_); |
| 297 | helper_->OnExtensionLoaded(*extension_); |
| 298 | EXPECT_EQ(0u, sink.message_count()); |
| 299 | EXPECT_EQ(0u, incognito_sink.message_count()); |
| 300 | EXPECT_TRUE(IsExtensionLoaded(*extension_)); |
| 301 | EXPECT_FALSE(IsExtensionLoadedInProcess( |
| 302 | *extension_, incognito_render_process_host_.get())); |
| 303 | EXPECT_FALSE( |
| 304 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 305 | |
| 306 | // Initialize the normal renderer. The extension should get loaded in it. |
| 307 | sink.ClearMessages(); |
| 308 | incognito_sink.ClearMessages(); |
| 309 | EXPECT_FALSE(IsProcessInitialized(render_process_host_.get())); |
| 310 | SimulateRenderProcessCreated(render_process_host_.get()); |
| 311 | EXPECT_TRUE(IsProcessInitialized(render_process_host_.get())); |
| 312 | EXPECT_TRUE( |
| 313 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 314 | EXPECT_FALSE(IsExtensionLoadedInProcess( |
| 315 | *extension_, incognito_render_process_host_.get())); |
| 316 | // Multiple initialization messages including the extension load message |
| 317 | // should be dispatched to the non-incognito renderer. |
| 318 | EXPECT_LE(1u, sink.message_count()); |
| 319 | EXPECT_EQ(0u, incognito_sink.message_count()); |
| 320 | |
| 321 | // Enable the extension in incognito mode. This will reload the extension. |
| 322 | sink.ClearMessages(); |
| 323 | incognito_sink.ClearMessages(); |
| 324 | ExtensionPrefs::Get(browser_context()) |
| 325 | ->SetIsIncognitoEnabled(extension_->id(), true); |
| 326 | helper_->OnExtensionUnloaded(*extension_); |
| 327 | helper_->OnExtensionLoaded(*extension_); |
| 328 | EXPECT_TRUE(IsExtensionLoadedInProcess(*extension_, |
| 329 | incognito_render_process_host_.get())); |
| 330 | EXPECT_TRUE( |
| 331 | IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| 332 | // The extension would not have been unloaded from the incognito renderer |
| 333 | // since it wasn't loaded. |
| 334 | ASSERT_EQ(1u, incognito_sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 335 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID), |
| 336 | incognito_sink.GetMessageAt(0)->type()); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 337 | // The extension would be first unloaded and then loaded from the normal |
| 338 | // renderer. |
| 339 | ASSERT_EQ(2u, sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 340 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Unloaded::ID), |
| 341 | sink.GetMessageAt(0)->type()); |
| 342 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID), |
| 343 | sink.GetMessageAt(1)->type()); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 344 | } |
| 345 | |
| 346 | // Tests that platform apps are always loaded in an incognito renderer. |
| 347 | TEST_F(RendererStartupHelperTest, PlatformAppInIncognitoRenderer) { |
| 348 | // Initialize the incognito renderer. |
| 349 | EXPECT_FALSE(IsProcessInitialized(incognito_render_process_host_.get())); |
| 350 | SimulateRenderProcessCreated(incognito_render_process_host_.get()); |
| 351 | EXPECT_TRUE(IsProcessInitialized(incognito_render_process_host_.get())); |
| 352 | |
| 353 | IPC::TestSink& incognito_sink = incognito_render_process_host_->sink(); |
| 354 | |
Devlin Cronin | 8e5892f | 2018-10-04 00:13:43 | [diff] [blame] | 355 | scoped_refptr<const Extension> platform_app( |
| 356 | CreatePlatformApp("platform_app")); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 357 | ASSERT_TRUE(platform_app->is_platform_app()); |
| 358 | EXPECT_FALSE(util::IsIncognitoEnabled(platform_app->id(), browser_context())); |
| 359 | EXPECT_FALSE(util::CanBeIncognitoEnabled(platform_app.get())); |
| 360 | |
| 361 | // Enable the app. It should get loaded in the incognito renderer even though |
| 362 | // IsIncognitoEnabled returns false for it, since it can't be enabled for |
| 363 | // incognito. |
| 364 | incognito_sink.ClearMessages(); |
| 365 | AddExtensionToRegistry(platform_app); |
| 366 | helper_->OnExtensionLoaded(*platform_app); |
| 367 | EXPECT_TRUE(IsExtensionLoadedInProcess(*platform_app, |
| 368 | incognito_render_process_host_.get())); |
| 369 | ASSERT_EQ(1u, incognito_sink.message_count()); |
Hans Wennborg | 4b99b0f | 2017-12-07 17:01:28 | [diff] [blame] | 370 | EXPECT_EQ(static_cast<uint32_t>(ExtensionMsg_Loaded::ID), |
| 371 | incognito_sink.GetMessageAt(0)->type()); |
karandeepb | 18ab4ab8 | 2017-04-07 00:27:31 | [diff] [blame] | 372 | } |
| 373 | |
karandeepb | 53c8920d | 2017-04-06 02:13:07 | [diff] [blame] | 374 | } // namespace extensions |