// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/browsing_instance.h"

#include "base/check_op.h"
#include "base/command_line.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/site_info.h"
#include "content/browser/site_instance_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_or_resource_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"

namespace content {

// Start the BrowsingInstance ID counter from 1 to avoid a conflict with the
// invalid BrowsingInstanceId value, which is 0 in its underlying IdType32.
int BrowsingInstance::next_browsing_instance_id_ = 1;

BrowsingInstance::BrowsingInstance(
    BrowserContext* browser_context,
    const WebExposedIsolationInfo& web_exposed_isolation_info,
    bool is_guest,
    bool is_fenced)
    : isolation_context_(
          BrowsingInstanceId::FromUnsafeValue(next_browsing_instance_id_++),
          BrowserOrResourceContext(browser_context),
          is_guest,
          is_fenced),
      active_contents_count_(0u),
      default_site_instance_(nullptr),
      web_exposed_isolation_info_(web_exposed_isolation_info) {
  DCHECK(browser_context);
}

BrowserContext* BrowsingInstance::GetBrowserContext() const {
  return isolation_context_.browser_or_resource_context().ToBrowserContext();
}

bool BrowsingInstance::HasSiteInstance(const SiteInfo& site_info) {
  return site_instance_map_.find(site_info) != site_instance_map_.end();
}

scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
    const UrlInfo& url_info,
    bool allow_default_instance) {
  scoped_refptr<SiteInstanceImpl> site_instance =
      GetSiteInstanceForURLHelper(url_info, allow_default_instance);

  if (site_instance)
    return site_instance;

  // No current SiteInstance for this site, so let's create one.
  scoped_refptr<SiteInstanceImpl> instance = new SiteInstanceImpl(this);

  // Set the site of this new SiteInstance, which will register it with us.
  // Some URLs should leave the SiteInstance's site unassigned, though if
  // `instance` is for a guest, we should always set the site to ensure that it
  // carries guest information contained within SiteInfo.
  if (SiteInstance::ShouldAssignSiteForURL(url_info.url) ||
      isolation_context_.is_guest())
    instance->SetSite(url_info);
  return instance;
}

SiteInfo BrowsingInstance::GetSiteInfoForURL(const UrlInfo& url_info,
                                             bool allow_default_instance) {
  scoped_refptr<SiteInstanceImpl> site_instance =
      GetSiteInstanceForURLHelper(url_info, allow_default_instance);

  if (site_instance)
    return site_instance->GetSiteInfo();

  return ComputeSiteInfoForURL(url_info);
}

scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForSiteInfo(
    const SiteInfo& site_info) {
  auto i = site_instance_map_.find(site_info);
  if (i != site_instance_map_.end())
    return i->second;

  scoped_refptr<SiteInstanceImpl> instance = new SiteInstanceImpl(this);
  instance->SetSite(site_info);
  return instance;
}

scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURLHelper(
    const UrlInfo& url_info,
    bool allow_default_instance) {
  const SiteInfo site_info = ComputeSiteInfoForURL(url_info);
  auto i = site_instance_map_.find(site_info);
  if (i != site_instance_map_.end())
    return i->second;

  // Check to see if we can use the default SiteInstance for sites that don't
  // need to be isolated in their own process.
  if (allow_default_instance &&
      SiteInstanceImpl::CanBePlacedInDefaultSiteInstance(
          isolation_context_, url_info.url, site_info)) {
    scoped_refptr<SiteInstanceImpl> site_instance =
        default_site_instance_.get();
    if (!site_instance) {
      site_instance = new SiteInstanceImpl(this);

      // Note: |default_site_instance_| will get set inside this call
      // via RegisterSiteInstance().
      site_instance->SetSiteInfoToDefault(site_info.storage_partition_config());
      DCHECK_EQ(default_site_instance_, site_instance.get());
    }

    // Add |site_info| to the set so we can keep track of all the sites the
    // the default SiteInstance has been returned for.
    site_instance->AddSiteInfoToDefault(site_info);
    return site_instance;
  }

  return nullptr;
}

void BrowsingInstance::RegisterSiteInstance(SiteInstanceImpl* site_instance) {
  DCHECK(site_instance->browsing_instance_.get() == this);
  DCHECK(site_instance->HasSite());

  // Verify that the SiteInstance's StoragePartitionConfig matches this
  // BrowsingInstance's StoragePartitionConfig if it already has one.
  const StoragePartitionConfig& storage_partition_config =
      site_instance->GetSiteInfo().storage_partition_config();
  if (storage_partition_config_.has_value()) {
    // We should only use a single StoragePartition within a BrowsingInstance.
    // If we're attempting to use multiple, something has gone wrong with the
    // logic at upper layers.  Similarly, whether this StoragePartition is for
    // a guest should remain constant over a BrowsingInstance's lifetime.
    CHECK_EQ(storage_partition_config_.value(), storage_partition_config);
    CHECK_EQ(isolation_context_.is_guest(), site_instance->IsGuest());
  } else {
    storage_partition_config_ = storage_partition_config;
  }

  // Explicitly prevent the default SiteInstance from being added since
  // the map is only supposed to contain instances that map to a single site.
  if (site_instance->IsDefaultSiteInstance()) {
    CHECK(!default_site_instance_);
    default_site_instance_ = site_instance;
    return;
  }

  const SiteInfo& site_info = site_instance->GetSiteInfo();

  // Only register if we don't have a SiteInstance for this site already.
  // It's possible to have two SiteInstances point to the same site if two
  // tabs are navigated there at the same time.  (We don't call SetSite or
  // register them until DidNavigate.)  If there is a previously existing
  // SiteInstance for this site, we just won't register the new one.
  auto i = site_instance_map_.find(site_info);
  if (i == site_instance_map_.end()) {
    // Not previously registered, so register it.
    site_instance_map_[site_info] = site_instance;
  }
}

