summaryrefslogtreecommitdiff
path: root/chromium/components/js_injection/browser
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/components/js_injection/browser
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/js_injection/browser')
-rw-r--r--chromium/components/js_injection/browser/BUILD.gn27
-rw-r--r--chromium/components/js_injection/browser/js_communication_host.cc227
-rw-r--r--chromium/components/js_injection/browser/js_communication_host.h110
-rw-r--r--chromium/components/js_injection/browser/js_to_browser_messaging.cc129
-rw-r--r--chromium/components/js_injection/browser/js_to_browser_messaging.h66
-rw-r--r--chromium/components/js_injection/browser/web_message.cc13
-rw-r--r--chromium/components/js_injection/browser/web_message.h26
-rw-r--r--chromium/components/js_injection/browser/web_message_host.h24
-rw-r--r--chromium/components/js_injection/browser/web_message_host_factory.h34
-rw-r--r--chromium/components/js_injection/browser/web_message_reply_proxy.h25
10 files changed, 681 insertions, 0 deletions
diff --git a/chromium/components/js_injection/browser/BUILD.gn b/chromium/components/js_injection/browser/BUILD.gn
new file mode 100644
index 00000000000..f2b8216f66a
--- /dev/null
+++ b/chromium/components/js_injection/browser/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("browser") {
+ sources = [
+ "js_communication_host.cc",
+ "js_communication_host.h",
+ "js_to_browser_messaging.cc",
+ "js_to_browser_messaging.h",
+ "web_message.cc",
+ "web_message.h",
+ "web_message_host.h",
+ "web_message_host_factory.h",
+ "web_message_reply_proxy.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/js_injection/common",
+ "//components/js_injection/common:common_mojom",
+ "//content/public/browser",
+ "//mojo/public/cpp/bindings",
+ "//third_party/blink/public/common",
+ "//url",
+ ]
+}
diff --git a/chromium/components/js_injection/browser/js_communication_host.cc b/chromium/components/js_injection/browser/js_communication_host.cc
new file mode 100644
index 00000000000..f4115b3aa86
--- /dev/null
+++ b/chromium/components/js_injection/browser/js_communication_host.cc
@@ -0,0 +1,227 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/js_injection/browser/js_communication_host.h"
+
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/js_injection/browser/js_to_browser_messaging.h"
+#include "components/js_injection/browser/web_message_host.h"
+#include "components/js_injection/browser/web_message_host_factory.h"
+#include "components/js_injection/common/origin_matcher.h"
+#include "components/js_injection/common/origin_matcher_mojom_traits.h"
+#include "content/public/browser/web_contents.h"
+#include "mojo/public/cpp/bindings/pending_associated_remote.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+
+namespace js_injection {
+namespace {
+
+std::string ConvertToNativeAllowedOriginRulesWithSanityCheck(
+ const std::vector<std::string>& allowed_origin_rules_strings,
+ OriginMatcher& allowed_origin_rules) {
+ for (auto& rule : allowed_origin_rules_strings) {
+ if (!allowed_origin_rules.AddRuleFromString(rule))
+ return "allowedOriginRules " + rule + " is invalid";
+ }
+ return std::string();
+}
+
+} // namespace
+
+struct JsObject {
+ JsObject(const base::string16& name,
+ OriginMatcher allowed_origin_rules,
+ std::unique_ptr<WebMessageHostFactory> factory)
+ : name(std::move(name)),
+ allowed_origin_rules(std::move(allowed_origin_rules)),
+ factory(std::move(factory)) {}
+ JsObject(JsObject&& other) = delete;
+ JsObject& operator=(JsObject&& other) = delete;
+ ~JsObject() = default;
+
+ base::string16 name;
+ OriginMatcher allowed_origin_rules;
+ std::unique_ptr<WebMessageHostFactory> factory;
+};
+
+struct DocumentStartJavaScript {
+ DocumentStartJavaScript(base::string16 script,
+ OriginMatcher allowed_origin_rules,
+ int32_t script_id)
+ : script_(std::move(script)),
+ allowed_origin_rules_(allowed_origin_rules),
+ script_id_(script_id) {}
+
+ DocumentStartJavaScript(DocumentStartJavaScript&) = delete;
+ DocumentStartJavaScript& operator=(DocumentStartJavaScript&) = delete;
+ DocumentStartJavaScript(DocumentStartJavaScript&&) = default;
+ DocumentStartJavaScript& operator=(DocumentStartJavaScript&&) = default;
+
+ base::string16 script_;
+ OriginMatcher allowed_origin_rules_;
+ int32_t script_id_;
+};
+
+JsCommunicationHost::AddScriptResult::AddScriptResult() = default;
+JsCommunicationHost::AddScriptResult::AddScriptResult(
+ const JsCommunicationHost::AddScriptResult&) = default;
+JsCommunicationHost::AddScriptResult&
+JsCommunicationHost::AddScriptResult::operator=(
+ const JsCommunicationHost::AddScriptResult&) = default;
+JsCommunicationHost::AddScriptResult::~AddScriptResult() = default;
+
+JsCommunicationHost::JsCommunicationHost(content::WebContents* web_contents)
+ : content::WebContentsObserver(web_contents) {}
+
+JsCommunicationHost::~JsCommunicationHost() = default;
+
+JsCommunicationHost::AddScriptResult
+JsCommunicationHost::AddDocumentStartJavaScript(
+ const base::string16& script,
+ const std::vector<std::string>& allowed_origin_rules) {
+ OriginMatcher origin_matcher;
+ std::string error_message = ConvertToNativeAllowedOriginRulesWithSanityCheck(
+ allowed_origin_rules, origin_matcher);
+ AddScriptResult result;
+ if (!error_message.empty()) {
+ result.error_message = std::move(error_message);
+ return result;
+ }
+
+ scripts_.emplace_back(script, origin_matcher, next_script_id_++);
+
+ web_contents()->ForEachFrame(base::BindRepeating(
+ &JsCommunicationHost::NotifyFrameForAddDocumentStartJavaScript,
+ base::Unretained(this), &*scripts_.rbegin()));
+ result.script_id = scripts_.rbegin()->script_id_;
+ return result;
+}
+
+bool JsCommunicationHost::RemoveDocumentStartJavaScript(int script_id) {
+ for (auto it = scripts_.begin(); it != scripts_.end(); ++it) {
+ if (it->script_id_ == script_id) {
+ scripts_.erase(it);
+ web_contents()->ForEachFrame(base::BindRepeating(
+ &JsCommunicationHost::NotifyFrameForRemoveDocumentStartJavaScript,
+ base::Unretained(this), script_id));
+ return true;
+ }
+ }
+ return false;
+}
+
+base::string16 JsCommunicationHost::AddWebMessageHostFactory(
+ std::unique_ptr<WebMessageHostFactory> factory,
+ const base::string16& js_object_name,
+ const std::vector<std::string>& allowed_origin_rules) {
+ OriginMatcher origin_matcher;
+ std::string error_message = ConvertToNativeAllowedOriginRulesWithSanityCheck(
+ allowed_origin_rules, origin_matcher);
+ if (!error_message.empty())
+ return base::UTF8ToUTF16(error_message);
+
+ for (const auto& js_object : js_objects_) {
+ if (js_object->name == js_object_name) {
+ return base::ASCIIToUTF16("jsObjectName ") + js_object->name +
+ base::ASCIIToUTF16(" was already added.");
+ }
+ }
+
+ js_objects_.push_back(std::make_unique<JsObject>(
+ js_object_name, origin_matcher, std::move(factory)));
+
+ web_contents()->ForEachFrame(base::BindRepeating(
+ &JsCommunicationHost::NotifyFrameForWebMessageListener,
+ base::Unretained(this)));
+ return base::string16();
+}
+
+void JsCommunicationHost::RemoveWebMessageHostFactory(
+ const base::string16& js_object_name) {
+ for (auto iterator = js_objects_.begin(); iterator != js_objects_.end();
+ ++iterator) {
+ if ((*iterator)->name == js_object_name) {
+ js_objects_.erase(iterator);
+ web_contents()->ForEachFrame(base::BindRepeating(
+ &JsCommunicationHost::NotifyFrameForWebMessageListener,
+ base::Unretained(this)));
+ break;
+ }
+ }
+}
+
+std::vector<JsCommunicationHost::RegisteredFactory>
+JsCommunicationHost::GetWebMessageHostFactories() {
+ const size_t num_objects = js_objects_.size();
+ std::vector<RegisteredFactory> factories(num_objects);
+ for (size_t i = 0; i < num_objects; ++i) {
+ factories[i].js_name = js_objects_[i]->name;
+ factories[i].allowed_origin_rules = js_objects_[i]->allowed_origin_rules;
+ factories[i].factory = js_objects_[i]->factory.get();
+ }
+ return factories;
+}
+
+void JsCommunicationHost::RenderFrameCreated(
+ content::RenderFrameHost* render_frame_host) {
+ NotifyFrameForWebMessageListener(render_frame_host);
+ NotifyFrameForAllDocumentStartJavaScripts(render_frame_host);
+}
+
+void JsCommunicationHost::RenderFrameDeleted(
+ content::RenderFrameHost* render_frame_host) {
+ js_to_browser_messagings_.erase(render_frame_host);
+}
+
+void JsCommunicationHost::NotifyFrameForAllDocumentStartJavaScripts(
+ content::RenderFrameHost* render_frame_host) {
+ for (const auto& script : scripts_) {
+ NotifyFrameForAddDocumentStartJavaScript(&script, render_frame_host);
+ }
+}
+
+void JsCommunicationHost::NotifyFrameForWebMessageListener(
+ content::RenderFrameHost* render_frame_host) {
+ mojo::AssociatedRemote<mojom::JsCommunication> configurator_remote;
+ render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
+ &configurator_remote);
+ std::vector<mojom::JsObjectPtr> js_objects;
+ js_objects.reserve(js_objects_.size());
+ for (const auto& js_object : js_objects_) {
+ mojo::PendingAssociatedRemote<mojom::JsToBrowserMessaging> pending_remote;
+ js_to_browser_messagings_[render_frame_host].emplace_back(
+ std::make_unique<JsToBrowserMessaging>(
+ render_frame_host,
+ pending_remote.InitWithNewEndpointAndPassReceiver(),
+ js_object->factory.get(), js_object->allowed_origin_rules));
+ js_objects.push_back(mojom::JsObject::New(js_object->name,
+ std::move(pending_remote),
+ js_object->allowed_origin_rules));
+ }
+ configurator_remote->SetJsObjects(std::move(js_objects));
+}
+
+void JsCommunicationHost::NotifyFrameForAddDocumentStartJavaScript(
+ const DocumentStartJavaScript* script,
+ content::RenderFrameHost* render_frame_host) {
+ DCHECK(script);
+ mojo::AssociatedRemote<mojom::JsCommunication> configurator_remote;
+ render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
+ &configurator_remote);
+ configurator_remote->AddDocumentStartScript(
+ mojom::DocumentStartJavaScript::New(script->script_id_, script->script_,
+ script->allowed_origin_rules_));
+}
+
+void JsCommunicationHost::NotifyFrameForRemoveDocumentStartJavaScript(
+ int32_t script_id,
+ content::RenderFrameHost* render_frame_host) {
+ mojo::AssociatedRemote<mojom::JsCommunication> configurator_remote;
+ render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
+ &configurator_remote);
+ configurator_remote->RemoveDocumentStartScript(script_id);
+}
+
+} // namespace js_injection
diff --git a/chromium/components/js_injection/browser/js_communication_host.h b/chromium/components/js_injection/browser/js_communication_host.h
new file mode 100644
index 00000000000..3cd096d163e
--- /dev/null
+++ b/chromium/components/js_injection/browser/js_communication_host.h
@@ -0,0 +1,110 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_JS_INJECTION_BROWSER_JS_COMMUNICATION_HOST_H_
+#define COMPONENTS_JS_INJECTION_BROWSER_JS_COMMUNICATION_HOST_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/optional.h"
+#include "base/strings/string16.h"
+#include "components/js_injection/common/interfaces.mojom.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace content {
+class RenderFrameHost;
+} // namespace content
+
+namespace js_injection {
+
+class OriginMatcher;
+struct DocumentStartJavaScript;
+struct JsObject;
+class JsToBrowserMessaging;
+class WebMessageHostFactory;
+
+// This class is 1:1 with WebContents, when AddWebMessageListener() is called,
+// it stores the information in this class and send them to renderer side
+// JsCommunication if there is any. When RenderFrameCreated() gets called, it
+// needs to configure that new RenderFrame with the information stores in this
+// class.
+class JsCommunicationHost : public content::WebContentsObserver {
+ public:
+ explicit JsCommunicationHost(content::WebContents* web_contents);
+ ~JsCommunicationHost() override;
+
+ // Captures the result of adding script. There are two possibilities when
+ // adding script: there was an error, in which case |error_message| is set,
+ // otherwise the add was successful and |script_id| is set.
+ struct AddScriptResult {
+ AddScriptResult();
+ AddScriptResult(const AddScriptResult&);
+ AddScriptResult& operator=(const AddScriptResult&);
+ ~AddScriptResult();
+
+ base::Optional<std::string> error_message;
+ base::Optional<int> script_id;
+ };
+
+ // Native side AddDocumentStartJavaScript, returns an error message if the
+ // parameters didn't pass necessary checks.
+ AddScriptResult AddDocumentStartJavaScript(
+ const base::string16& script,
+ const std::vector<std::string>& allowed_origin_rules);
+
+ bool RemoveDocumentStartJavaScript(int script_id);
+
+ // Adds a new WebMessageHostFactory. For any urls that match
+ // |allowed_origin_rules|, |js_object_name| is registered as a JS object that
+ // can be used by script on the page to send and receive messages. Returns
+ // an empty string on success. On failure, the return string gives the error
+ // message.
+ base::string16 AddWebMessageHostFactory(
+ std::unique_ptr<WebMessageHostFactory> factory,
+ const base::string16& js_object_name,
+ const std::vector<std::string>& allowed_origin_rules);
+
+ // Returns the factory previously registered under the specified name.
+ void RemoveWebMessageHostFactory(const base::string16& js_object_name);
+
+ struct RegisteredFactory {
+ base::string16 js_name;
+ OriginMatcher allowed_origin_rules;
+ WebMessageHostFactory* factory = nullptr;
+ };
+
+ // Returns the registered factories.
+ std::vector<RegisteredFactory> GetWebMessageHostFactories();
+
+ // content::WebContentsObserver implementations
+ void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
+ void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
+
+ private:
+ void NotifyFrameForWebMessageListener(
+ content::RenderFrameHost* render_frame_host);
+ void NotifyFrameForAllDocumentStartJavaScripts(
+ content::RenderFrameHost* render_frame_host);
+ void NotifyFrameForAddDocumentStartJavaScript(
+ const DocumentStartJavaScript* script,
+ content::RenderFrameHost* render_frame_host);
+
+ void NotifyFrameForRemoveDocumentStartJavaScript(
+ int32_t script_id,
+ content::RenderFrameHost* render_frame_host);
+
+ int32_t next_script_id_ = 0;
+ std::vector<DocumentStartJavaScript> scripts_;
+ std::vector<std::unique_ptr<JsObject>> js_objects_;
+ std::map<content::RenderFrameHost*,
+ std::vector<std::unique_ptr<JsToBrowserMessaging>>>
+ js_to_browser_messagings_;
+
+ DISALLOW_COPY_AND_ASSIGN(JsCommunicationHost);
+};
+
+} // namespace js_injection
+
+#endif // COMPONENTS_JS_INJECTION_BROWSER_JS_COMMUNICATION_HOST_H_
diff --git a/chromium/components/js_injection/browser/js_to_browser_messaging.cc b/chromium/components/js_injection/browser/js_to_browser_messaging.cc
new file mode 100644
index 00000000000..e7ce36d7fd0
--- /dev/null
+++ b/chromium/components/js_injection/browser/js_to_browser_messaging.cc
@@ -0,0 +1,129 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/js_injection/browser/js_to_browser_messaging.h"
+
+#include "base/stl_util.h"
+#include "components/js_injection/browser/web_message.h"
+#include "components/js_injection/browser/web_message_host.h"
+#include "components/js_injection/browser/web_message_host_factory.h"
+#include "components/js_injection/browser/web_message_reply_proxy.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/messaging/message_port_descriptor.h"
+#include "url/origin.h"
+#include "url/url_util.h"
+
+namespace js_injection {
+namespace {
+
+// We want to pass a string "null" for local file schemes, to make it
+// consistent to the Blink side SecurityOrigin serialization. When both
+// setAllow{File,Universal}AccessFromFileURLs are false, Blink::SecurityOrigin
+// will be serialized as string "null" for local file schemes, but when
+// setAllowFileAccessFromFileURLs is true, Blink::SecurityOrigin will be
+// serialized as the scheme, which will be inconsistentt to this place. In
+// this case we want to let developer to know that local files are not safe,
+// so we still pass "null".
+std::string GetOriginString(const url::Origin& source_origin) {
+ return base::Contains(url::GetLocalSchemes(), source_origin.scheme())
+ ? "null"
+ : source_origin.Serialize();
+}
+
+} // namespace
+
+class JsToBrowserMessaging::ReplyProxyImpl : public WebMessageReplyProxy {
+ public:
+ explicit ReplyProxyImpl(
+ mojo::PendingAssociatedRemote<mojom::BrowserToJsMessaging>
+ java_to_js_messaging)
+ : java_to_js_messaging_(std::move(java_to_js_messaging)) {}
+ ReplyProxyImpl(const ReplyProxyImpl&) = delete;
+ ReplyProxyImpl& operator=(const ReplyProxyImpl&) = delete;
+ ~ReplyProxyImpl() override = default;
+
+ // WebMessageReplyProxy:
+ void PostMessage(std::unique_ptr<WebMessage> message) override {
+ java_to_js_messaging_->OnPostMessage(message->message);
+ }
+
+ private:
+ mojo::AssociatedRemote<mojom::BrowserToJsMessaging> java_to_js_messaging_;
+};
+
+JsToBrowserMessaging::JsToBrowserMessaging(
+ content::RenderFrameHost* render_frame_host,
+ mojo::PendingAssociatedReceiver<mojom::JsToBrowserMessaging> receiver,
+ WebMessageHostFactory* factory,
+ const OriginMatcher& origin_matcher)
+ : render_frame_host_(render_frame_host),
+ connection_factory_(factory),
+ origin_matcher_(origin_matcher) {
+ receiver_.Bind(std::move(receiver));
+}
+
+JsToBrowserMessaging::~JsToBrowserMessaging() = default;
+
+void JsToBrowserMessaging::PostMessage(
+ const base::string16& message,
+ std::vector<blink::MessagePortDescriptor> ports) {
+ DCHECK(render_frame_host_);
+
+ content::WebContents* web_contents =
+ content::WebContents::FromRenderFrameHost(render_frame_host_);
+
+ if (!web_contents)
+ return;
+
+ // |source_origin| has no race with this PostMessage call, because of
+ // associated mojo channel, the committed origin message and PostMessage are
+ // in sequence.
+ const url::Origin source_origin =
+ render_frame_host_->GetLastCommittedOrigin();
+
+ if (!origin_matcher_.Matches(source_origin))
+ return;
+
+ // SetBrowserToJsMessaging must be called before this.
+ DCHECK(reply_proxy_);
+
+ if (!host_) {
+ const std::string origin_string = GetOriginString(source_origin);
+ const bool is_main_frame =
+ web_contents->GetMainFrame() == render_frame_host_;
+
+ host_ = connection_factory_->CreateHost(origin_string, is_main_frame,
+ reply_proxy_.get());
+#if DCHECK_IS_ON()
+ origin_string_ = origin_string;
+ is_main_frame_ = is_main_frame;
+#endif
+ if (!host_)
+ return;
+ }
+ // The origin and whether this is the main frame should not change once
+ // PostMessage() has been received.
+#if DCHECK_IS_ON()
+ DCHECK_EQ(GetOriginString(source_origin), origin_string_);
+ DCHECK_EQ(is_main_frame_, web_contents->GetMainFrame() == render_frame_host_);
+#endif
+ std::unique_ptr<WebMessage> web_message = std::make_unique<WebMessage>();
+ web_message->message = message;
+ web_message->ports = std::move(ports);
+ host_->OnPostMessage(std::move(web_message));
+}
+
+void JsToBrowserMessaging::SetBrowserToJsMessaging(
+ mojo::PendingAssociatedRemote<mojom::BrowserToJsMessaging>
+ java_to_js_messaging) {
+ // A RenderFrame may inject JsToBrowserMessaging in the JavaScript context
+ // more than once because of reusing of RenderFrame.
+ host_.reset();
+ reply_proxy_ =
+ std::make_unique<ReplyProxyImpl>(std::move(java_to_js_messaging));
+}
+
+} // namespace js_injection
diff --git a/chromium/components/js_injection/browser/js_to_browser_messaging.h b/chromium/components/js_injection/browser/js_to_browser_messaging.h
new file mode 100644
index 00000000000..716905182f1
--- /dev/null
+++ b/chromium/components/js_injection/browser/js_to_browser_messaging.h
@@ -0,0 +1,66 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_JS_INJECTION_BROWSER_JS_TO_BROWSER_MESSAGING_H_
+#define COMPONENTS_JS_INJECTION_BROWSER_JS_TO_BROWSER_MESSAGING_H_
+
+#include <vector>
+
+#include "base/check.h"
+#include "base/strings/string16.h"
+#include "components/js_injection/common/interfaces.mojom.h"
+#include "components/js_injection/common/origin_matcher.h"
+#include "mojo/public/cpp/bindings/associated_receiver_set.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "mojo/public/cpp/bindings/pending_associated_remote.h"
+#include "third_party/blink/public/common/messaging/message_port_descriptor.h"
+
+namespace content {
+class RenderFrameHost;
+}
+
+namespace js_injection {
+
+class WebMessageHost;
+class WebMessageHostFactory;
+
+// Implementation of mojo::JsToBrowserMessaging interface. Receives
+// PostMessage() call from renderer JsBinding.
+class JsToBrowserMessaging : public mojom::JsToBrowserMessaging {
+ public:
+ JsToBrowserMessaging(
+ content::RenderFrameHost* rfh,
+ mojo::PendingAssociatedReceiver<mojom::JsToBrowserMessaging> receiver,
+ WebMessageHostFactory* factory,
+ const OriginMatcher& origin_matcher);
+ ~JsToBrowserMessaging() override;
+
+ // mojom::JsToBrowserMessaging implementation.
+ void PostMessage(const base::string16& message,
+ std::vector<blink::MessagePortDescriptor> ports) override;
+ void SetBrowserToJsMessaging(
+ mojo::PendingAssociatedRemote<mojom::BrowserToJsMessaging>
+ java_to_js_messaging) override;
+
+ private:
+ class ReplyProxyImpl;
+
+ content::RenderFrameHost* render_frame_host_;
+ std::unique_ptr<ReplyProxyImpl> reply_proxy_;
+ WebMessageHostFactory* connection_factory_;
+ OriginMatcher origin_matcher_;
+ mojo::AssociatedReceiver<mojom::JsToBrowserMessaging> receiver_{this};
+ std::unique_ptr<WebMessageHost> host_;
+#if DCHECK_IS_ON()
+ std::string origin_string_;
+ bool is_main_frame_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(JsToBrowserMessaging);
+};
+
+} // namespace js_injection
+
+#endif // COMPONENTS_JS_INJECTION_BROWSER_JS_TO_BROWSER_MESSAGING_H_
diff --git a/chromium/components/js_injection/browser/web_message.cc b/chromium/components/js_injection/browser/web_message.cc
new file mode 100644
index 00000000000..34e8e64e08f
--- /dev/null
+++ b/chromium/components/js_injection/browser/web_message.cc
@@ -0,0 +1,13 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/js_injection/browser/web_message.h"
+
+namespace js_injection {
+
+WebMessage::WebMessage() = default;
+
+WebMessage::~WebMessage() = default;
+
+} // namespace js_injection
diff --git a/chromium/components/js_injection/browser/web_message.h b/chromium/components/js_injection/browser/web_message.h
new file mode 100644
index 00000000000..1061cc82a76
--- /dev/null
+++ b/chromium/components/js_injection/browser/web_message.h
@@ -0,0 +1,26 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_H_
+#define COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_H_
+
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "third_party/blink/public/common/messaging/message_port_descriptor.h"
+
+namespace js_injection {
+
+// Represents a message to or from the page.
+struct WebMessage {
+ WebMessage();
+ ~WebMessage();
+
+ base::string16 message;
+ std::vector<blink::MessagePortDescriptor> ports;
+};
+
+} // namespace js_injection
+
+#endif // COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_H_
diff --git a/chromium/components/js_injection/browser/web_message_host.h b/chromium/components/js_injection/browser/web_message_host.h
new file mode 100644
index 00000000000..8fa339893fa
--- /dev/null
+++ b/chromium/components/js_injection/browser/web_message_host.h
@@ -0,0 +1,24 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_HOST_H_
+#define COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_HOST_H_
+
+#include <memory>
+
+namespace js_injection {
+
+struct WebMessage;
+
+// Represents the browser side of a WebMessage channel.
+class WebMessageHost {
+ public:
+ virtual ~WebMessageHost() = default;
+
+ virtual void OnPostMessage(std::unique_ptr<WebMessage> message) = 0;
+};
+
+} // namespace js_injection
+
+#endif // COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_HOST_H_
diff --git a/chromium/components/js_injection/browser/web_message_host_factory.h b/chromium/components/js_injection/browser/web_message_host_factory.h
new file mode 100644
index 00000000000..aeaaf772bc2
--- /dev/null
+++ b/chromium/components/js_injection/browser/web_message_host_factory.h
@@ -0,0 +1,34 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_HOST_FACTORY_H_
+#define COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_HOST_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+namespace js_injection {
+
+class WebMessageHost;
+class WebMessageReplyProxy;
+
+// Creates a WebMessageHost in response to a page interacting with the object
+// registered by way of JsCommunicationHost::AddWebMessageHostFactory(). A
+// WebMessageHost is created for every page that matches the parameters of
+// AddWebMessageHostFactory().
+class WebMessageHostFactory {
+ public:
+ virtual ~WebMessageHostFactory() = default;
+
+ // Creates a WebMessageHost for the specified page. |proxy| is valid for
+ // the life of the host and may be used to send messages back to the page.
+ virtual std::unique_ptr<WebMessageHost> CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* proxy) = 0;
+};
+
+} // namespace js_injection
+
+#endif // COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_HOST_FACTORY_H_
diff --git a/chromium/components/js_injection/browser/web_message_reply_proxy.h b/chromium/components/js_injection/browser/web_message_reply_proxy.h
new file mode 100644
index 00000000000..e94171f221f
--- /dev/null
+++ b/chromium/components/js_injection/browser/web_message_reply_proxy.h
@@ -0,0 +1,25 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_REPLY_PROXY_H_
+#define COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_REPLY_PROXY_H_
+
+#include "base/strings/string16.h"
+
+namespace js_injection {
+
+struct WebMessage;
+
+// Used to send messages to the page.
+class WebMessageReplyProxy {
+ public:
+ virtual void PostMessage(std::unique_ptr<WebMessage> message) = 0;
+
+ protected:
+ virtual ~WebMessageReplyProxy() = default;
+};
+
+} // namespace js_injection
+
+#endif // COMPONENTS_JS_INJECTION_BROWSER_WEB_MESSAGE_REPLY_PROXY_H_