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
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Flaky on Linux.  http://crbug.com/341898
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MAYBE_AppProcessRedirectBack DISABLED_AppProcessRedirectBack
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MAYBE_AppProcessRedirectBack AppProcessRedirectBack
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessRedirectBack) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open two tabs in the app.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until the second tab finishes its redirect train (2 hops).
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. We navigate to redirect.html
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. Renderer navigates and finishes, counting as a load stop.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. Renderer issues the meta refresh to navigate to server-redirect.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4. Renderer is now in a "provisional load", waiting for navigation to
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    complete.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 5. Browser sees a redirect response from server-redirect to empty.html, and
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    transfers that to a new navigation, using RequestTransferURL.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6. Renderer navigates to empty.html, and finishes loading, counting as the
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    second load stop
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/redirect.html"), 2);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3 tabs, including the initial about:blank. The last 2 should be the same
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process.
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, browser()->tab_strip_model()->count());
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("/extensions/api_test/app_process/path1/empty.html",
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetController().GetLastCommittedEntry()->GetURL().path());
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost(),
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that re-navigating to a URL after installing or uninstalling it as an
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// app correctly swaps the tab to the app process.  (http://crbug.com/80621)
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Fails on Windows. http://crbug.com/238670
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Added logging to help diagnose the location of the problem.
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an app URL before loading the app.
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html.";
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html - done.";
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app and re-navigate to the page.
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension.";
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension - done.";
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html.";
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html - done.";
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Disable app and re-navigate to the page.
45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisableExtension(app->id());
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html.";
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading path1/empty.html - done.";
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that reloading a URL after installing or uninstalling it as an app
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// correctly swaps the tab to the app process.  (http://crbug.com/80621)
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Added logging to help diagnose the location of the problem.
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// http://crbug.com/238670
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app, disable it, and navigate to the page.
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension.";
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* app =
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension - done.";
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(app);
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html.";
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html - done.";
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable app and reload the page.
50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension.";
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableExtension(app->id());
50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension - done.";
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver reload_observer(
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
51090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading.";
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_observer.Wait();
51390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading - done.";
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable app and reload the page.
51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver reload_observer2(
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
52690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading.";
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_observer2.Wait();
52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Reloading - done.";
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that reloading a URL with JavaScript after installing or uninstalling
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it as an app correctly swaps the process.  (http://crbug.com/80621)
53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)//
53790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Crashes on Windows and Mac. http://crbug.com/238670
53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Added logging to help diagnose the location of the problem.
53990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app, disable it, and navigate to the page.
55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension.";
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* app =
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
55490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Loading extension - done.";
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(app);
55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisableExtension(app->id());
55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
55990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html.";
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Navigate to path1/empty.html - done.";
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable app and reload via JavaScript.
56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension.";
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableExtension(app->id());
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Enabling extension - done.";
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver js_reload_observer(
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
57590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location.reload().";
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_reload_observer.Wait();
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location.reload() - done.";
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable app and reload via JavaScript.
58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension.";
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Disabling extension - done.";
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver js_reload_observer2(
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location = location.";
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_reload_observer2.Wait();
59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LOG(INFO) << "Executing location = location - done.";
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if we have a non-app process (path3/container.html) that has an
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iframe with  a URL in the app's extent (path1/iframe.html), then opening a
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// link from that iframe to a new window to a URL in the app's extent (path1/
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// empty.html) results in the new window being in an app process. See
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/89272 for more details.
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
605ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
606ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
608ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
609ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
610ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (not in the app).
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base_url.Resolve("path3/container.html"));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const BrowserList* active_browser_list =
6311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      BrowserList::GetInstance(chrome::GetActiveDesktop());
6321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2U, active_browser_list->size());
6331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WebContents* popup_contents =
6341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
6351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WaitForLoadStop(popup_contents);
6361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Popup window should be in the app's process.
6381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to the previous test, but ensure that popup blocking bypass
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isn't granted to the iframe.  See crbug.com/117446.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/153513
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_OpenAppFromIframe OpenAppFromIframe
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (not in the app).
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
66358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  PopupBlockerTabHelper* popup_blocker_tab_helper =
66458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      PopupBlockerTabHelper::FromWebContents(tab);
6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!popup_blocker_tab_helper->GetBlockedPopupsCount()) {
66658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    content::WindowedNotificationObserver observer(
66758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
66858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch        content::NotificationService::AllSources());
66958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    observer.Wait();
67058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  }
67158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount());
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if an extension launches an app via chrome.tabs.create with an URL
676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// that's not in the app's extent but that server redirects to it, we still end
677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// up with an app process. See http://crbug.com/99349 for more details.
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(StartEmbeddedTestServer());
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LoadExtension(test_data_dir_.AppendASCII("app_process"));
683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const Extension* launcher =
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // There should be two navigations by the time the app page is loaded.
687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 1. The extension launcher page.
688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 2. The app's URL (which includes a server redirect).
689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Note that the server redirect does not generate a navigation event.
690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestNavigationObserver test_navigation_observer(
691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      2);
693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test_navigation_observer.StartWatchingNewWebContents();
694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Load the launcher extension, which should launch the app.
696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser(),
698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      launcher->GetResourceURL("server_redirect.html"),
699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CURRENT_TAB,
700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Wait for app tab to be created and loaded.
7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  test_navigation_observer.Wait();
704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // App has loaded, and chrome.app.isInstalled should be true.
706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool is_installed = false;
707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      &is_installed));
711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(is_installed);
712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests that if an extension launches an app via chrome.tabs.create with an URL
715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// that's not in the app's extent but that client redirects to it, we still end
716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// up with an app process.
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(StartEmbeddedTestServer());
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadExtension(test_data_dir_.AppendASCII("app_process"));
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* launcher =
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be three navigations by the time the app page is loaded.
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. The extension launcher page.
727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 2. The URL that the extension launches, which client redirects.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. The app's URL.
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestNavigationObserver test_navigation_observer(
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      3);
732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test_navigation_observer.StartWatchingNewWebContents();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the launcher extension, which should launch the app.
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      launcher->GetResourceURL("client_redirect.html"),
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CURRENT_TAB,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for app tab to be created and loaded.
7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  test_navigation_observer.Wait();
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // App has loaded, and chrome.app.isInstalled should be true.
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_installed = false;
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if we have an app process (path1/container.html) with a non-app
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iframe (path3/iframe.html), then opening a link from that iframe to a new
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window to a same-origin non-app URL (path3/empty.html) should keep the window
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the app process.
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is in contrast to OpenAppFromIframe, since here the popup will not be
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// missing special permissions and should be scriptable from the iframe.
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/92669 for more details.
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (in the app).
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base_url.Resolve("path1/container.html"));
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderProcessHost* process =
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(process->GetID()));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Popup window should be in the app's process.
7811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const BrowserList* active_browser_list =
7821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      BrowserList::GetInstance(chrome::GetActiveDesktop());
7831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(2U, active_browser_list->size());
7841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WebContents* popup_contents =
7851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  content::WaitForLoadStop(popup_contents);
7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RenderViewHost* popup_host = popup_contents->GetRenderViewHost();
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(process, popup_host->GetProcess());
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/118502
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) || defined(OS_LINUX)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the app, chrome.app.isInstalled should be true.
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_installed = false;
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents,
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Crash the tab and reload it, chrome.app.isInstalled should still be true.
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver observer(
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.Wait();
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents,
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
836a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test that a cross-process navigation away from a hosted app stays in the same
838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// BrowsingInstance, so that postMessage calls to the app's other windows still
839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// work.
840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, SameBrowsingInstanceAfterSwap) {
8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ProcessMap* process_map =
8425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ProcessMap::Get(browser()->profile());
843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
845a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
846a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Load app and start URL (in the app).
850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const Extension* app =
851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
852a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(app);
853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               base_url.Resolve("path1/iframe.html"));
856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::SiteInstance* app_instance =
857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->GetSiteInstance();
858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(app_instance->GetProcess()->GetID()));
859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Popup window should be in the app's process.
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const BrowserList* active_browser_list =
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      BrowserList::GetInstance(chrome::GetActiveDesktop());
863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(2U, active_browser_list->size());
864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::WebContents* popup_contents =
865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      active_browser_list->get(1)->tab_strip_model()->GetActiveWebContents();
866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::WaitForLoadStop(popup_contents);
867a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SiteInstance* popup_instance = popup_contents->GetSiteInstance();
869a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(app_instance, popup_instance);
870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Navigate the popup to another process outside the app.
872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GURL non_app_url(base_url.Resolve("path3/empty.html"));
873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ui_test_utils::NavigateToURL(active_browser_list->get(1), non_app_url);
874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SiteInstance* new_instance = popup_contents->GetSiteInstance();
875a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(app_instance, new_instance);
876a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
877a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // It should still be in the same BrowsingInstance, allowing postMessage to
878a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // work.
879a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(app_instance->IsRelatedSiteInstance(new_instance));
880a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
881