void BrowsingInstance::UnregisterSiteInstance(SiteInstanceImpl* site_instance) {
  DCHECK(site_instance->browsing_instance_.get() == this);
  DCHECK(site_instance->HasSite());

  if (site_instance == default_site_instance_) {
    // The last reference to the default SiteInstance is being destroyed.
    default_site_instance_ = nullptr;
  }

  // Only unregister the SiteInstance if it is the same one that is registered
  // for the site.  (It might have been an unregistered SiteInstance.  See the
  // comments in RegisterSiteInstance.)
  auto i = site_instance_map_.find(site_instance->GetSiteInfo());
  if (i != site_instance_map_.end() && i->second == site_instance) {
    // Matches, so erase it.
    site_instance_map_.erase(i);
  }
}

// static
BrowsingInstanceId BrowsingInstance::NextBrowsingInstanceId() {
  return BrowsingInstanceId::FromUnsafeValue(next_browsing_instance_id_);
}

BrowsingInstance::~BrowsingInstance() {
  // We should only be deleted when all of the SiteInstances that refer to
  // us are gone.
  DCHECK(site_instance_map_.empty());
  DCHECK_EQ(0u, active_contents_count_);
  DCHECK(!default_site_instance_);

  // Remove any origin isolation opt-ins related to this instance.
  ChildProcessSecurityPolicyImpl* policy =
      ChildProcessSecurityPolicyImpl::GetInstance();
  policy->RemoveOptInIsolatedOriginsForBrowsingInstance(
      isolation_context_.browsing_instance_id());
}

SiteInfo BrowsingInstance::ComputeSiteInfoForURL(
    const UrlInfo& url_info) const {
  // If a StoragePartitionConfig is specified in both `url_info` and this
  // BrowsingInstance, make sure they match.
  if (url_info.storage_partition_config.has_value() &&
      storage_partition_config_.has_value()) {
    CHECK_EQ(storage_partition_config_.value(),
             url_info.storage_partition_config.value());
  }
  // If no StoragePartitionConfig was set in `url_info`, create a new UrlInfo
  // that inherit's this BrowsingInstance's StoragePartitionConfig.
  UrlInfo url_info_with_partition =
      url_info.storage_partition_config.has_value()
          ? url_info
          : UrlInfo(UrlInfoInit(url_info).WithStoragePartitionConfig(
                storage_partition_config_));

  // The WebExposedIsolationInfos must be compatible for this function to make
  // sense.
  DCHECK(WebExposedIsolationInfo::AreCompatible(
      url_info.web_exposed_isolation_info, web_exposed_isolation_info_));

  // If the passed in UrlInfo has a null WebExposedIsolationInfo, meaning that
  // it is compatible with any isolation state, we reuse the isolation state of
  // the BrowsingInstance.
  url_info_with_partition.web_exposed_isolation_info =
      url_info.web_exposed_isolation_info.value_or(web_exposed_isolation_info_);
  return SiteInfo::Create(isolation_context_, url_info_with_partition);
}

int BrowsingInstance::EstimateOriginAgentClusterOverhead() {
  DCHECK(SiteIsolationPolicy::IsProcessIsolationForOriginAgentClusterEnabled());

  std::set<SiteInfo> site_info_set;
  std::set<SiteInfo> site_info_set_no_oac;

  // The following computes an estimate of how many additional processes have
  // been created to deal with OriginAgentCluster (OAC) headers. When OAC
  // headers forces an additional process, that corresponds to the SiteInfo's
  // is_origin_keyed_ flag being set. To compute the estimate, we use the set of
  // unique SiteInstances (each represented by a unique SiteInfo) in each
  // BrowsingInstance as a proxy for the set of different RenderProcesses. We
  // start with the total count of SiteInfos, then we create a new set of
  // SiteInfos created by resetting the is_origin_keyed_ flag on each of the
  // SiteInfos (along with any corresponding adjustments to the site_url_ and
  // process_lock_url_ to reflect the possible conversion from origin to site).
  // The assumption here is that SiteInfos that forced a new process due to OAC
  // may no longer be unique once these values are reset, and as such the new
  // set will have less elements than the original set, with the difference
  // being the count of extra SiteInstances due to OAC. There are cases where
  // ignoring the OAC header would still result in an extra process, e.g. when
  // the SiteInfo's origin appears in the command-line origin isolation list.
  //
  // The estimate is computed using several simplifying assumptions:
  // 1) We only consider HTTPS SiteInfos to compute the additional SiteInfos.
  // This assumption should generally be valid, since we don't apply
  // is_origin_keyed_ to non-HTTPS schemes.
  // 2) We assume that SiteInfos from multiple BrowsingInstances aren't
  // coalesced into a single RenderProcess.  While this isn't true in general,
  // it is difficult in practice to account for, so we don't try to.
  for (auto& entry : site_instance_map_) {
    const SiteInfo& site_info = entry.first;
    GURL process_lock_url = site_info.process_lock_url();
    if (!process_lock_url.SchemeIs(url::kHttpsScheme))
      continue;

    site_info_set.insert(site_info);
    site_info_set_no_oac.insert(
        site_info.GetNonOriginKeyedEquivalentForMetrics(isolation_context_));
  }
  DCHECK_GE(site_info_set.size(), site_info_set_no_oac.size());
  int result = site_info_set.size() - site_info_set_no_oac.size();
  return result;
}

}  // namespace content
