From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Wed, 15 Jan 2020 16:35:18 -0800
Subject: add DidInstallConditionalFeatures

This adds a hook on script context creation _after conditional features
have been installed_. Electron uses this to run preload scripts and
various other initialization. This is necessary because at the time
DidCreateScriptContext is called, not all JS APIs are available in the
context, which can cause some preload scripts to trip.

diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 0af40eb8f556aa29c8b7e1bdd0d62b1fb7b38791..b3ae64cf8836fdd3634bfd24fc2f8a25e1735da5 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -136,6 +136,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
   virtual void DidHandleOnloadEvents() {}
   virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
                                       int32_t world_id) {}
+  virtual void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
+                                             int32_t world_id) {}
   virtual void WillReleaseScriptContext(v8::Local<v8::Context> context,
                                         int32_t world_id) {}
   virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index fb0483af59b0e289bd716a3417a545233f17be1f..6a7e5ab92e6fa23762794efc3031ce982836c20e 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4365,6 +4365,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
     observer.DidCreateScriptContext(context, world_id);
 }
 
+void RenderFrameImpl::DidInstallConditionalFeatures(
+    v8::Local<v8::Context> context, int world_id) {
+  for (auto& observer : observers_)
+    observer.DidInstallConditionalFeatures(context, world_id);
+}
+
 void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context,
                                                int world_id) {
   for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 0e1296d023867bf1e4f12757d482cffcfe8a1942..0e4b144aeb54af86bc663d8b20fba4d0483ec28c 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -591,6 +591,8 @@ class CONTENT_EXPORT RenderFrameImpl
                           uint32_t ng_call_count) override;
   void DidCreateScriptContext(v8::Local<v8::Context> context,
                               int world_id) override;
+  void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
+                                     int world_id) override;
   void WillReleaseScriptContext(v8::Local<v8::Context> context,
                                 int world_id) override;
   void DidChangeScrollOffset() override;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 149ca596036a4a4c123b6982014001953cf06800..dd069baf01929b75f42093ecf09ecf8eb20376c0 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -580,6 +580,9 @@ class BLINK_EXPORT WebLocalFrameClient {
   virtual void DidCreateScriptContext(v8::Local<v8::Context>,
                                       int32_t world_id) {}
 
+  virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+                                             int32_t world_id) {}
+
   // WebKit is about to release its reference to a v8 context for a frame.
   virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
                                         int32_t world_id) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
index d0b5233ad45995bd6128a03fe9267618d723d683..e5e93be8f2433196a13aa104241b1ddd63985e81 100644
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -210,6 +210,7 @@ void LocalWindowProxy::Initialize() {
   }
 
   InstallConditionalFeatures();
+  GetFrame()->Client()->DidInstallConditionalFeatures(context, world_->GetWorldId());
 
   if (World().IsMainWorld()) {
     GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 83a62e23b1d395b0aa545de5b828c24196cccc6d..0ca8163eb9ab87aead27bc8b2ee9e614d7e1d8c7 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -301,6 +301,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
 
   virtual void DidCreateScriptContext(v8::Local<v8::Context>,
                                       int32_t world_id) = 0;
+  virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+                                             int32_t world_id) = 0;
   virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
                                         int32_t world_id) = 0;
   virtual bool AllowScriptExtensions() = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index 7b726508f926eb9e694230c3801a4324aac1e989..c688eb24441e2921de1fc85d69deb4a965fdd2b7 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -273,6 +273,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
     web_frame_->Client()->DidCreateScriptContext(context, world_id);
 }
 
+void LocalFrameClientImpl::DidInstallConditionalFeatures(
+    v8::Local<v8::Context> context,
+    int32_t world_id) {
+  if (web_frame_->Client())
+    web_frame_->Client()->DidInstallConditionalFeatures(context, world_id);
+}
+
 void LocalFrameClientImpl::WillReleaseScriptContext(
     v8::Local<v8::Context> context,
     int32_t world_id) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
index c974fa2f7c7f9c2aa5f075ec4aeb887d0b104453..b4ed9b2fadcfad7676387045b8581eb8d33e89e8 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -80,6 +80,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
 
   void DidCreateScriptContext(v8::Local<v8::Context>,
                               int32_t world_id) override;
+  void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+                                     int32_t world_id) override;
   void WillReleaseScriptContext(v8::Local<v8::Context>,
                                 int32_t world_id) override;
 
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index ba841a41c1387c2cac3578bc01524b0a1868f74d..d2ce9ae524025cc06028b4ca80d04c580dc29b44 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -366,6 +366,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
 
   void DidCreateScriptContext(v8::Local<v8::Context>,
                               int32_t world_id) override {}
+  void DidInstallConditionalFeatures(v8::Local<v8::Context>,
+                                     int32_t world_id) override {}
   void WillReleaseScriptContext(v8::Local<v8::Context>,
                                 int32_t world_id) override {}
   bool AllowScriptExtensions() override { return false; }
