From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 14 Nov 2018 20:38:46 +0530
Subject: frame_host_manager.patch

Allows embedder to intercept site instances chosen by chromium
and respond with custom instance.

diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc
index 8aca9384edb69012628fc9afb98f647aeec7d593..10fe96e6c9bfc7f33a81ad9b75c75d4dda776d7c 100644
--- a/content/browser/browsing_instance.cc
+++ b/content/browser/browsing_instance.cc
@@ -53,6 +53,13 @@ scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
   return instance;
 }
 
+scoped_refptr<SiteInstanceImpl> BrowsingInstance::CreateSiteInstanceForURL(
+    const GURL& url) {
+  scoped_refptr<SiteInstanceImpl> instance = new SiteInstanceImpl(this);
+  instance->SetSite(url);
+  return instance;
+}
+
 void BrowsingInstance::RegisterSiteInstance(SiteInstanceImpl* site_instance) {
   DCHECK(site_instance->browsing_instance_.get() == this);
   DCHECK(site_instance->HasSite());
diff --git a/content/browser/browsing_instance.h b/content/browser/browsing_instance.h
index d439dfbb603876f942ff40fe1a505f9498f57c23..fd576eb894e06fe6c5cb21351b2b95b0a8444dce 100644
--- a/content/browser/browsing_instance.h
+++ b/content/browser/browsing_instance.h
@@ -100,6 +100,11 @@ class CONTENT_EXPORT BrowsingInstance final
   // SiteInstance per site.
   scoped_refptr<SiteInstanceImpl> GetSiteInstanceForURL(const GURL& url);
 
+  // Create a new SiteInstance for the given URL bound the current
+  // BrowsingInstance.
+  scoped_refptr<SiteInstanceImpl> CreateSiteInstanceForURL(
+      const GURL& url);
+
   // Adds the given SiteInstance to our map, to ensure that we do not create
   // another SiteInstance for the same site.
   void RegisterSiteInstance(SiteInstanceImpl* site_instance);
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 0e3fc30fae933e0493920ed1823b086ac6ceee61..6dbb73c964601f0dae7ef6460a0ae2a048634a35 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1984,6 +1984,16 @@ bool RenderFrameHostManager::InitRenderView(
 scoped_refptr<SiteInstance>
 RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
     const NavigationRequest& request) {
+  BrowserContext* browser_context =
+      delegate_->GetControllerForRenderManager().GetBrowserContext();
+  // If the navigation can swap SiteInstances, compute the SiteInstance it
+  // should use.
+  // TODO(clamy): We should also consider as a candidate SiteInstance the
+  // speculative SiteInstance that was computed on redirects.
+  scoped_refptr<SiteInstance> candidate_site_instance =
+      speculative_render_frame_host_
+          ? speculative_render_frame_host_->GetSiteInstance()
+          : nullptr;
   // First, check if the navigation can switch SiteInstances. If not, the
   // navigation should use the current SiteInstance.
   SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
@@ -2016,6 +2026,51 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
                                               request.common_params().url);
     no_renderer_swap_allowed |=
         request.from_begin_navigation() && !can_renderer_initiate_transfer;
+
+    bool has_response_started =
+        (request.state() == NavigationRequest::RESPONSE_STARTED ||
+         request.state() == NavigationRequest::FAILED) &&
+        !speculative_render_frame_host_;
+    // Gives user a chance to choose a custom site instance.
+    SiteInstance* affinity_site_instance = nullptr;
+    scoped_refptr<SiteInstance> overriden_site_instance;
+    ContentBrowserClient::SiteInstanceForNavigationType siteInstanceType =
+        GetContentClient()->browser()->ShouldOverrideSiteInstanceForNavigation(
+            current_frame_host(), speculative_frame_host(), browser_context,
+            request.common_params().url, has_response_started,
+            &affinity_site_instance);
+    switch (siteInstanceType) {
+      case ContentBrowserClient::SiteInstanceForNavigationType::
+          FORCE_CANDIDATE_OR_NEW:
+        overriden_site_instance =
+            candidate_site_instance
+                ? candidate_site_instance
+                : current_site_instance->CreateRelatedSiteInstance(
+                                             request.common_params().url);
+        break;
+      case ContentBrowserClient::SiteInstanceForNavigationType::FORCE_CURRENT:
+        overriden_site_instance = render_frame_host_->GetSiteInstance();
+        break;
+      case ContentBrowserClient::SiteInstanceForNavigationType::FORCE_AFFINITY:
+        DCHECK(affinity_site_instance);
+        overriden_site_instance =
+            scoped_refptr<SiteInstance>(affinity_site_instance);
+        break;
+      case ContentBrowserClient::SiteInstanceForNavigationType::ASK_CHROMIUM:
+        DCHECK(!affinity_site_instance);
+        break;
+      default:
+        break;
+    }
+    if (overriden_site_instance) {
+      if (siteInstanceType ==
+          ContentBrowserClient::SiteInstanceForNavigationType::
+              FORCE_CANDIDATE_OR_NEW) {
+        GetContentClient()->browser()->RegisterPendingSiteInstance(
+            render_frame_host_.get(), overriden_site_instance.get());
+      }
+      return overriden_site_instance;
+    }
   } else {
     // Subframe navigations will use the current renderer, unless specifically
     // allowed to swap processes.
@@ -2027,23 +2082,17 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
   if (no_renderer_swap_allowed && !should_swap_for_error_isolation)
     return scoped_refptr<SiteInstance>(current_site_instance);
 
-  // If the navigation can swap SiteInstances, compute the SiteInstance it
-  // should use.
-  // TODO(clamy): We should also consider as a candidate SiteInstance the
-  // speculative SiteInstance that was computed on redirects.
-  SiteInstance* candidate_site_instance =
-      speculative_render_frame_host_
-          ? speculative_render_frame_host_->GetSiteInstance()
-          : nullptr;
-
   scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation(
       request.common_params().url, request.source_site_instance(),
-      request.dest_site_instance(), candidate_site_instance,
+      request.dest_site_instance(), candidate_site_instance.get(),
       request.common_params().transition,
       request.state() == NavigationRequest::FAILED,
       request.restore_type() != RestoreType::NONE, request.is_view_source(),
       was_server_redirect);
 
+  GetContentClient()->browser()->RegisterPendingSiteInstance(
+      render_frame_host_.get(), dest_site_instance.get());
+
   return dest_site_instance;
 }
 
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index e1a7560631bd07f812315cb9932475cf890d8a6b..34b947c34a3eb676286f43fcb23100134f751dfb 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -236,6 +236,10 @@ bool SiteInstanceImpl::HasRelatedSiteInstance(const GURL& url) {
   return browsing_instance_->HasSiteInstance(url);
 }
 
