Avoids the extension check in ShouldFork for server-redirects.
These are already handled by the transfer navigation logic in the browser.
This is a first step towards moving the transfer navigation logic.

Also tests that the is_redirect value refers to server redirects and not
client redirects, by making sure we still swap processes for a client redirect
to an app.

BUG=238331
TEST=No behavior change.

Review URL: https://chromiumcodereview.appspot.com/16116006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203255 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index bcc8c64..b09c107 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -661,9 +661,9 @@
 }
 
 // Tests that if an extension launches an app via chrome.tabs.create with an URL
-// that's not in the app's extent but that redirects to it, we still end up with
-// an app process. See http://crbug.com/99349 for more details.
-IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromExtension) {
+// that's not in the app's extent but that server redirects to it, we still end
+// up with an app process. See http://crbug.com/99349 for more details.
+IN_PROC_BROWSER_TEST_F(AppApiTest, ServerRedirectToAppFromExtension) {
   host_resolver()->AddRule("*", "127.0.0.1");
   ASSERT_TRUE(StartTestServer());
 
@@ -682,7 +682,48 @@
   // Load the launcher extension, which should launch the app.
   ui_test_utils::NavigateToURLWithDisposition(
       browser(),
-      launcher->GetResourceURL("main.html"),
+      launcher->GetResourceURL("server_redirect.html"),
+      CURRENT_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+
+  // Wait for app tab to be created and loaded.
+  test_navigation_observer.WaitForObservation(
+      base::Bind(&content::RunMessageLoop),
+      base::Bind(&MessageLoop::Quit,
+                 base::Unretained(MessageLoopForUI::current())));
+
+  // App has loaded, and chrome.app.isInstalled should be true.
+  bool is_installed = false;
+  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+      browser()->tab_strip_model()->GetActiveWebContents(),
+      "window.domAutomationController.send(chrome.app.isInstalled)",
+      &is_installed));
+  ASSERT_TRUE(is_installed);
+}
+
+// Tests that if an extension launches an app via chrome.tabs.create with an URL
+// that's not in the app's extent but that client redirects to it, we still end
+// up with an app process.
+IN_PROC_BROWSER_TEST_F(AppApiTest, ClientRedirectToAppFromExtension) {
+  host_resolver()->AddRule("*", "127.0.0.1");
+  ASSERT_TRUE(StartTestServer());
+
+  LoadExtension(test_data_dir_.AppendASCII("app_process"));
+  const Extension* launcher =
+      LoadExtension(test_data_dir_.AppendASCII("app_launcher"));
+
+  // There should be three navigations by the time the app page is loaded.
+  // 1. The extension launcher page.
+  // 2. The URL that the extension launches, which client redirects.
+  // 3. The app's URL.
+  content::TestNavigationObserver test_navigation_observer(
+      content::NotificationService::AllSources(),
+      3);
+
+  // Load the launcher extension, which should launch the app.
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(),
+      launcher->GetResourceURL("client_redirect.html"),
       CURRENT_TAB,
       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
 
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index e66d9bf9..14c0cd07c 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -873,6 +873,7 @@
                                              const GURL& url,
                                              const std::string& http_method,
                                              bool is_initial_navigation,
+                                             bool is_server_redirect,
                                              bool* send_referrer) {
   DCHECK(!frame->parent());
 
@@ -915,11 +916,12 @@
   bool is_extension_url = !!new_url_extension;
 
   // If the navigation would cross an app extent boundary, we also need
-  // to defer to the browser to ensure process isolation.
-  // TODO(erikkay) This is happening inside of a check to is_content_initiated
-  // which means that things like the back button won't trigger it.  Is that
-  // OK?
-  if (CrossesExtensionExtents(frame, url, *extensions, is_extension_url,
+  // to defer to the browser to ensure process isolation.  This is not necessary
+  // for server redirects, which will be transferred to a new process by the
+  // browser process when they are ready to commit.  It is necessary for client
+  // redirects, which won't be transferred in the same way.
+  if (!is_server_redirect &&
+      CrossesExtensionExtents(frame, url, *extensions, is_extension_url,
           is_initial_navigation)) {
     // Include the referrer in this case since we're going from a hosted web
     // page. (the packaged case is handled previously by the extension
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 8726c8a..02f620b6 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -89,6 +89,7 @@
                           const GURL& url,
                           const std::string& http_method,
                           bool is_initial_navigation,
+                          bool is_server_redirect,
                           bool* send_referrer) OVERRIDE;
   virtual bool WillSendRequest(WebKit::WebFrame* frame,
                                content::PageTransition transition_type,
diff --git a/chrome/test/data/extensions/api_test/app_launcher/client_redirect.html b/chrome/test/data/extensions/api_test/app_launcher/client_redirect.html
new file mode 100644
index 0000000..ff9f4bd
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/app_launcher/client_redirect.html
@@ -0,0 +1,6 @@
+<!--
+* Copyright (c) 2013 The Chromium Authors. All rights reserved. Use of this
+* source code is governed by a BSD-style license that can be found in the
+* LICENSE file.
+-->
+<script src="client_redirect.js"></script>
diff --git a/chrome/test/data/extensions/api_test/app_launcher/main.js b/chrome/test/data/extensions/api_test/app_launcher/client_redirect.js
similarity index 79%
copy from chrome/test/data/extensions/api_test/app_launcher/main.js
copy to chrome/test/data/extensions/api_test/app_launcher/client_redirect.js
index 47fd1bf..f5fa3c65 100644
--- a/chrome/test/data/extensions/api_test/app_launcher/main.js
+++ b/chrome/test/data/extensions/api_test/app_launcher/client_redirect.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,7 +6,7 @@
   var appUrl = 'http://localhost:' + config.testServer.port +
         '/files/extensions/api_test/app_process/path1/empty.html';
   var redirectUrl = 'http://localhost:' + config.testServer.port +
-      '/server-redirect?' + appUrl;
+      '/client-redirect?' + appUrl;
   chrome.tabs.create({
     url: redirectUrl
   });
diff --git a/chrome/test/data/extensions/api_test/app_launcher/main.html b/chrome/test/data/extensions/api_test/app_launcher/server_redirect.html
similarity index 80%
rename from chrome/test/data/extensions/api_test/app_launcher/main.html
rename to chrome/test/data/extensions/api_test/app_launcher/server_redirect.html
index c16c48f22..71dd3ecc 100644
--- a/chrome/test/data/extensions/api_test/app_launcher/main.html
+++ b/chrome/test/data/extensions/api_test/app_launcher/server_redirect.html
@@ -3,4 +3,4 @@
 * source code is governed by a BSD-style license that can be found in the
 * LICENSE file.
 -->
-<script src="main.js"></script>
+<script src="server_redirect.js"></script>
diff --git a/chrome/test/data/extensions/api_test/app_launcher/main.js b/chrome/test/data/extensions/api_test/app_launcher/server_redirect.js
similarity index 86%
rename from chrome/test/data/extensions/api_test/app_launcher/main.js
rename to chrome/test/data/extensions/api_test/app_launcher/server_redirect.js
index 47fd1bf..99e3a44 100644
--- a/chrome/test/data/extensions/api_test/app_launcher/main.js
+++ b/chrome/test/data/extensions/api_test/app_launcher/server_redirect.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright 2013 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index 45d08cd..449451f 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -101,6 +101,7 @@
                                        const GURL& url,
                                        const std::string& http_method,
                                        bool is_initial_navigation,
+                                       bool is_server_redirect,
                                        bool* send_referrer) {
   return false;
 }
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index b0c70a7..cea543c1 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -186,6 +186,7 @@
                           const GURL& url,
                           const std::string& http_method,
                           bool is_initial_navigation,
+                          bool is_server_redirect,
                           bool* send_referrer);
 
   // Notifies the embedder that the given frame is requesting the resource at
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index d028ce0..d3e7f65 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -3027,7 +3027,7 @@
       // Give the embedder a chance.
       should_fork = GetContentClient()->renderer()->ShouldFork(
           frame, url, request.httpMethod().utf8(), is_initial_navigation,
-          &send_referrer);
+          is_redirect, &send_referrer);
     }
 
     if (should_fork) {