1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/common/extensions/extension_process_policy.h"
6
7#include "chrome/common/extensions/extension_constants.h"
8#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
9#include "extensions/common/constants.h"
10#include "extensions/common/extension.h"
11#include "extensions/common/extension_set.h"
12
13namespace extensions {
14
15const extensions::Extension* GetNonBookmarkAppExtension(
16    const ExtensionSet& extensions, const GURL& url) {
17  // Exclude bookmark apps, which do not use the app process model.
18  const extensions::Extension* extension =
19      extensions.GetExtensionOrAppByURL(url);
20  if (extension && extension->from_bookmark())
21    extension = NULL;
22  return extension;
23}
24
25bool CrossesExtensionProcessBoundary(
26    const ExtensionSet& extensions,
27    const GURL& old_url,
28    const GURL& new_url,
29    bool should_consider_workaround) {
30  const extensions::Extension* old_url_extension = GetNonBookmarkAppExtension(
31      extensions,
32      old_url);
33  const extensions::Extension* new_url_extension = GetNonBookmarkAppExtension(
34      extensions,
35      new_url);
36
37  // TODO(creis): Temporary workaround for crbug.com/59285: Do not swap process
38  // to navigate from a hosted app to a normal page or another hosted app
39  // (unless either is the web store).  This is because some OAuth providers
40  // use non-app popups that communicate with non-app iframes inside the app
41  // (e.g., Facebook).  This would require out-of-process iframes to support.
42  // See http://crbug.com/99379.
43  // Note that we skip this exception for isolated apps, which require strict
44  // process separation from non-app pages.
45  if (should_consider_workaround) {
46    bool old_url_is_hosted_app = old_url_extension &&
47        !old_url_extension->web_extent().is_empty() &&
48        !AppIsolationInfo::HasIsolatedStorage(old_url_extension);
49    bool new_url_is_normal_or_hosted = !new_url_extension ||
50        (!new_url_extension->web_extent().is_empty() &&
51         !AppIsolationInfo::HasIsolatedStorage(new_url_extension));
52    bool either_is_web_store =
53        (old_url_extension &&
54        old_url_extension->id() == extensions::kWebStoreAppId) ||
55        (new_url_extension &&
56        new_url_extension->id() == extensions::kWebStoreAppId);
57    if (old_url_is_hosted_app &&
58        new_url_is_normal_or_hosted &&
59        !either_is_web_store)
60      return false;
61  }
62
63  return old_url_extension != new_url_extension;
64}
65
66}  // namespace extensions
67