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 902d84ad70adc9496f3af989465a99b6f44b077a..3ce043eea32c41130aa59ab8570a05b31fdb4de9 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -146,6 +146,8 @@ class CONTENT_EXPORT RenderFrameObserver
   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 2d7d13fc9f361bc3e4b16e4db008c042f492704a..dc96cd01365491a2384e9d27e384b680c3e86a23 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4692,6 +4692,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 b4e2293651bb0e234aa8119c2afece5faa11a758..37af654883ec39c761cc4fcaab9d22061595d451 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -645,6 +645,8 @@ class CONTENT_EXPORT RenderFrameImpl
   void DidObserveLayoutShift(double score, bool after_input_or_scroll) 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 2bb6e24cf5b83b8f6cf523d648307608ede1b538..1fe4df62e66fd10267e72d91176529fccabe83aa 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -645,6 +645,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 50352340def787f5c6a382b622c37905ee79302c..97a79a4bfbcdd63ec01b201571fdccf2701ae40b 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
@@ -215,6 +215,7 @@ void LocalWindowProxy::Initialize() {
   }
 
   InstallConditionalFeatures();
+  GetFrame()->Client()->DidInstallConditionalFeatures(context, world_->GetWorldId());
 
   if (World().IsMainWorld()) {
     probe::DidCreateMainWorldContext(GetFrame());
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 69c46beec12f4b5abf530c2fb836d6185ee049f9..e9c0f5c0930929a5f62a34943f7619a368c551e1 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -306,6 +306,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 0cee9fc9642c4a2eac51cc7b57124d9772411b8c..4a2bd06f9f254969419d3ec00a59466f8278814c 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
@@ -293,6 +293,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 a70c4a78a3dc740446b06a44a448760015bc9c24..be9872bdd93755bbf9e2be684cfd37efe9f4a5a8 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
@@ -84,6 +84,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 ec2a8f7d2fc14702686be73e663dfb9632b5b4de..5f3fdd7d03b81c7bf59528af96c550d9f2307835 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -412,6 +412,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; }
