| Index: chrome/renderer/extensions/chrome_extensions_renderer_client.cc
|
| diff --git a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
|
| index b1127e949e6dfdc908f093ff19dcd69512884b8a..b7150aba143751ef74c739bead4b53576da7cfe2 100644
|
| --- a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
|
| +++ b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
|
| @@ -13,7 +13,6 @@
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/common/extensions/extension_constants.h"
|
| #include "chrome/common/extensions/extension_metrics.h"
|
| -#include "chrome/common/extensions/extension_process_policy.h"
|
| #include "chrome/common/url_constants.h"
|
| #include "chrome/renderer/chrome_render_thread_observer.h"
|
| #include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
|
| @@ -26,6 +25,7 @@
|
| #include "extensions/common/constants.h"
|
| #include "extensions/common/extension.h"
|
| #include "extensions/common/extension_set.h"
|
| +#include "extensions/common/manifest_handlers/app_isolation_info.h"
|
| #include "extensions/common/switches.h"
|
| #include "extensions/renderer/dispatcher.h"
|
| #include "extensions/renderer/extension_frame_helper.h"
|
| @@ -39,6 +39,7 @@
|
| #include "third_party/WebKit/public/web/WebDocument.h"
|
| #include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| #include "third_party/WebKit/public/web/WebPluginParams.h"
|
| +#include "url/gurl.h"
|
|
|
| using extensions::Extension;
|
|
|
| @@ -57,9 +58,71 @@ void IsGuestViewApiAvailableToScriptContext(
|
| }
|
| }
|
|
|
| +// Returns the extension for the given URL. Excludes extension objects for
|
| +// bookmark apps, which do not use the app process model.
|
| +const Extension* GetNonBookmarkAppExtension(
|
| + const extensions::ExtensionSet& extensions,
|
| + const GURL& url) {
|
| + // Exclude bookmark apps, which do not use the app process model.
|
| + const Extension* extension = extensions.GetExtensionOrAppByURL(url);
|
| + if (extension && extension->from_bookmark())
|
| + extension = NULL;
|
| + return extension;
|
| +}
|
| +
|
| +bool IsHostedApp(const extensions::ExtensionSet& extensions, const GURL& url) {
|
| + const extensions::Extension* extension =
|
| + GetNonBookmarkAppExtension(extensions, url);
|
| + return extension && extension->is_app();
|
| +}
|
| +
|
| +// Check if navigating a toplevel page from |old_url| to |new_url| would cross
|
| +// an extension process boundary (e.g. navigating from a web URL into an
|
| +// extension URL).
|
| +// We temporarily consider a workaround where we will keep non-app URLs in
|
| +// an app process, but only if |should_consider_workaround| is true. See
|
| +// http://crbug.com/59285.
|
| +bool CrossesExtensionProcessBoundary(const extensions::ExtensionSet& extensions,
|
| + const GURL& old_url,
|
| + const GURL& new_url,
|
| + bool should_consider_workaround) {
|
| + const extensions::Extension* old_url_extension =
|
| + GetNonBookmarkAppExtension(extensions, old_url);
|
| + const extensions::Extension* new_url_extension =
|
| + GetNonBookmarkAppExtension(extensions, new_url);
|
| +
|
| + // TODO(creis): Temporary workaround for crbug.com/59285: Do not swap process
|
| + // to navigate from a hosted app to a normal page or another hosted app
|
| + // (unless either is the web store). This is because some OAuth providers
|
| + // use non-app popups that communicate with non-app iframes inside the app
|
| + // (e.g., Facebook). This would require out-of-process iframes to support.
|
| + // See http://crbug.com/99379.
|
| + // Note that we skip this exception for isolated apps, which require strict
|
| + // process separation from non-app pages.
|
| + if (should_consider_workaround) {
|
| + bool old_url_is_hosted_app =
|
| + old_url_extension && !old_url_extension->web_extent().is_empty() &&
|
| + !extensions::AppIsolationInfo::HasIsolatedStorage(old_url_extension);
|
| + bool new_url_is_normal_or_hosted =
|
| + !new_url_extension ||
|
| + (!new_url_extension->web_extent().is_empty() &&
|
| + !extensions::AppIsolationInfo::HasIsolatedStorage(new_url_extension));
|
| + bool either_is_web_store =
|
| + (old_url_extension &&
|
| + old_url_extension->id() == extensions::kWebStoreAppId) ||
|
| + (new_url_extension &&
|
| + new_url_extension->id() == extensions::kWebStoreAppId);
|
| + if (old_url_is_hosted_app && new_url_is_normal_or_hosted &&
|
| + !either_is_web_store)
|
| + return false;
|
| + }
|
| +
|
| + return old_url_extension != new_url_extension;
|
| +}
|
| +
|
| // Returns true if the frame is navigating to an URL either into or out of an
|
| // extension app's extent.
|
| -bool CrossesExtensionExtents(blink::WebLocalFrame* frame,
|
| +bool CrossesHostedAppExtents(blink::WebLocalFrame* frame,
|
| const GURL& new_url,
|
| bool is_extension_url,
|
| bool is_initial_navigation) {
|
| @@ -68,6 +131,8 @@ bool CrossesExtensionExtents(blink::WebLocalFrame* frame,
|
|
|
| extensions::RendererExtensionRegistry* extension_registry =
|
| extensions::RendererExtensionRegistry::Get();
|
| + const extensions::ExtensionSet& main_thread_extensions =
|
| + *extension_registry->GetMainThreadExtensionSet();
|
|
|
| // If old_url is still empty and this is an initial navigation, then this is
|
| // a window.open operation. We should look at the opener URL. Note that the
|
| @@ -101,14 +166,22 @@ bool CrossesExtensionExtents(blink::WebLocalFrame* frame,
|
| return false;
|
| }
|
|
|
| + // With --isolate-extensions, forking is no longer needed to isolate
|
| + // extensions into separate renderer processes (i.e. isolation should
|
| + // be enforced by the transfer logic).
|
| + bool old_or_new_is_hosted_app =
|
| + IsHostedApp(main_thread_extensions, old_url) ||
|
| + IsHostedApp(main_thread_extensions, new_url);
|
| + if (!old_or_new_is_hosted_app)
|
| + return false;
|
| +
|
| // Only consider keeping non-app URLs in an app process if this window
|
| // has an opener (in which case it might be an OAuth popup that tries to
|
| // script an iframe within the app).
|
| bool should_consider_workaround = !!frame->Opener();
|
|
|
| - return extensions::CrossesExtensionProcessBoundary(
|
| - *extension_registry->GetMainThreadExtensionSet(), old_url, new_url,
|
| - should_consider_workaround);
|
| + return CrossesExtensionProcessBoundary(main_thread_extensions, old_url,
|
| + new_url, should_consider_workaround);
|
| }
|
|
|
| } // namespace
|
| @@ -246,7 +319,7 @@ bool ChromeExtensionsRendererClient::ShouldFork(blink::WebLocalFrame* frame,
|
| extensions::RendererExtensionRegistry::Get();
|
|
|
| // Determine if the new URL is an extension (excluding bookmark apps).
|
| - const Extension* new_url_extension = extensions::GetNonBookmarkAppExtension(
|
| + const Extension* new_url_extension = GetNonBookmarkAppExtension(
|
| *extension_registry->GetMainThreadExtensionSet(), url);
|
| bool is_extension_url = !!new_url_extension;
|
|
|
| @@ -256,7 +329,7 @@ bool ChromeExtensionsRendererClient::ShouldFork(blink::WebLocalFrame* frame,
|
| // 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, is_extension_url,
|
| + CrossesHostedAppExtents(frame, url, 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
|
|
|