// Copyright (c) 2012 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.

#include "chrome/common/extensions/extension_process_policy.h"

#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"

namespace extensions {

const extensions::Extension* GetNonBookmarkAppExtension(
    const ExtensionSet& extensions, const GURL& url) {
  // Exclude bookmark apps, which do not use the app process model.
  const extensions::Extension* extension =
      extensions.GetExtensionOrAppByURL(url);
  if (extension && extension->from_bookmark())
    extension = NULL;
  return extension;
}

bool CrossesExtensionProcessBoundary(
    const 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() &&
        !AppIsolationInfo::HasIsolatedStorage(old_url_extension);
    bool new_url_is_normal_or_hosted = !new_url_extension ||
        (!new_url_extension->web_extent().is_empty() &&
         !AppIsolationInfo::HasIsolatedStorage(new_url_extension));
    bool either_is_web_store =
        (old_url_extension &&
        old_url_extension->id() == extension_misc::kWebStoreAppId) ||
        (new_url_extension &&
        new_url_extension->id() == extension_misc::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;
}

}  // namespace extensions