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/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index b5301d164138f21ca8ae01abfb153efde51ec324..91efc5f94f61f7bccc2ff802851097df8eb52818 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -2127,6 +2127,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();
@@ -2159,6 +2169,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
+                : SiteInstance::CreateForURL(browser_context,
+                                             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.
@@ -2170,23 +2225,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/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 3729dcc9ea3272c943754a92c6ed1d7a1fd8fcf3..2317ddf6a3c533f701fe44bf1b8114eb042c2189 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -51,6 +51,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 4c84fb3648b3de36015b325246559f8aefe2ebd5..a81f40507b2233c3bde03b940cccd6be0aaa4926 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -211,8 +211,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.