app_process_apitest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_host.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/process_map.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_file_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_navigation_observer.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/string_ordinal.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppApiTest : public ExtensionApiTest {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the base URL for files for a specific test, making sure that it uses
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "localhost" as the hostname, since that is what the extent is declared
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as in the test apps manifests.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetTestBaseURL(std::string test_directory) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL::Replacements replace_host;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string host_str("localhost");  // must stay in scope with replace_host
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replace_host.SetHostStr(host_str);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL base_url = test_server()->GetURL(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "files/extensions/api_test/" + test_directory + "/");
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base_url.ReplaceComponents(replace_host);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pass flags to make testing apps easier.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionApiTest::SetUpCommandLine(command_line);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kDisablePopupBlocking);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kAllowHTTPBackgroundPage);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function to test that independent tabs of the named app are loaded
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into separate processes.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestAppInstancesHelper(std::string app_name) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "Start of test.";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser()->profile())->extension_service()->process_map();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver()->AddRule("*", "127.0.0.1");
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_server()->Start());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(LoadExtension(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_data_dir_.AppendASCII(app_name)));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Open two tabs in the app, one outside it.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL base_url = GetTestBaseURL(app_name);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test both opening a URL in a new tab, and opening a tab and then
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // navigating it.  Either way, app tabs should be considered extension
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // processes, but they have no elevated privileges and thus should not
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // have WebUI bindings.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_test_utils::NavigateToURLWithDisposition(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "Nav 1.";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(process_map->Contains(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser()->tab_strip_model()->GetWebContentsAt(1)->
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetRenderProcessHost()->GetID()));
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WindowedNotificationObserver tab_added_observer(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_TAB_ADDED,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::AllSources());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::NewTab(browser());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_added_observer.Wait();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "New tab.";
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_test_utils::NavigateToURL(browser(),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base_url.Resolve("path2/empty.html"));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "Nav 2.";
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(process_map->Contains(
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        browser()->tab_strip_model()->GetWebContentsAt(2)->
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetRenderProcessHost()->GetID()));
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We should have opened 2 new extension tabs. Including the original blank
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tab, we now have 3 tabs. The two app tabs should not be in the same
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // process, since they do not have the background permission.  (Thus, we
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // want to separate them to improve responsiveness.)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(3, browser()->tab_strip_model()->count());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* tab1 = browser()->tab_strip_model()->GetWebContentsAt(1);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* tab2 = browser()->tab_strip_model()->GetWebContentsAt(2);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Opening tabs with window.open should keep the page in the opener's
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // process.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          browser()->host_desktop_type()));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpenWindow(tab1, base_url.Resolve("path1/empty.html"), true, NULL);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "WindowOpenHelper 1.";
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OpenWindow(tab2, base_url.Resolve("path2/empty.html"), true, NULL);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "End of test.";
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Omits the disable-popup-blocking flag so we can cover that case.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BlockedAppApiTest : public AppApiTest {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionApiTest::SetUpCommandLine(command_line);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kAllowHTTPBackgroundPage);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that hosted apps with the background permission get a process-per-app
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// model, since all pages need to be able to script the background page.
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://crbug.com/172750
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AppProcess DISABLED_AppProcess
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AppProcess AppProcess
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcess) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Start of test.";
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Loaded extension.";
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open two tabs in the app, one outside it.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test both opening a URL in a new tab, and opening a tab and then navigating
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it.  Either way, app tabs should be considered extension processes, but
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // they have no elevated privileges and thus should not have WebUI bindings.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(1)->
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Nav 1.";
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path2/empty.html"), NEW_FOREGROUND_TAB,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(2)->
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Nav 2.";
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver tab_added_observer(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_ADDED,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_added_observer.Wait();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "New tab.";
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path3/empty.html"));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Nav 3.";
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(3)->
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(3)->GetWebUI());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have opened 3 new extension tabs. Including the original blank
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab, we now have 4 tabs. Because the app_process app has the background
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // permission, all of its instances are in the same process.  Thus two tabs
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be part of the extension app and grouped in the same process.
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(4, browser()->tab_strip_model()->count());
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tab->GetRenderProcessHost(),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(tab->GetRenderProcessHost(),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(3)->
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's do the same using window.open. The same should happen.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        browser()->host_desktop_type()));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "WindowOpenHelper 1.";
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "WindowOpenHelper 2.";
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(creis): This should open in a new process (i.e., false for the last
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument), but we temporarily avoid swapping processes away from a hosted
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // app if it has an opener, because some OAuth providers make script calls
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // between non-app popups and non-app iframes in the app process.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See crbug.com/59285.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path3/empty.html"), true, NULL);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "WindowOpenHelper 3.";
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's have these pages navigate, into or out of the extension web
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extent. They should switch processes.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& app_url(base_url.Resolve("path1/empty.html"));
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     non_app_url);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "NavigateTabHelper 1.";
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(3),
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     app_url);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "NavigateTabHelper 2.";
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(tab->GetRenderProcessHost(),
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tab->GetRenderProcessHost(),
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(3)->
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If one of the popup tabs navigates back to the app, window.opener should
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(6),
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     app_url);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "NavigateTabHelper 3.";
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tab->GetRenderProcessHost(),
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(6)->
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool windowOpenerValid = false;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(6),
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(window.opener != null)",
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &windowOpenerValid));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(windowOpenerValid);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "End of test.";
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that hosted apps without the background permission use a process per app
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instance model, such that separate instances are in separate processes.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessInstances) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAppInstancesHelper("app_process_instances");
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that hosted apps with the background permission but that set
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// allow_js_access to false also use a process per app instance model.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Separate instances should be in separate processes.
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Flaky on XP: http://crbug.com/165834
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AppProcessBackgroundInstances \
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISABLED_AppProcessBackgroundInstances
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AppProcessBackgroundInstances AppProcessBackgroundInstances
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcessBackgroundInstances) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAppInstancesHelper("app_process_background_instances");
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that bookmark apps do not use the app process model and are treated
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// like normal web pages instead.  http://crbug.com/104636.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, BookmarkAppGetsNormalProcess) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::ProcessMap* process_map = service->process_map();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an app as a bookmark app.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const Extension> extension(extension_file_util::LoadExtension(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_data_dir_.AppendASCII("app_process"),
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::Manifest::UNPACKED,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Extension::FROM_BOOKMARK,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &error));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->OnExtensionInstalled(extension,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                syncer::StringOrdinal::CreateInitialOrdinal(),
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                false /* no requirement errors */,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                false /* don't wait for idle */);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(extension.get());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(extension->from_bookmark());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test both opening a URL in a new tab, and opening a tab and then navigating
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it.  Either way, bookmark app tabs should be considered normal processes
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with no elevated privileges and no WebUI bindings.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/empty.html"), NEW_FOREGROUND_TAB,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(1)->
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(1)->GetWebUI());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver tab_added_observer(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_ADDED,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_added_observer.Wait();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path2/empty.html"));
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(2)->
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(browser()->tab_strip_model()->GetWebContentsAt(2)->GetWebUI());
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have opened 2 new bookmark app tabs. Including the original blank
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab, we now have 3 tabs.  Because normal pages use the
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process-per-site-instance model, each should be in its own process.
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, browser()->tab_strip_model()->count());
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(tab->GetRenderProcessHost(),
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's do the same using window.open. The same should happen.
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        browser()->host_desktop_type()));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path1/empty.html"), true, NULL);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenWindow(tab, base_url.Resolve("path2/empty.html"), true, NULL);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's have a tab navigate out of and back into the app's web
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extent. Neither navigation should switch processes.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& app_url(base_url.Resolve("path1/empty.html"));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* host2 =
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(2)->GetRenderViewHost();
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     non_app_url);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(host2->GetProcess(),
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateInRenderer(browser()->tab_strip_model()->GetWebContentsAt(2),
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     app_url);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(host2->GetProcess(),
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that app process switching works properly in the following scenario:
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. navigate to a page1 in the app
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. page1 redirects to a page2 outside the app extent (ie, "/server-redirect")
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. page2 redirects back to a page in the app
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The final navigation should end up in the app process.
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/61757
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, AppProcessRedirectBack) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open two tabs in the app.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NewTab(browser());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until the second tab finishes its redirect train (2 hops).
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. We navigate to redirect.html
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. Renderer navigates and finishes, counting as a load stop.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. Renderer issues the meta refresh to navigate to server-redirect.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4. Renderer is now in a "provisional load", waiting for navigation to
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    complete.
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 5. Browser sees a redirect response from server-redirect to empty.html, and
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    transfers that to a new navigation, using RequestTransferURL.
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6. Renderer navigates to empty.html, and finishes loading, counting as the
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    second load stop
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), base_url.Resolve("path1/redirect.html"), 2);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3 tabs, including the initial about:blank. The last 2 should be the same
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process.
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, browser()->tab_strip_model()->count());
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("/files/extensions/api_test/app_process/path1/empty.html",
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetController().GetLastCommittedEntry()->GetURL().path());
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(browser()->tab_strip_model()->GetWebContentsAt(1)->
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost(),
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            browser()->tab_strip_model()->GetWebContentsAt(2)->
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetRenderProcessHost());
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that re-navigating to a URL after installing or uninstalling it as an
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// app correctly swaps the tab to the app process.  (http://crbug.com/80621)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, NavigateIntoAppProcess) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an app URL before loading the app.
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app and re-navigate to the page.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Disable app and re-navigate to the page.
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisableExtension(app->id());
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that reloading a URL after installing or uninstalling it as an app
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// correctly swaps the tab to the app process.  (http://crbug.com/80621)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcess) {
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app, disable it, and navigate to the page.
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* app =
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(app);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable app and reload the page.
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableExtension(app->id());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver reload_observer(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_observer.Wait();
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable app and reload the page.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver reload_observer2(
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reload_observer2.Wait();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that reloading a URL with JavaScript after installing or uninstalling
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it as an app correctly swaps the process.  (http://crbug.com/80621)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, ReloadIntoAppProcessWithJavaScript) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The app under test acts on URLs whose host is "localhost",
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the URLs we navigate to must have host "localhost".
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load app, disable it, and navigate to the page.
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* app =
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(app);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisableExtension(app->id());
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable app and reload via JavaScript.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableExtension(app->id());
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver js_reload_observer(
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScript(contents, "location.reload();"));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_reload_observer.Wait();
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable app and reload via JavaScript.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableExtension(app->id());
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver js_reload_observer2(
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScript(contents, "location = location;"));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  js_reload_observer2.Wait();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if we have a non-app process (path3/container.html) that has an
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iframe with  a URL in the app's extent (path1/iframe.html), then opening a
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// link from that iframe to a new window to a URL in the app's extent (path1/
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// empty.html) results in the new window being in an app process. See
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/89272 for more details.
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (not in the app).
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver popup_observer(
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_RENDER_VIEW_HOST_CREATED,
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base_url.Resolve("path3/container.html"));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(process_map->Contains(
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRenderProcessHost()->GetID()));
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  popup_observer.Wait();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Popup window should be in the app's process.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* popup_host =
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<RenderViewHost>(popup_observer.source()).ptr();
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(popup_host->GetProcess()->GetID()));
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to the previous test, but ensure that popup blocking bypass
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isn't granted to the iframe.  See crbug.com/117446.
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/153513
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_OpenAppFromIframe DISABLED_OpenAppFromIframe
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_OpenAppFromIframe OpenAppFromIframe
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BlockedAppApiTest, MAYBE_OpenAppFromIframe) {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (not in the app).
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver blocker_observer(
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_CONTENT_BLOCKED_STATE_CHANGED,
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(), GetTestBaseURL("app_process").Resolve("path3/container.html"));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blocker_observer.Wait();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BlockedContentTabHelper* blocked_content_tab_helper =
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BlockedContentTabHelper::FromWebContents(tab);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<WebContents*> blocked_contents;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blocked_content_tab_helper->GetBlockedContents(&blocked_contents);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(blocked_contents.size(), 1u);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if an extension launches an app via chrome.tabs.create with an URL
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that's not in the app's extent but that redirects to it, we still end up with
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an app process. See http://crbug.com/99349 for more details.
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromExtension) {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(StartTestServer());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadExtension(test_data_dir_.AppendASCII("app_process"));
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* launcher =
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be three navigations by the time the app page is loaded.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. The extension launcher page.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. The URL that the extension launches, which redirects.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. The app's URL.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestNavigationObserver test_navigation_observer(
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      3);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the launcher extension, which should launch the app.
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      launcher->GetResourceURL("main.html"),
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CURRENT_TAB,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for app tab to be created and loaded.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_navigation_observer.WaitForObservation(
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&content::RunMessageLoop),
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MessageLoop::Quit,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(MessageLoopForUI::current())));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // App has loaded, and chrome.app.isInstalled should be true.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_installed = false;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents(),
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if we have an app process (path1/container.html) with a non-app
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iframe (path3/iframe.html), then opening a link from that iframe to a new
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window to a same-origin non-app URL (path3/empty.html) should keep the window
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the app process.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is in contrast to OpenAppFromIframe, since here the popup will not be
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// missing special permissions and should be scriptable from the iframe.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/92669 for more details.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, OpenWebPopupFromWebIframe) {
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load app and start URL (in the app).
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* app =
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LoadExtension(test_data_dir_.AppendASCII("app_process"));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(app);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver popup_observer(
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NOTIFICATION_RENDER_VIEW_HOST_CREATED,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::AllSources());
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(),
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base_url.Resolve("path1/container.html"));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderProcessHost* process =
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderProcessHost();
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(process->GetID()));
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for popup window to appear.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  popup_observer.Wait();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Popup window should be in the app's process.
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* popup_host =
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<RenderViewHost>(popup_observer.source()).ptr();
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(process, popup_host->GetProcess());
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/118502
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) || defined(OS_LINUX)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ReloadAppAfterCrash DISABLED_ReloadAppAfterCrash
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ReloadAppAfterCrash ReloadAppAfterCrash
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_ReloadAppAfterCrash) {
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser()->profile())->extension_service()->process_map();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app_process")));
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL base_url = GetTestBaseURL("app_process");
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the app, chrome.app.isInstalled should be true.
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), base_url.Resolve("path1/empty.html"));
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = browser()->tab_strip_model()->GetWebContentsAt(0);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(process_map->Contains(
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()->GetID()));
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_installed = false;
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents,
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Crash the tab and reload it, chrome.app.isInstalled should still be true.
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents());
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver observer(
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &browser()->tab_strip_model()->GetActiveWebContents()->
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetController()));
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.Wait();
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents,
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "window.domAutomationController.send(chrome.app.isInstalled)",
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &is_installed));
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(is_installed);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
722