blob: 952bf210b1e14c4951192bc2b9f50d3d232b5a70 [file] [log] [blame]
[email protected]c333e792012-01-06 16:57:391// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]3a8eecb2010-04-22 23:56:302// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]3a8eecb2010-04-22 23:56:305#include "chrome/browser/extensions/extension_apitest.h"
6#include "chrome/browser/extensions/extension_host.h"
[email protected]6f371442011-11-09 06:45:467#include "chrome/browser/extensions/extension_service.h"
[email protected]06bdd2b2012-11-30 18:47:138#include "chrome/browser/extensions/extension_system.h"
[email protected]6f371442011-11-09 06:45:469#include "chrome/browser/extensions/process_map.h"
[email protected]8ecad5e2010-12-02 21:18:3310#include "chrome/browser/profiles/profile.h"
[email protected]079b3cc2012-09-26 19:59:1311#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]7b5dc002010-11-16 23:08:1012#include "chrome/browser/ui/browser.h"
[email protected]a37d4b02012-06-25 21:56:1013#include "chrome/browser/ui/browser_commands.h"
[email protected]d8748142012-05-16 21:13:4314#include "chrome/browser/ui/browser_finder.h"
[email protected]71b73f02011-04-06 15:57:2915#include "chrome/browser/ui/browser_list.h"
[email protected]d55c2382011-08-18 23:10:3616#include "chrome/browser/ui/browser_window.h"
[email protected]e0448872013-01-11 19:35:0217#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]884033e2012-04-16 19:38:4218#include "chrome/common/chrome_notification_types.h"
[email protected]3a8eecb2010-04-22 23:56:3019#include "chrome/common/chrome_switches.h"
[email protected]814a7bf0f2011-08-13 05:30:5920#include "chrome/common/extensions/extension.h"
[email protected]c2f36e3a2011-12-14 01:27:1921#include "chrome/common/extensions/extension_file_util.h"
[email protected]af44e7fb2011-07-29 18:32:3222#include "chrome/test/base/ui_test_utils.h"
[email protected]ad23a092011-12-28 07:02:0423#include "content/public/browser/navigation_entry.h"
[email protected]ad50def52011-10-19 23:17:0724#include "content/public/browser/notification_service.h"
[email protected]c333e792012-01-06 16:57:3925#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3326#include "content/public/browser/render_view_host.h"
[email protected]6acde6352012-01-04 16:52:2027#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4228#include "content/public/test/browser_test_utils.h"
[email protected]5b8ff1c2012-06-02 20:42:2029#include "content/public/test/test_navigation_observer.h"
[email protected]f2cb3cf2013-03-21 01:40:5330#include "net/dns/mock_host_resolver.h"
[email protected]36b643212012-09-07 12:53:0031#include "sync/api/string_ordinal.h"
[email protected]3a8eecb2010-04-22 23:56:3032
[email protected]c5eed492012-01-04 17:07:5033using content::NavigationController;
[email protected]eaabba22012-03-07 15:02:1134using content::RenderViewHost;
[email protected]4ca15302012-01-03 05:53:2035using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:3436using extensions::Extension;
[email protected]4ca15302012-01-03 05:53:2037
[email protected]7b54ca02012-03-02 18:06:5338class AppApiTest : public ExtensionApiTest {
39 protected:
40 // Gets the base URL for files for a specific test, making sure that it uses
41 // "localhost" as the hostname, since that is what the extent is declared
42 // as in the test apps manifests.
43 GURL GetTestBaseURL(std::string test_directory) {
44 GURL::Replacements replace_host;
45 std::string host_str("localhost"); // must stay in scope with replace_host
46 replace_host.SetHostStr(host_str);
47 GURL base_url = test_server()->GetURL(
48 "files/extensions/api_test/" + test_directory + "/");
49 return base_url.ReplaceComponents(replace_host);
50 }
51
52 // Pass flags to make testing apps easier.
[email protected]49aeab62013-02-07 02:53:1153 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
[email protected]7b54ca02012-03-02 18:06:5354 ExtensionApiTest::SetUpCommandLine(command_line);
55 CommandLine::ForCurrentProcess()->AppendSwitch(
56 switches::kDisablePopupBlocking);
57 CommandLine::ForCurrentProcess()->AppendSwitch(
58 switches::kAllowHTTPBackgroundPage);
59 }
60
61 // Helper function to test that independent tabs of the named app are loaded
62 // into separate processes.
63 void TestAppInstancesHelper(std::string app_name) {
64 LOG(INFO) << "Start of test.";
65
[email protected]06bdd2b2012-11-30 18:47:1366 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
67 browser()->profile())->extension_service()->process_map();
[email protected]7b54ca02012-03-02 18:06:5368
69 host_resolver()->AddRule("*", "127.0.0.1");
70 ASSERT_TRUE(test_server()->Start());
71
72 ASSERT_TRUE(LoadExtension(
73 test_data_dir_.AppendASCII(app_name)));
[email protected]50686c3b2013-04-27 00:26:2774 const Extension* extension = GetSingleLoadedExtension();
[email protected]7b54ca02012-03-02 18:06:5375
76 // Open two tabs in the app, one outside it.
77 GURL base_url = GetTestBaseURL(app_name);
78
79 // Test both opening a URL in a new tab, and opening a tab and then
80 // navigating it. Either way, app tabs should be considered extension
81 // processes, but they have no elevated privileges and thus should not
82 // have WebUI bindings.
83 ui_test_utils::NavigateToURLWithDisposition(
84 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
85 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
86 LOG(INFO) << "Nav 1.";
87 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:0288 browser()->tab_strip_model()->GetWebContentsAt(1)->
89 GetRenderProcessHost()->GetID()));
90 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:5391
[email protected]a7fe9112012-07-20 02:34:4592 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:4293 chrome::NOTIFICATION_TAB_ADDED,
[email protected]7b54ca02012-03-02 18:06:5394 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:1095 chrome::NewTab(browser());
[email protected]7b54ca02012-03-02 18:06:5396 tab_added_observer.Wait();
97 LOG(INFO) << "New tab.";
98 ui_test_utils::NavigateToURL(browser(),
99 base_url.Resolve("path2/empty.html"));
100 LOG(INFO) << "Nav 2.";
101 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02102 browser()->tab_strip_model()->GetWebContentsAt(2)->
103 GetRenderProcessHost()->GetID()));
104 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]7b54ca02012-03-02 18:06:53105
106 // We should have opened 2 new extension tabs. Including the original blank
107 // tab, we now have 3 tabs. The two app tabs should not be in the same
108 // process, since they do not have the background permission. (Thus, we
109 // want to separate them to improve responsiveness.)
[email protected]e0448872013-01-11 19:35:02110 ASSERT_EQ(3, browser()->tab_strip_model()->count());
111 WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
112 WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
[email protected]19da16a92012-05-23 17:11:29113 EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
[email protected]7b54ca02012-03-02 18:06:53114
115 // Opening tabs with window.open should keep the page in the opener's
116 // process.
[email protected]c987a242013-02-28 01:17:41117 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
118 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29119 OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53120 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29121 OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]7b54ca02012-03-02 18:06:53122 LOG(INFO) << "End of test.";
[email protected]50686c3b2013-04-27 00:26:27123 UnloadExtension(extension->id());
[email protected]7b54ca02012-03-02 18:06:53124 }
125};
126
[email protected]079b3cc2012-09-26 19:59:13127// Omits the disable-popup-blocking flag so we can cover that case.
128class BlockedAppApiTest : public AppApiTest {
129 protected:
[email protected]49aeab62013-02-07 02:53:11130 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
[email protected]079b3cc2012-09-26 19:59:13131 ExtensionApiTest::SetUpCommandLine(command_line);
132 CommandLine::ForCurrentProcess()->AppendSwitch(
133 switches::kAllowHTTPBackgroundPage);
134 }
135};
136
[email protected]7b54ca02012-03-02 18:06:53137// Tests that hosted apps with the background permission get a process-per-app
138// model, since all pages need to be able to script the background page.
[email protected]c9c206082013-01-29 00:42:56139// http://crbug.com/172750
140#if defined(OS_WIN)
141#define MAYBE_AppProcess DISABLED_AppProcess
142#else
143#define MAYBE_AppProcess AppProcess
144#endif
145IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcess) {
[email protected]87c7c292011-10-27 16:16:41146 LOG(INFO) << "Start of test.";
[email protected]9b600832011-10-26 20:31:59147
[email protected]06bdd2b2012-11-30 18:47:13148 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
149 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52150
[email protected]3a8eecb2010-04-22 23:56:30151 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]95409e12010-08-17 20:07:11152 ASSERT_TRUE(test_server()->Start());
[email protected]3a8eecb2010-04-22 23:56:30153
[email protected]cbf4d1912010-08-12 18:24:57154 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
[email protected]3a8eecb2010-04-22 23:56:30155
[email protected]87c7c292011-10-27 16:16:41156 LOG(INFO) << "Loaded extension.";
157
[email protected]cbf4d1912010-08-12 18:24:57158 // Open two tabs in the app, one outside it.
[email protected]118d3122011-08-10 17:09:53159 GURL base_url = GetTestBaseURL("app_process");
[email protected]fe3048872010-10-18 14:58:59160
[email protected]f0e13332011-05-20 22:41:14161 // Test both opening a URL in a new tab, and opening a tab and then navigating
162 // it. Either way, app tabs should be considered extension processes, but
163 // they have no elevated privileges and thus should not have WebUI bindings.
164 ui_test_utils::NavigateToURLWithDisposition(
165 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
166 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46167 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02168 browser()->tab_strip_model()->GetWebContentsAt(1)->
169 GetRenderProcessHost()->GetID()));
170 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41171 LOG(INFO) << "Nav 1.";
172
173 ui_test_utils::NavigateToURLWithDisposition(
174 browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
175 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
[email protected]6f371442011-11-09 06:45:46176 EXPECT_TRUE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02177 browser()->tab_strip_model()->GetWebContentsAt(2)->
178 GetRenderProcessHost()->GetID()));
179 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]87c7c292011-10-27 16:16:41180 LOG(INFO) << "Nav 2.";
181
[email protected]a7fe9112012-07-20 02:34:45182 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42183 chrome::NOTIFICATION_TAB_ADDED,
[email protected]87c7c292011-10-27 16:16:41184 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10185 chrome::NewTab(browser());
[email protected]87c7c292011-10-27 16:16:41186 tab_added_observer.Wait();
187 LOG(INFO) << "New tab.";
[email protected]cbf4d1912010-08-12 18:24:57188 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
[email protected]87c7c292011-10-27 16:16:41189 LOG(INFO) << "Nav 3.";
[email protected]6f371442011-11-09 06:45:46190 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02191 browser()->tab_strip_model()->GetWebContentsAt(3)->
192 GetRenderProcessHost()->GetID()));
193 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
[email protected]3a8eecb2010-04-22 23:56:30194
[email protected]056ad2a2011-07-12 02:13:55195 // We should have opened 3 new extension tabs. Including the original blank
196 // tab, we now have 4 tabs. Because the app_process app has the background
197 // permission, all of its instances are in the same process. Thus two tabs
198 // should be part of the extension app and grouped in the same process.
[email protected]e0448872013-01-11 19:35:02199 ASSERT_EQ(4, browser()->tab_strip_model()->count());
200 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]cbf4d1912010-08-12 18:24:57201
[email protected]19da16a92012-05-23 17:11:29202 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02203 browser()->tab_strip_model()->GetWebContentsAt(2)->
204 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29205 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02206 browser()->tab_strip_model()->GetWebContentsAt(3)->
207 GetRenderProcessHost());
[email protected]3a8eecb2010-04-22 23:56:30208
209 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41210 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
211 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29212 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41213 LOG(INFO) << "WindowOpenHelper 1.";
[email protected]19da16a92012-05-23 17:11:29214 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41215 LOG(INFO) << "WindowOpenHelper 2.";
[email protected]361a5f1f2011-10-05 20:11:15216 // TODO(creis): This should open in a new process (i.e., false for the last
[email protected]ea7b7d82012-05-25 17:29:17217 // argument), but we temporarily avoid swapping processes away from a hosted
218 // app if it has an opener, because some OAuth providers make script calls
219 // between non-app popups and non-app iframes in the app process.
[email protected]361a5f1f2011-10-05 20:11:15220 // See crbug.com/59285.
[email protected]19da16a92012-05-23 17:11:29221 OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
[email protected]87c7c292011-10-27 16:16:41222 LOG(INFO) << "WindowOpenHelper 3.";
[email protected]3a8eecb2010-04-22 23:56:30223
224 // Now let's have these pages navigate, into or out of the extension web
225 // extent. They should switch processes.
[email protected]9a1e6d42010-04-26 22:29:36226 const GURL& app_url(base_url.Resolve("path1/empty.html"));
227 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]e0448872013-01-11 19:35:02228 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
229 non_app_url);
[email protected]87c7c292011-10-27 16:16:41230 LOG(INFO) << "NavigateTabHelper 1.";
[email protected]e0448872013-01-11 19:35:02231 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
232 app_url);
[email protected]87c7c292011-10-27 16:16:41233 LOG(INFO) << "NavigateTabHelper 2.";
[email protected]ea7b7d82012-05-25 17:29:17234 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02235 browser()->tab_strip_model()->GetWebContentsAt(2)->
236 GetRenderProcessHost());
[email protected]19da16a92012-05-23 17:11:29237 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02238 browser()->tab_strip_model()->GetWebContentsAt(3)->
239 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04240
241 // If one of the popup tabs navigates back to the app, window.opener should
242 // be valid.
[email protected]e0448872013-01-11 19:35:02243 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
244 app_url);
[email protected]87c7c292011-10-27 16:16:41245 LOG(INFO) << "NavigateTabHelper 3.";
[email protected]19da16a92012-05-23 17:11:29246 EXPECT_EQ(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02247 browser()->tab_strip_model()->GetWebContentsAt(6)->
248 GetRenderProcessHost());
[email protected]08e94b82010-12-15 22:51:04249 bool windowOpenerValid = false;
[email protected]b6987e02013-01-04 18:30:43250 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02251 browser()->tab_strip_model()->GetWebContentsAt(6),
[email protected]06bc5d92013-01-02 22:44:13252 "window.domAutomationController.send(window.opener != null)",
[email protected]08e94b82010-12-15 22:51:04253 &windowOpenerValid));
254 ASSERT_TRUE(windowOpenerValid);
[email protected]87c7c292011-10-27 16:16:41255
256 LOG(INFO) << "End of test.";
[email protected]3a8eecb2010-04-22 23:56:30257}
[email protected]faf407b2011-01-05 01:24:32258
[email protected]056ad2a2011-07-12 02:13:55259// Test that hosted apps without the background permission use a process per app
260// instance model, such that separate instances are in separate processes.
[email protected]19da16a92012-05-23 17:11:29261IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessInstances) {
[email protected]7b54ca02012-03-02 18:06:53262 TestAppInstancesHelper("app_process_instances");
263}
[email protected]87c7c292011-10-27 16:16:41264
[email protected]7b54ca02012-03-02 18:06:53265// Test that hosted apps with the background permission but that set
266// allow_js_access to false also use a process per app instance model.
267// Separate instances should be in separate processes.
[email protected]0d70b7d42012-12-13 01:14:20268// Flaky on XP: http://crbug.com/165834
[email protected]0cfb748b2012-12-13 01:10:11269#if defined(OS_WIN)
270#define MAYBE_AppProcessBackgroundInstances \
271 DISABLED_AppProcessBackgroundInstances
272#else
273#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
274#endif
275IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
[email protected]7b54ca02012-03-02 18:06:53276 TestAppInstancesHelper("app_process_background_instances");
[email protected]056ad2a2011-07-12 02:13:55277}
278
[email protected]15877ca2011-11-18 22:40:52279// Tests that bookmark apps do not use the app process model and are treated
280// like normal web pages instead. http://crbug.com/104636.
[email protected]19da16a92012-05-23 17:11:29281IN_PROC_BROWSER_TEST_F(AppApiTest, BookmarkAppGetsNormalProcess) {
[email protected]06bdd2b2012-11-30 18:47:13282 ExtensionService* service = extensions::ExtensionSystem::Get(
283 browser()->profile())->extension_service();
[email protected]c2f36e3a2011-12-14 01:27:19284 extensions::ProcessMap* process_map = service->process_map();
[email protected]15877ca2011-11-18 22:40:52285
286 host_resolver()->AddRule("*", "127.0.0.1");
287 ASSERT_TRUE(test_server()->Start());
[email protected]15877ca2011-11-18 22:40:52288 GURL base_url = GetTestBaseURL("app_process");
289
[email protected]c2f36e3a2011-12-14 01:27:19290 // Load an app as a bookmark app.
291 std::string error;
292 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
293 test_data_dir_.AppendASCII("app_process"),
[email protected]12075d12013-02-27 05:38:05294 extensions::Manifest::UNPACKED,
[email protected]c2f36e3a2011-12-14 01:27:19295 Extension::FROM_BOOKMARK,
296 &error));
[email protected]26367b62012-10-04 23:03:32297 service->OnExtensionInstalled(extension,
[email protected]98270432012-09-11 20:51:24298 syncer::StringOrdinal::CreateInitialOrdinal(),
[email protected]0db124b02012-11-07 04:55:05299 false /* no requirement errors */,
300 false /* don't wait for idle */);
[email protected]c2f36e3a2011-12-14 01:27:19301 ASSERT_TRUE(extension.get());
302 ASSERT_TRUE(extension->from_bookmark());
303
[email protected]15877ca2011-11-18 22:40:52304 // Test both opening a URL in a new tab, and opening a tab and then navigating
305 // it. Either way, bookmark app tabs should be considered normal processes
306 // with no elevated privileges and no WebUI bindings.
307 ui_test_utils::NavigateToURLWithDisposition(
308 browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
309 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
310 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02311 browser()->tab_strip_model()->GetWebContentsAt(1)->
312 GetRenderProcessHost()->GetID()));
313 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52314
[email protected]a7fe9112012-07-20 02:34:45315 content::WindowedNotificationObserver tab_added_observer(
[email protected]884033e2012-04-16 19:38:42316 chrome::NOTIFICATION_TAB_ADDED,
[email protected]15877ca2011-11-18 22:40:52317 content::NotificationService::AllSources());
[email protected]a37d4b02012-06-25 21:56:10318 chrome::NewTab(browser());
[email protected]15877ca2011-11-18 22:40:52319 tab_added_observer.Wait();
320 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
321 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02322 browser()->tab_strip_model()->GetWebContentsAt(2)->
323 GetRenderProcessHost()->GetID()));
324 EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
[email protected]15877ca2011-11-18 22:40:52325
326 // We should have opened 2 new bookmark app tabs. Including the original blank
327 // tab, we now have 3 tabs. Because normal pages use the
328 // process-per-site-instance model, each should be in its own process.
[email protected]e0448872013-01-11 19:35:02329 ASSERT_EQ(3, browser()->tab_strip_model()->count());
330 WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
[email protected]19da16a92012-05-23 17:11:29331 EXPECT_NE(tab->GetRenderProcessHost(),
[email protected]e0448872013-01-11 19:35:02332 browser()->tab_strip_model()->GetWebContentsAt(2)->
333 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52334
335 // Now let's do the same using window.open. The same should happen.
[email protected]c987a242013-02-28 01:17:41336 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
337 browser()->host_desktop_type()));
[email protected]19da16a92012-05-23 17:11:29338 OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
339 OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
[email protected]15877ca2011-11-18 22:40:52340
341 // Now let's have a tab navigate out of and back into the app's web
342 // extent. Neither navigation should switch processes.
343 const GURL& app_url(base_url.Resolve("path1/empty.html"));
344 const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
[email protected]52877dbc62012-06-29 22:22:03345 RenderViewHost* host2 =
[email protected]e0448872013-01-11 19:35:02346 browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
347 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
348 non_app_url);
[email protected]9f76c1e2012-03-05 15:15:58349 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02350 browser()->tab_strip_model()->GetWebContentsAt(2)->
351 GetRenderProcessHost());
352 NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
353 app_url);
[email protected]9f76c1e2012-03-05 15:15:58354 EXPECT_EQ(host2->GetProcess(),
[email protected]e0448872013-01-11 19:35:02355 browser()->tab_strip_model()->GetWebContentsAt(2)->
356 GetRenderProcessHost());
[email protected]15877ca2011-11-18 22:40:52357}
358
[email protected]faf407b2011-01-05 01:24:32359// Tests that app process switching works properly in the following scenario:
360// 1. navigate to a page1 in the app
361// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
362// 3. page2 redirects back to a page in the app
363// The final navigation should end up in the app process.
364// See http://crbug.com/61757
[email protected]ea7b7d82012-05-25 17:29:17365IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessRedirectBack) {
[email protected]faf407b2011-01-05 01:24:32366 host_resolver()->AddRule("*", "127.0.0.1");
367 ASSERT_TRUE(test_server()->Start());
368
369 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
370
371 // Open two tabs in the app.
[email protected]118d3122011-08-10 17:09:53372 GURL base_url = GetTestBaseURL("app_process");
[email protected]faf407b2011-01-05 01:24:32373
[email protected]a37d4b02012-06-25 21:56:10374 chrome::NewTab(browser());
[email protected]faf407b2011-01-05 01:24:32375 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]a37d4b02012-06-25 21:56:10376 chrome::NewTab(browser());
[email protected]ea7b7d82012-05-25 17:29:17377 // Wait until the second tab finishes its redirect train (2 hops).
[email protected]4ad5d77d2011-12-03 02:00:48378 // 1. We navigate to redirect.html
379 // 2. Renderer navigates and finishes, counting as a load stop.
380 // 3. Renderer issues the meta refresh to navigate to server-redirect.
381 // 4. Renderer is now in a "provisional load", waiting for navigation to
382 // complete.
383 // 5. Browser sees a redirect response from server-redirect to empty.html, and
384 // transfers that to a new navigation, using RequestTransferURL.
[email protected]ea7b7d82012-05-25 17:29:17385 // 6. Renderer navigates to empty.html, and finishes loading, counting as the
386 // second load stop
[email protected]4ad5d77d2011-12-03 02:00:48387 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
[email protected]ea7b7d82012-05-25 17:29:17388 browser(), base_url.Resolve("path1/redirect.html"), 2);
[email protected]faf407b2011-01-05 01:24:32389
390 // 3 tabs, including the initial about:blank. The last 2 should be the same
391 // process.
[email protected]e0448872013-01-11 19:35:02392 ASSERT_EQ(3, browser()->tab_strip_model()->count());
[email protected]089e8c332011-01-06 21:37:29393 EXPECT_EQ("/files/extensions/api_test/app_process/path1/empty.html",
[email protected]e0448872013-01-11 19:35:02394 browser()->tab_strip_model()->GetWebContentsAt(2)->
395 GetController().GetLastCommittedEntry()->GetURL().path());
396 EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
397 GetRenderProcessHost(),
398 browser()->tab_strip_model()->GetWebContentsAt(2)->
399 GetRenderProcessHost());
[email protected]faf407b2011-01-05 01:24:32400}
[email protected]d292d8a2011-05-25 03:47:11401
[email protected]aaef4752013-03-02 10:10:51402// Ensure that re-navigating to a URL after installing or uninstalling it as an
403// app correctly swaps the tab to the app process. (http://crbug.com/80621)
404IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
[email protected]06bdd2b2012-11-30 18:47:13405 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
406 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52407
[email protected]d292d8a2011-05-25 03:47:11408 host_resolver()->AddRule("*", "127.0.0.1");
409 ASSERT_TRUE(test_server()->Start());
410
411 // The app under test acts on URLs whose host is "localhost",
412 // so the URLs we navigate to must have host "localhost".
[email protected]118d3122011-08-10 17:09:53413 GURL base_url = GetTestBaseURL("app_process");
[email protected]d292d8a2011-05-25 03:47:11414
415 // Load an app URL before loading the app.
416 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02417 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46418 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52419 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11420
[email protected]aaef4752013-03-02 10:10:51421 // Load app and re-navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11422 const Extension* app =
423 LoadExtension(test_data_dir_.AppendASCII("app_process"));
424 ASSERT_TRUE(app);
425 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]6f371442011-11-09 06:45:46426 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52427 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11428
[email protected]aaef4752013-03-02 10:10:51429 // Disable app and re-navigate to the page.
[email protected]d292d8a2011-05-25 03:47:11430 DisableExtension(app->id());
431 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]6f371442011-11-09 06:45:46432 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52433 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51434}
435
436// Ensure that reloading a URL after installing or uninstalling it as an app
437// correctly swaps the tab to the app process. (http://crbug.com/80621)
438IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
439 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
440 browser()->profile())->extension_service()->process_map();
441
442 host_resolver()->AddRule("*", "127.0.0.1");
443 ASSERT_TRUE(test_server()->Start());
444
445 // The app under test acts on URLs whose host is "localhost",
446 // so the URLs we navigate to must have host "localhost".
447 GURL base_url = GetTestBaseURL("app_process");
448
449 // Load app, disable it, and navigate to the page.
450 const Extension* app =
451 LoadExtension(test_data_dir_.AppendASCII("app_process"));
452 ASSERT_TRUE(app);
453 DisableExtension(app->id());
454 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
455 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
456 EXPECT_FALSE(process_map->Contains(
457 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11458
[email protected]8d3132f62011-10-12 07:13:42459 // Enable app and reload the page.
460 EnableExtension(app->id());
[email protected]a7fe9112012-07-20 02:34:45461 content::WindowedNotificationObserver reload_observer(
[email protected]8d3132f62011-10-12 07:13:42462 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50463 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02464 &browser()->tab_strip_model()->GetActiveWebContents()->
465 GetController()));
[email protected]a37d4b02012-06-25 21:56:10466 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42467 reload_observer.Wait();
[email protected]6f371442011-11-09 06:45:46468 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52469 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42470
471 // Disable app and reload the page.
472 DisableExtension(app->id());
[email protected]a7fe9112012-07-20 02:34:45473 content::WindowedNotificationObserver reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42474 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50475 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02476 &browser()->tab_strip_model()->GetActiveWebContents()->
477 GetController()));
[email protected]a37d4b02012-06-25 21:56:10478 chrome::Reload(browser(), CURRENT_TAB);
[email protected]8d3132f62011-10-12 07:13:42479 reload_observer2.Wait();
[email protected]6f371442011-11-09 06:45:46480 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52481 contents->GetRenderProcessHost()->GetID()));
[email protected]aaef4752013-03-02 10:10:51482}
483
484// Ensure that reloading a URL with JavaScript after installing or uninstalling
485// it as an app correctly swaps the process. (http://crbug.com/80621)
486IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
487 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
488 browser()->profile())->extension_service()->process_map();
489
490 host_resolver()->AddRule("*", "127.0.0.1");
491 ASSERT_TRUE(test_server()->Start());
492
493 // The app under test acts on URLs whose host is "localhost",
494 // so the URLs we navigate to must have host "localhost".
495 GURL base_url = GetTestBaseURL("app_process");
496
497 // Load app, disable it, and navigate to the page.
498 const Extension* app =
499 LoadExtension(test_data_dir_.AppendASCII("app_process"));
500 ASSERT_TRUE(app);
501 DisableExtension(app->id());
502 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
503 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
504 EXPECT_FALSE(process_map->Contains(
505 contents->GetRenderProcessHost()->GetID()));
[email protected]8d3132f62011-10-12 07:13:42506
[email protected]d292d8a2011-05-25 03:47:11507 // Enable app and reload via JavaScript.
508 EnableExtension(app->id());
[email protected]a7fe9112012-07-20 02:34:45509 content::WindowedNotificationObserver js_reload_observer(
[email protected]8d3132f62011-10-12 07:13:42510 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50511 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02512 &browser()->tab_strip_model()->GetActiveWebContents()->
513 GetController()));
[email protected]b6987e02013-01-04 18:30:43514 ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
[email protected]8d3132f62011-10-12 07:13:42515 js_reload_observer.Wait();
[email protected]6f371442011-11-09 06:45:46516 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52517 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11518
519 // Disable app and reload via JavaScript.
520 DisableExtension(app->id());
[email protected]a7fe9112012-07-20 02:34:45521 content::WindowedNotificationObserver js_reload_observer2(
[email protected]8d3132f62011-10-12 07:13:42522 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50523 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02524 &browser()->tab_strip_model()->GetActiveWebContents()->
525 GetController()));
[email protected]b6987e02013-01-04 18:30:43526 ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
[email protected]8d3132f62011-10-12 07:13:42527 js_reload_observer2.Wait();
[email protected]6f371442011-11-09 06:45:46528 EXPECT_FALSE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52529 contents->GetRenderProcessHost()->GetID()));
[email protected]d292d8a2011-05-25 03:47:11530}
[email protected]118d3122011-08-10 17:09:53531
[email protected]eab29432013-04-09 21:30:47532namespace {
533
534void RenderViewHostCreated(std::vector<content::RenderViewHost*>* rvh_vector,
535 content::RenderViewHost* rvh) {
536 rvh_vector->push_back(rvh);
537}
538
539} // namespace
540
[email protected]118d3122011-08-10 17:09:53541// Tests that if we have a non-app process (path3/container.html) that has an
542// iframe with a URL in the app's extent (path1/iframe.html), then opening a
543// link from that iframe to a new window to a URL in the app's extent (path1/
544// empty.html) results in the new window being in an app process. See
545// http://crbug.com/89272 for more details.
[email protected]1f4495b2012-10-12 05:51:05546IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
[email protected]06bdd2b2012-11-30 18:47:13547 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
548 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52549
[email protected]118d3122011-08-10 17:09:53550 host_resolver()->AddRule("*", "127.0.0.1");
551 ASSERT_TRUE(test_server()->Start());
552
553 GURL base_url = GetTestBaseURL("app_process");
554
555 // Load app and start URL (not in the app).
556 const Extension* app =
557 LoadExtension(test_data_dir_.AppendASCII("app_process"));
558 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29559
[email protected]eab29432013-04-09 21:30:47560 std::vector<content::RenderViewHost*> rvh_vector;
561 content::RenderViewHost::CreatedCallback rvh_callback(
562 base::Bind(&RenderViewHostCreated, &rvh_vector));
563 content::RenderViewHost::AddCreatedCallback(rvh_callback);
[email protected]19da16a92012-05-23 17:11:29564 ui_test_utils::NavigateToURL(browser(),
565 base_url.Resolve("path3/container.html"));
[email protected]eab29432013-04-09 21:30:47566 content::RenderViewHost::RemoveCreatedCallback(rvh_callback);
[email protected]6f371442011-11-09 06:45:46567 EXPECT_FALSE(process_map->Contains(
[email protected]e0448872013-01-11 19:35:02568 browser()->tab_strip_model()->GetWebContentsAt(0)->
569 GetRenderProcessHost()->GetID()));
[email protected]118d3122011-08-10 17:09:53570
571 // Popup window should be in the app's process.
[email protected]eab29432013-04-09 21:30:47572 ASSERT_EQ(3U, rvh_vector.size());
573 RenderViewHost* popup_host = rvh_vector[2];
[email protected]19da16a92012-05-23 17:11:29574 EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
[email protected]118d3122011-08-10 17:09:53575}
[email protected]a09add52011-08-12 03:59:23576
[email protected]079b3cc2012-09-26 19:59:13577// Similar to the previous test, but ensure that popup blocking bypass
578// isn't granted to the iframe. See crbug.com/117446.
[email protected]1f4495b2012-10-12 05:51:05579#if defined(OS_CHROMEOS)
580// http://crbug.com/153513
581#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
582#else
583#define MAYBE_OpenAppFromIframe OpenAppFromIframe
584#endif
585IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
[email protected]079b3cc2012-09-26 19:59:13586 host_resolver()->AddRule("*", "127.0.0.1");
587 ASSERT_TRUE(test_server()->Start());
588
589 // Load app and start URL (not in the app).
590 const Extension* app =
591 LoadExtension(test_data_dir_.AppendASCII("app_process"));
592 ASSERT_TRUE(app);
593
594 content::WindowedNotificationObserver blocker_observer(
595 chrome::NOTIFICATION_CONTENT_BLOCKED_STATE_CHANGED,
596 content::NotificationService::AllSources());
597 ui_test_utils::NavigateToURL(
598 browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
599
600 blocker_observer.Wait();
601
[email protected]e0448872013-01-11 19:35:02602 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
[email protected]079b3cc2012-09-26 19:59:13603 BlockedContentTabHelper* blocked_content_tab_helper =
604 BlockedContentTabHelper::FromWebContents(tab);
605 std::vector<WebContents*> blocked_contents;
606 blocked_content_tab_helper->GetBlockedContents(&blocked_contents);
607 EXPECT_EQ(blocked_contents.size(), 1u);
608}
609
[email protected]88aae972011-12-16 01:14:18610// Tests that if an extension launches an app via chrome.tabs.create with an URL
611// that's not in the app's extent but that redirects to it, we still end up with
612// an app process. See http://crbug.com/99349 for more details.
613IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromExtension) {
614 host_resolver()->AddRule("*", "127.0.0.1");
615 ASSERT_TRUE(StartTestServer());
616
617 LoadExtension(test_data_dir_.AppendASCII("app_process"));
618 const Extension* launcher =
619 LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
620
621 // There should be three navigations by the time the app page is loaded.
622 // 1. The extension launcher page.
623 // 2. The URL that the extension launches, which redirects.
624 // 3. The app's URL.
[email protected]5b8ff1c2012-06-02 20:42:20625 content::TestNavigationObserver test_navigation_observer(
626 content::NotificationService::AllSources(),
[email protected]5b8ff1c2012-06-02 20:42:20627 3);
[email protected]88aae972011-12-16 01:14:18628
629 // Load the launcher extension, which should launch the app.
630 ui_test_utils::NavigateToURLWithDisposition(
631 browser(),
632 launcher->GetResourceURL("main.html"),
633 CURRENT_TAB,
634 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
635
636 // Wait for app tab to be created and loaded.
637 test_navigation_observer.WaitForObservation(
[email protected]729eb632012-07-26 04:45:26638 base::Bind(&content::RunMessageLoop),
[email protected]88aae972011-12-16 01:14:18639 base::Bind(&MessageLoop::Quit,
640 base::Unretained(MessageLoopForUI::current())));
641
642 // App has loaded, and chrome.app.isInstalled should be true.
643 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43644 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
[email protected]e0448872013-01-11 19:35:02645 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13646 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]88aae972011-12-16 01:14:18647 &is_installed));
648 ASSERT_TRUE(is_installed);
649}
650
[email protected]d55c2382011-08-18 23:10:36651// Tests that if we have an app process (path1/container.html) with a non-app
652// iframe (path3/iframe.html), then opening a link from that iframe to a new
653// window to a same-origin non-app URL (path3/empty.html) should keep the window
654// in the app process.
655// This is in contrast to OpenAppFromIframe, since here the popup will not be
656// missing special permissions and should be scriptable from the iframe.
657// See http://crbug.com/92669 for more details.
[email protected]19da16a92012-05-23 17:11:29658IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
[email protected]06bdd2b2012-11-30 18:47:13659 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
660 browser()->profile())->extension_service()->process_map();
[email protected]718eab62011-10-05 21:16:52661
[email protected]d55c2382011-08-18 23:10:36662 host_resolver()->AddRule("*", "127.0.0.1");
663 ASSERT_TRUE(test_server()->Start());
664
665 GURL base_url = GetTestBaseURL("app_process");
666
667 // Load app and start URL (in the app).
668 const Extension* app =
669 LoadExtension(test_data_dir_.AppendASCII("app_process"));
670 ASSERT_TRUE(app);
[email protected]19da16a92012-05-23 17:11:29671
[email protected]eab29432013-04-09 21:30:47672 std::vector<content::RenderViewHost*> rvh_vector;
673 content::RenderViewHost::CreatedCallback rvh_callback(
674 base::Bind(&RenderViewHostCreated, &rvh_vector));
675 content::RenderViewHost::AddCreatedCallback(rvh_callback);
[email protected]19da16a92012-05-23 17:11:29676 ui_test_utils::NavigateToURL(browser(),
677 base_url.Resolve("path1/container.html"));
[email protected]eab29432013-04-09 21:30:47678 content::RenderViewHost::RemoveCreatedCallback(rvh_callback);
[email protected]f3b1a082011-11-18 00:34:30679 content::RenderProcessHost* process =
[email protected]e0448872013-01-11 19:35:02680 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
[email protected]f3b1a082011-11-18 00:34:30681 EXPECT_TRUE(process_map->Contains(process->GetID()));
[email protected]d55c2382011-08-18 23:10:36682
[email protected]d55c2382011-08-18 23:10:36683 // Popup window should be in the app's process.
[email protected]eab29432013-04-09 21:30:47684 ASSERT_EQ(2U, rvh_vector.size());
685 RenderViewHost* popup_host = rvh_vector[1];
[email protected]19da16a92012-05-23 17:11:29686 EXPECT_EQ(process, popup_host->GetProcess());
[email protected]d55c2382011-08-18 23:10:36687}
688
[email protected]a344b762012-03-16 18:53:49689// http://crbug.com/118502
690#if defined(OS_MACOSX) || defined(OS_LINUX)
691#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
692#else
693#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
694#endif
695IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
[email protected]06bdd2b2012-11-30 18:47:13696 extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
697 browser()->profile())->extension_service()->process_map();
[email protected]6f371442011-11-09 06:45:46698
[email protected]a09add52011-08-12 03:59:23699 host_resolver()->AddRule("*", "127.0.0.1");
700 ASSERT_TRUE(test_server()->Start());
701
702 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
703
704 GURL base_url = GetTestBaseURL("app_process");
705
706 // Load the app, chrome.app.isInstalled should be true.
707 ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
[email protected]e0448872013-01-11 19:35:02708 WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
[email protected]6f371442011-11-09 06:45:46709 EXPECT_TRUE(process_map->Contains(
[email protected]151a63d2011-12-20 22:32:52710 contents->GetRenderProcessHost()->GetID()));
[email protected]a09add52011-08-12 03:59:23711 bool is_installed = false;
[email protected]b6987e02013-01-04 18:30:43712 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
713 contents,
[email protected]06bc5d92013-01-02 22:44:13714 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23715 &is_installed));
716 ASSERT_TRUE(is_installed);
717
718 // Crash the tab and reload it, chrome.app.isInstalled should still be true.
[email protected]e0448872013-01-11 19:35:02719 content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
[email protected]a7fe9112012-07-20 02:34:45720 content::WindowedNotificationObserver observer(
[email protected]ae673742011-08-24 19:48:37721 content::NOTIFICATION_LOAD_STOP,
[email protected]c5eed492012-01-04 17:07:50722 content::Source<NavigationController>(
[email protected]e0448872013-01-11 19:35:02723 &browser()->tab_strip_model()->GetActiveWebContents()->
724 GetController()));
[email protected]a37d4b02012-06-25 21:56:10725 chrome::Reload(browser(), CURRENT_TAB);
[email protected]ae673742011-08-24 19:48:37726 observer.Wait();
[email protected]b6987e02013-01-04 18:30:43727 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
728 contents,
[email protected]06bc5d92013-01-02 22:44:13729 "window.domAutomationController.send(chrome.app.isInstalled)",
[email protected]a09add52011-08-12 03:59:23730 &is_installed));
731 ASSERT_TRUE(is_installed);
732}