15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/command_line.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
1058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/test/base/test_switches.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/site_instance.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_navigation_observer.h"
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_host.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/browser/install_flag.h"
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_map.h"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/file_util.h"
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/switches.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/test/embedded_test_server/embedded_test_server.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/string_ordinal.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::SiteInstance;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppApiTest : public ExtensionApiTest {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the base URL for files for a specific test, making sure that it uses
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "localhost" as the hostname, since that is what the extent is declared
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as in the test apps manifests.
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  GURL GetTestBaseURL(const std::string& test_directory) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL::Replacements replace_host;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string host_str("localhost");  // must stay in scope with replace_host
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replace_host.SetHostStr(host_str);
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GURL base_url = embedded_test_server()->GetURL(
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "/extensions/api_test/" + test_directory + "/");
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base_url.ReplaceComponents(replace_host);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pass flags to make testing apps easier.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionApiTest::SetUpCommandLine(command_line);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kDisablePopupBlocking);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        extensions::switches::kAllowHTTPBackgroundPage);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function to test that independent tabs of the named app are loaded
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into separate processes.
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void TestAppInstancesHelper(const std::string& app_name) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "Start of test.";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensions::ProcessMap* process_map =
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        extensions::ProcessMap::Get(browser()->profile());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver()->AddRule("*", "127.0.0.1");
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(LoadExtension(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_data_dir_.AppendASCII(app_name)));
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension = GetSingleLoadedExtension();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Open two tabs in the app, one outside it.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL base_url = GetTestBaseURL(app_name);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test both opening a URL in a new tab, and opening a tab and then
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // navigating it.  Either way, app tabs should be considered extension
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // processes, but they have no elevated privileges and thus should not
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // have WebUI bindings.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_test_utils::NavigateToURLWithDisposition(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "Nav 1.";
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(process_map->Contains(
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser()->tab_strip_model()->GetWebContentsAt(1)->
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetRenderProcessHost()->GetID()));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WindowedNotificationObserver tab_added_observer(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_TAB_ADDED,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::AllSources());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::NewTab(browser());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_added_observer.Wait();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "New tab.";
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_test_utils::NavigateToURL(browser(),
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base_url.Resolve("path2/empty.html"));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "Nav 2.";
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(process_map->Contains(
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser()->tab_strip_model()->GetWebContentsAt(2)->
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetRenderProcessHost()->GetID()));
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We should have opened 2 new extension tabs. Including the original blank
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tab, we now have 3 tabs. The two app tabs should not be in the same
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // process, since they do not have the background permission.  (Thus, we
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // want to separate them to improve responsiveness.)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(3, browser()->tab_strip_model()->count());
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Opening tabs with window.open should keep the page in the opener's
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // process.
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          browser()->host_desktop_type()));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "WindowOpenHelper 1.";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "End of test.";
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UnloadExtension(extension->id());
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Omits the disable-popup-blocking flag so we can cover that case.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BlockedAppApiTest : public AppApiTest {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionApiTest::SetUpCommandLine(command_line);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        extensions::switches::kAllowHTTPBackgroundPage);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that hosted apps with the background permission get a process-per-app
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// model, since all pages need to be able to script the background page.
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://crbug.com/172750
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcess) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Start of test.";
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Loaded extension.";
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open two tabs in the app, one outside it.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test both opening a URL in a new tab, and opening a tab and then navigating
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it.  Either way, app tabs should be considered extension processes, but
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // they have no elevated privileges and thus should not have WebUI bindings.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(1)->
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Nav 1.";
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(2)->
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Nav 2.";
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver tab_added_observer(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_ADDED,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_added_observer.Wait();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "New tab.";
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Nav 3.";
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(3)->
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have opened 3 new extension tabs. Including the original blank
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab, we now have 4 tabs. Because the app_process app has the background
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // permission, all of its instances are in the same process.  Thus two tabs
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be part of the extension app and grouped in the same process.
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(4, browser()->tab_strip_model()->count());
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tab->GetRenderProcessHost(),
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(tab->GetRenderProcessHost(),
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(3)->
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's do the same using window.open. The same should happen.
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        browser()->host_desktop_type()));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "WindowOpenHelper 1.";
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "WindowOpenHelper 2.";
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(creis): This should open in a new process (i.e., false for the last
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument), but we temporarily avoid swapping processes away from a hosted
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // app if it has an opener, because some OAuth providers make script calls
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // between non-app popups and non-app iframes in the app process.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See crbug.com/59285.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "WindowOpenHelper 3.";
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's have these pages navigate, into or out of the extension web
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extent. They should switch processes.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& app_url(base_url.Resolve("path1/empty.html"));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     non_app_url);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "NavigateTabHelper 1.";
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     app_url);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "NavigateTabHelper 2.";
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(tab->GetRenderProcessHost(),
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tab->GetRenderProcessHost(),
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(3)->
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If one of the popup tabs navigates back to the app, window.opener should
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid.
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     app_url);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "NavigateTabHelper 3.";
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tab->GetRenderProcessHost(),
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(6)->
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool windowOpenerValid = false;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(6),
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(window.opener != null)",
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &windowOpenerValid));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(windowOpenerValid);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "End of test.";
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that hosted apps without the background permission use a process per app
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instance model, such that separate instances are in separate processes.
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Flaky on Windows. http://crbug.com/248047
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN)
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_AppProcessInstances DISABLED_AppProcessInstances
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_AppProcessInstances AppProcessInstances
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessInstances) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAppInstancesHelper("app_process_instances");
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that hosted apps with the background permission but that set
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// allow_js_access to false also use a process per app instance model.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Separate instances should be in separate processes.
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Flaky on XP: http://crbug.com/165834
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AppProcessBackgroundInstances \
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISABLED_AppProcessBackgroundInstances
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAppInstancesHelper("app_process_background_instances");
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that bookmark apps do not use the app process model and are treated
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// like normal web pages instead.  http://crbug.com/104636.
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Timing out on Windows. http://crbug.com/238777
290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(OS_WIN)
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#define MAYBE_BookmarkAppGetsNormalProcess DISABLED_BookmarkAppGetsNormalProcess
292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else
293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#define MAYBE_BookmarkAppGetsNormalProcess BookmarkAppGetsNormalProcess
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_BookmarkAppGetsNormalProcess) {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service();
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an app as a bookmark app.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
307a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<const Extension> extension(extensions::file_util::LoadExtension(
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_data_dir_.AppendASCII("app_process"),
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::Manifest::UNPACKED,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Extension::FROM_BOOKMARK,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &error));
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service->OnExtensionInstalled(extension.get(),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                syncer::StringOrdinal::CreateInitialOrdinal(),
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                extensions::kInstallFlagInstallImmediately);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(extension.get());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(extension->from_bookmark());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test both opening a URL in a new tab, and opening a tab and then navigating
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it.  Either way, bookmark app tabs should be considered normal processes
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with no elevated privileges and no WebUI bindings.
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(1)->
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver tab_added_observer(
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_ADDED,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_added_observer.Wait();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(2)->
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have opened 2 new bookmark app tabs. Including the original blank
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab, we now have 3 tabs.  Because normal pages use the
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process-per-site-instance model, each should be in its own process.
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, browser()->tab_strip_model()->count());
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(tab->GetRenderProcessHost(),
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's do the same using window.open. The same should happen.
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        browser()->host_desktop_type()));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's have a tab navigate out of and back into the app's web
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extent. Neither navigation should switch processes.
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& app_url(base_url.Resolve("path1/empty.html"));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* host2 =
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     non_app_url);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(host2->GetProcess(),
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     app_url);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(host2->GetProcess(),
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that app process switching works properly in the following scenario:
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. navigate to a page1 in the app
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. page2 redirects back to a page in the app
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The final navigation should end up in the app process.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/61757
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Flaky.  http://crbug.com/341898
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(AppApiTest, DISABLED_AppProcessRedirectBack) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open two tabs in the app.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until the second tab finishes its redirect train (2 hops).
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. We navigate to redirect.html
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. Renderer navigates and finishes, counting as a load stop.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. Renderer issues the meta refresh to navigate to server-redirect.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4. Renderer is now in a "provisional load", waiting for navigation to
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    complete.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 5. Browser sees a redirect response from server-redirect to empty.html, and
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    transfers that to a new navigation, using RequestTransferURL.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6. Renderer navigates to empty.html, and finishes loading, counting as the
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    second load stop
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/redirect.html"), 2);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3 tabs, including the initial about:blank. The last 2 should be the same
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process.
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, browser()->tab_strip_model()->count());
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetController().GetLastCommittedEntry()->GetURL().path());
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost(),
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that re-navigating to a URL after installing or uninstalling it as an
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// app correctly swaps the tab to the app process.  (http://crbug.com/80621)
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Fails on Windows. http://crbug.com/238670
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Added logging to help diagnose the location of the problem.
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an app URL before loading the app.
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html.";
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html - done.";
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app and re-navigate to the page.
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension.";
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension - done.";
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html.";
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html - done.";
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Disable app and re-navigate to the page.
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisableExtension(app->id());
45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html.";
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html - done.";
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that reloading a URL after installing or uninstalling it as an app
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// correctly swaps the tab to the app process.  (http://crbug.com/80621)
46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Added logging to help diagnose the location of the problem.
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// http://crbug.com/238670
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app, disable it, and navigate to the page.
48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension.";
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* app =
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension - done.";
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(app);
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html.";
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html - done.";
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable app and reload the page.
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension.";
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableExtension(app->id());
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension - done.";
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver reload_observer(
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading.";
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_observer.Wait();
50890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading - done.";
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable app and reload the page.
51390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver reload_observer2(
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
52190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading.";
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_observer2.Wait();
52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading - done.";
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that reloading a URL with JavaScript after installing or uninstalling
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it as an app correctly swaps the process.  (http://crbug.com/80621)
53190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
53290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Crashes on Windows and Mac. http://crbug.com/238670
53390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Added logging to help diagnose the location of the problem.
53490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app, disable it, and navigate to the page.
54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension.";
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* app =
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension - done.";
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(app);
55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisableExtension(app->id());
55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
55490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html.";
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html - done.";
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable app and reload via JavaScript.
56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension.";
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableExtension(app->id());
56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension - done.";
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver js_reload_observer(
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location.reload().";
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_reload_observer.Wait();
57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location.reload() - done.";
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable app and reload via JavaScript.
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver js_reload_observer2(
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location = location.";
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_reload_observer2.Wait();
58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location = location - done.";
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if we have a non-app process (path3/container.html) that has an
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iframe with  a URL in the app's extent (path1/iframe.html), then opening a
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// link from that iframe to a new window to a URL in the app's extent (path1/
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// empty.html) results in the new window being in an app process. See
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/89272 for more details.
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
600ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
603ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
604ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
605ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (not in the app).
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base_url.Resolve("path3/container.html"));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const BrowserList* active_browser_list =
6261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      BrowserList::GetInstance(chrome::GetActiveDesktop());
6271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2U, active_browser_list->size());
6281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WebContents* popup_contents =
6291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
6301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WaitForLoadStop(popup_contents);
6311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Popup window should be in the app's process.
6331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to the previous test, but ensure that popup blocking bypass
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isn't granted to the iframe.  See crbug.com/117446.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/153513
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_OpenAppFromIframe OpenAppFromIframe
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (not in the app).
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
65858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  PopupBlockerTabHelper* popup_blocker_tab_helper =
65958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      PopupBlockerTabHelper::FromWebContents(tab);
6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!popup_blocker_tab_helper->GetBlockedPopupsCount()) {
66158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    content::WindowedNotificationObserver observer(
66258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
66358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        content::NotificationService::AllSources());
66458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    observer.Wait();
66558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
66658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
6673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if an extension launches an app via chrome.tabs.create with an URL
671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// that's not in the app's extent but that server redirects to it, we still end
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// up with an app process. See http://crbug.com/99349 for more details.
673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(StartEmbeddedTestServer());
676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LoadExtension(test_data_dir_.AppendASCII("app_process"));
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const Extension* launcher =
679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // There should be two navigations by the time the app page is loaded.
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 1. The extension launcher page.
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 2. The app's URL (which includes a server redirect).
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Note that the server redirect does not generate a navigation event.
685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestNavigationObserver test_navigation_observer(
686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      2);
688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test_navigation_observer.StartWatchingNewWebContents();
689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Load the launcher extension, which should launch the app.
691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser(),
693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      launcher->GetResourceURL("server_redirect.html"),
694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CURRENT_TAB,
695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Wait for app tab to be created and loaded.
6984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  test_navigation_observer.Wait();
699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // App has loaded, and chrome.app.isInstalled should be true.
701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool is_installed = false;
702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      &is_installed));
706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(is_installed);
707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests that if an extension launches an app via chrome.tabs.create with an URL
710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// that's not in the app's extent but that client redirects to it, we still end
711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// up with an app process.
712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(StartEmbeddedTestServer());
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadExtension(test_data_dir_.AppendASCII("app_process"));
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* launcher =
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be three navigations by the time the app page is loaded.
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. The extension launcher page.
722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 2. The URL that the extension launches, which client redirects.
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. The app's URL.
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestNavigationObserver test_navigation_observer(
725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      3);
727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test_navigation_observer.StartWatchingNewWebContents();
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the launcher extension, which should launch the app.
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      launcher->GetResourceURL("client_redirect.html"),
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CURRENT_TAB,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for app tab to be created and loaded.
7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  test_navigation_observer.Wait();
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // App has loaded, and chrome.app.isInstalled should be true.
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_installed = false;
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if we have an app process (path1/container.html) with a non-app
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iframe (path3/iframe.html), then opening a link from that iframe to a new
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window to a same-origin non-app URL (path3/empty.html) should keep the window
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the app process.
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is in contrast to OpenAppFromIframe, since here the popup will not be
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// missing special permissions and should be scriptable from the iframe.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/92669 for more details.
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (in the app).
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base_url.Resolve("path1/container.html"));
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderProcessHost* process =
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(process->GetID()));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Popup window should be in the app's process.
7761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const BrowserList* active_browser_list =
7771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      BrowserList::GetInstance(chrome::GetActiveDesktop());
7781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2U, active_browser_list->size());
7791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WebContents* popup_contents =
7801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
7811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WaitForLoadStop(popup_contents);
7821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(process, popup_host->GetProcess());
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/118502
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) || defined(OS_LINUX)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the app, chrome.app.isInstalled should be true.
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_installed = false;
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents,
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Crash the tab and reload it, chrome.app.isInstalled should still be true.
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver observer(
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.Wait();
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents,
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that a cross-process navigation away from a hosted app stays in the same
833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// BrowsingInstance, so that postMessage calls to the app's other windows still
834a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// work.
835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, SameBrowsingInstanceAfterSwap) {
8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
842a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Load app and start URL (in the app).
845a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const Extension* app =
846a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(app);
848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               base_url.Resolve("path1/iframe.html"));
851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::SiteInstance* app_instance =
852a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->GetSiteInstance();
853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(app_instance->GetProcess()->GetID()));
854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Popup window should be in the app's process.
856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const BrowserList* active_browser_list =
857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      BrowserList::GetInstance(chrome::GetActiveDesktop());
858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(2U, active_browser_list->size());
859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::WebContents* popup_contents =
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::WaitForLoadStop(popup_contents);
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SiteInstance* popup_instance = popup_contents->GetSiteInstance();
864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(app_instance, popup_instance);
865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Navigate the popup to another process outside the app.
867a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GURL non_app_url(base_url.Resolve("path3/empty.html"));
868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_test_utils::NavigateToURL(active_browser_list->get(1), non_app_url);
869a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SiteInstance* new_instance = popup_contents->GetSiteInstance();
870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(app_instance, new_instance);
871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // It should still be in the same BrowsingInstance, allowing postMessage to
873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // work.
874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(app_instance->IsRelatedSiteInstance(new_instance));
875a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
876