+scoped_refptr<SiteInstance> SiteInstanceImpl::CreateRelatedSiteInstance(const GURL& url) {
+  return browsing_instance_->CreateSiteInstanceForURL(url);
+}
+
 scoped_refptr<SiteInstance> SiteInstanceImpl::GetRelatedSiteInstance(
     const GURL& url) {
   return browsing_instance_->GetSiteInstanceForURL(url);
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
index da2696d679953096356e0c73891ff97854f76b54..c4c8e29a7723c4a22e6e52bd2f9ff792241b963a 100644
--- a/content/browser/site_instance_impl.h
+++ b/content/browser/site_instance_impl.h
@@ -70,6 +70,7 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
   BrowserContext* GetBrowserContext() const override;
   const GURL& GetSiteURL() const override;
   scoped_refptr<SiteInstance> GetRelatedSiteInstance(const GURL& url) override;
+	scoped_refptr<SiteInstance> CreateRelatedSiteInstance(const GURL& url) override;
   bool IsRelatedSiteInstance(const SiteInstance* instance) override;
   size_t GetRelatedActiveContentsCount() override;
   bool RequiresDedicatedProcess() override;
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 64c4d9eb2dfb8f53f7a6c8f00140b0cf22f18a49..0aff71c4339d0eacecf6b6d86ab750738696c31e 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -48,6 +48,16 @@ void OverrideOnBindInterface(const service_manager::BindSourceInfo& remote_info,
                                                          handle);
 }
 
+ContentBrowserClient::SiteInstanceForNavigationType ContentBrowserClient::ShouldOverrideSiteInstanceForNavigation(
+    content::RenderFrameHost* current_rfh,
+    content::RenderFrameHost* speculative_rfh,
+    content::BrowserContext* browser_context,
+    const GURL& url,
+    bool has_request_started,
+    content::SiteInstance** affinity_site_instance) const {
+  return SiteInstanceForNavigationType::ASK_CHROMIUM;
+}
+
 BrowserMainParts* ContentBrowserClient::CreateBrowserMainParts(
     const MainFunctionParams& parameters) {
   return nullptr;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index fdb9d7b8859270b36453e25349f7d84c44a6ce92..9f0a966d8abf72b606906b14f00748b4466f8b0a 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -206,8 +206,37 @@ CONTENT_EXPORT void OverrideOnBindInterface(
 // the observer interfaces.)
 class CONTENT_EXPORT ContentBrowserClient {
  public:
+  // Identifies the type of site instance to use for a navigation.
+  enum SiteInstanceForNavigationType {
+    // Use either the candidate site instance or, if it doesn't exist
+    // a new, unrelated site instance for the navigation.
+    FORCE_CANDIDATE_OR_NEW = 0,
+
+    // Use the current site instance for the navigation.
+    FORCE_CURRENT,
+
+    // Use the provided affinity site instance for the navigation.
+    FORCE_AFFINITY,
+
+    // Delegate the site instance creation to Chromium.
+    ASK_CHROMIUM
+  };
   virtual ~ContentBrowserClient() {}
 
+  // Electron: Allows overriding the SiteInstance when navigating.
+  virtual SiteInstanceForNavigationType ShouldOverrideSiteInstanceForNavigation(
+    content::RenderFrameHost* current_rfh,
+    content::RenderFrameHost* speculative_rfh,
+    content::BrowserContext* browser_context,
+    const GURL& url,
+    bool has_request_started,
+    content::SiteInstance** affinity_site_instance) const;
+
+  // Electron: Registers a pending site instance during a navigation.
+  virtual void RegisterPendingSiteInstance(
+      content::RenderFrameHost* rfh,
+      content::SiteInstance* pending_site_instance){};
+
   // Allows the embedder to set any number of custom BrowserMainParts
   // implementations for the browser startup code. See comments in
   // browser_main_parts.h.
diff --git a/content/public/browser/site_instance.h b/content/public/browser/site_instance.h
index 3b4c1cfacdad7ecc99b61cc0c2e4e71b72a855b6..d587f1e9211aa0e7636aa255a724ec9bb7399024 100644
--- a/content/public/browser/site_instance.h
+++ b/content/public/browser/site_instance.h
@@ -116,6 +116,11 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
   //   corresponds to a site URL with the host "example.com".
   virtual const GURL& GetSiteURL() const = 0;
 
+	// Create a SiteInstance for the given URL that shares the current
+	// BrowsingInstance.
+	virtual scoped_refptr<SiteInstance> CreateRelatedSiteInstance(
+	    const GURL& url) = 0;
+
   // Gets a SiteInstance for the given URL that shares the current
   // BrowsingInstance, creating a new SiteInstance if necessary.  This ensures
   // that a BrowsingInstance only has one SiteInstance per site, so that pages
