1 // Copyright 2013 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/process_manager.h" 6 7 #include "chrome/browser/extensions/browser_action_test_util.h" 8 #include "chrome/browser/extensions/extension_browsertest.h" 9 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/ui/tabs/tab_strip_model.h" 11 #include "chrome/test/base/in_process_browser_test.h" 12 #include "chrome/test/base/ui_test_utils.h" 13 #include "content/public/browser/notification_service.h" 14 #include "content/public/browser/web_contents.h" 15 #include "content/public/test/test_utils.h" 16 #include "extensions/browser/extension_system.h" 17 #include "net/dns/mock_host_resolver.h" 18 #include "net/test/embedded_test_server/embedded_test_server.h" 19 20 namespace extensions { 21 22 // Exists as a browser test because ExtensionHosts are hard to create without 23 // a real browser. 24 typedef ExtensionBrowserTest ProcessManagerBrowserTest; 25 26 // Test that basic extension loading creates the appropriate ExtensionHosts 27 // and background pages. 28 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, 29 ExtensionHostCreation) { 30 ProcessManager* pm = ExtensionSystem::Get(profile())->process_manager(); 31 32 // We start with no background hosts. 33 ASSERT_EQ(0u, pm->background_hosts().size()); 34 ASSERT_EQ(0u, pm->GetAllViews().size()); 35 36 // Load an extension with a background page. 37 scoped_refptr<const Extension> extension = 38 LoadExtension(test_data_dir_.AppendASCII("api_test") 39 .AppendASCII("browser_action") 40 .AppendASCII("none")); 41 ASSERT_TRUE(extension.get()); 42 43 // Process manager gains a background host. 44 EXPECT_EQ(1u, pm->background_hosts().size()); 45 EXPECT_EQ(1u, pm->GetAllViews().size()); 46 EXPECT_TRUE(pm->GetBackgroundHostForExtension(extension->id())); 47 EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url())); 48 EXPECT_EQ(1u, pm->GetRenderViewHostsForExtension(extension->id()).size()); 49 EXPECT_FALSE(pm->IsBackgroundHostClosing(extension->id())); 50 EXPECT_EQ(0, pm->GetLazyKeepaliveCount(extension.get())); 51 52 // Unload the extension. 53 UnloadExtension(extension->id()); 54 55 // Background host disappears. 56 EXPECT_EQ(0u, pm->background_hosts().size()); 57 EXPECT_EQ(0u, pm->GetAllViews().size()); 58 EXPECT_FALSE(pm->GetBackgroundHostForExtension(extension->id())); 59 EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url())); 60 EXPECT_EQ(0u, pm->GetRenderViewHostsForExtension(extension->id()).size()); 61 EXPECT_FALSE(pm->IsBackgroundHostClosing(extension->id())); 62 EXPECT_EQ(0, pm->GetLazyKeepaliveCount(extension.get())); 63 } 64 65 // Test that loading an extension with a browser action does not create a 66 // background page and that clicking on the action creates the appropriate 67 // ExtensionHost. 68 // Disabled due to flake, see http://crbug.com/315242 69 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, 70 DISABLED_PopupHostCreation) { 71 ProcessManager* pm = ExtensionSystem::Get(profile())->process_manager(); 72 73 // Load an extension with the ability to open a popup but no background 74 // page. 75 scoped_refptr<const Extension> popup = 76 LoadExtension(test_data_dir_.AppendASCII("api_test") 77 .AppendASCII("browser_action") 78 .AppendASCII("popup")); 79 ASSERT_TRUE(popup); 80 81 // No background host was added. 82 EXPECT_EQ(0u, pm->background_hosts().size()); 83 EXPECT_EQ(0u, pm->GetAllViews().size()); 84 EXPECT_FALSE(pm->GetBackgroundHostForExtension(popup->id())); 85 EXPECT_EQ(0u, pm->GetRenderViewHostsForExtension(popup->id()).size()); 86 EXPECT_TRUE(pm->GetSiteInstanceForURL(popup->url())); 87 EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id())); 88 EXPECT_EQ(0, pm->GetLazyKeepaliveCount(popup.get())); 89 90 // Simulate clicking on the action to open a popup. 91 BrowserActionTestUtil test_util(browser()); 92 content::WindowedNotificationObserver frame_observer( 93 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, 94 content::NotificationService::AllSources()); 95 // Open popup in the first extension. 96 test_util.Press(0); 97 frame_observer.Wait(); 98 ASSERT_TRUE(test_util.HasPopup()); 99 100 // We now have a view, but still no background hosts. 101 EXPECT_EQ(0u, pm->background_hosts().size()); 102 EXPECT_EQ(1u, pm->GetAllViews().size()); 103 EXPECT_FALSE(pm->GetBackgroundHostForExtension(popup->id())); 104 EXPECT_EQ(1u, pm->GetRenderViewHostsForExtension(popup->id()).size()); 105 EXPECT_TRUE(pm->GetSiteInstanceForURL(popup->url())); 106 EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id())); 107 EXPECT_EQ(0, pm->GetLazyKeepaliveCount(popup.get())); 108 } 109 110 // Content loaded from http://hlogonemlfkgpejgnedahbkiabcdhnnn should not 111 // interact with an installed extension with that ID. Regression test 112 // for bug 357382. 113 IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, HttpHostMatchingExtensionId) { 114 ProcessManager* pm = ExtensionSystem::Get(profile())->process_manager(); 115 116 // We start with no background hosts. 117 ASSERT_EQ(0u, pm->background_hosts().size()); 118 ASSERT_EQ(0u, pm->GetAllViews().size()); 119 120 // Load an extension with a background page. 121 scoped_refptr<const Extension> extension = 122 LoadExtension(test_data_dir_.AppendASCII("api_test") 123 .AppendASCII("browser_action") 124 .AppendASCII("none")); 125 126 // Set up a test server running at http://[extension-id] 127 ASSERT_TRUE(extension.get()); 128 const std::string aliased_host = extension->id(); 129 host_resolver()->AddRule(aliased_host, "127.0.0.1"); 130 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 131 GURL url = 132 embedded_test_server()->GetURL("/extensions/test_file_with_body.html"); 133 GURL::Replacements replace_host; 134 replace_host.SetHostStr(aliased_host); 135 url = url.ReplaceComponents(replace_host); 136 137 // Load a page from the test host in a new tab. 138 ui_test_utils::NavigateToURLWithDisposition( 139 browser(), 140 url, 141 NEW_FOREGROUND_TAB, 142 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 143 144 // Sanity check that there's no bleeding between the extension and the tab. 145 content::WebContents* tab_web_contents = 146 browser()->tab_strip_model()->GetActiveWebContents(); 147 EXPECT_EQ(url, tab_web_contents->GetVisibleURL()); 148 EXPECT_TRUE(NULL == pm->GetExtensionForRenderViewHost( 149 tab_web_contents->GetRenderViewHost())) 150 << "Non-extension content must not have an associated extension"; 151 ASSERT_EQ(1u, pm->GetRenderViewHostsForExtension(extension->id()).size()); 152 content::WebContents* extension_web_contents = 153 content::WebContents::FromRenderViewHost( 154 *pm->GetRenderViewHostsForExtension(extension->id()).begin()); 155 EXPECT_TRUE(extension_web_contents->GetSiteInstance() != 156 tab_web_contents->GetSiteInstance()); 157 EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url()) != 158 tab_web_contents->GetSiteInstance()); 159 EXPECT_TRUE(pm->GetBackgroundHostForExtension(extension->id())); 160 } 161 162 } // namespace extensions 163