summaryrefslogtreecommitdiff
path: root/chromium/weblayer/browser/js_communication
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/weblayer/browser/js_communication')
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_browsertest.cc112
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.cc25
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.h38
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc70
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.h38
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc52
-rw-r--r--chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.h47
7 files changed, 382 insertions, 0 deletions
diff --git a/chromium/weblayer/browser/js_communication/web_message_browsertest.cc b/chromium/weblayer/browser/js_communication/web_message_browsertest.cc
new file mode 100644
index 00000000000..8d147c10be7
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_browsertest.cc
@@ -0,0 +1,112 @@
+// 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 "weblayer/public/js_communication/web_message.h"
+
+#include "base/callback.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "weblayer/public/js_communication/web_message.h"
+#include "weblayer/public/js_communication/web_message_host.h"
+#include "weblayer/public/js_communication/web_message_host_factory.h"
+#include "weblayer/public/js_communication/web_message_reply_proxy.h"
+#include "weblayer/public/navigation.h"
+#include "weblayer/public/navigation_controller.h"
+#include "weblayer/public/tab.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+namespace weblayer {
+
+namespace {
+
+class WebMessageHostImpl;
+WebMessageHostImpl* current_connection = nullptr;
+
+// WebMessageHost implementation that records contents of OnPostMessage().
+class WebMessageHostImpl : public WebMessageHost {
+ public:
+ WebMessageHostImpl(base::RepeatingClosure quit_closure,
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* proxy)
+ : quit_closure_(quit_closure), proxy_(proxy) {
+ current_connection = this;
+ }
+ ~WebMessageHostImpl() override {
+ if (current_connection == this)
+ current_connection = nullptr;
+ }
+
+ std::vector<base::string16>& messages() { return messages_; }
+
+ // WebMessageHost:
+ void OnPostMessage(std::unique_ptr<WebMessage> message) override {
+ messages_.push_back(std::move(message->message));
+ if (++call_count_ == 1) {
+ // First time called, send a message to the page.
+ std::unique_ptr<WebMessage> m2 = std::make_unique<WebMessage>();
+ m2->message = base::ASCIIToUTF16("from c++");
+ proxy_->PostMessage(std::move(m2));
+ } else {
+ // On subsequent calls quit.
+ quit_closure_.Run();
+ }
+ }
+
+ private:
+ int call_count_ = 0;
+ base::RepeatingClosure quit_closure_;
+ WebMessageReplyProxy* proxy_;
+ std::vector<base::string16> messages_;
+};
+
+// WebMessageHostFactory implementation that creates WebMessageHostImp.
+class WebMessageHostFactoryImpl : public WebMessageHostFactory {
+ public:
+ explicit WebMessageHostFactoryImpl(base::RepeatingClosure quit_closure)
+ : quit_closure_(quit_closure) {}
+ ~WebMessageHostFactoryImpl() override = default;
+
+ // WebMessageHostFactory:
+ std::unique_ptr<WebMessageHost> CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* proxy) override {
+ return std::make_unique<WebMessageHostImpl>(quit_closure_, origin_string,
+ is_main_frame, proxy);
+ }
+
+ private:
+ base::RepeatingClosure quit_closure_;
+};
+
+} // namespace
+
+using WebMessageTest = WebLayerBrowserTest;
+
+IN_PROC_BROWSER_TEST_F(WebMessageTest, SendAndReceive) {
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ base::RunLoop run_loop;
+ shell()->tab()->AddWebMessageHostFactory(
+ std::make_unique<WebMessageHostFactoryImpl>(run_loop.QuitClosure()),
+ base::ASCIIToUTF16("x"), {"*"});
+
+ // web_message_test.html posts a message immediately.
+ shell()->tab()->GetNavigationController()->Navigate(
+ embedded_test_server()->GetURL("/web_message_test.html"));
+ run_loop.Run();
+
+ // There should be two messages. The one from the page, and the ack triggered
+ // when WebMessageHostImpl calls PostMessage().
+ ASSERT_TRUE(current_connection);
+ ASSERT_EQ(2u, current_connection->messages().size());
+ EXPECT_EQ(base::ASCIIToUTF16("from page"), current_connection->messages()[0]);
+ EXPECT_EQ(base::ASCIIToUTF16("bouncing from c++"),
+ current_connection->messages()[1]);
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.cc b/chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.cc
new file mode 100644
index 00000000000..e634cd95d78
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.cc
@@ -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.
+
+#include "weblayer/browser/js_communication/web_message_host_factory_proxy.h"
+
+#include "weblayer/browser/js_communication/web_message_reply_proxy_impl.h"
+
+namespace weblayer {
+
+WebMessageHostFactoryProxy::WebMessageHostFactoryProxy(
+ const base::android::JavaParamRef<jobject>& client)
+ : client_(client) {}
+
+WebMessageHostFactoryProxy::~WebMessageHostFactoryProxy() = default;
+
+std::unique_ptr<WebMessageHost> WebMessageHostFactoryProxy::CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* proxy) {
+ return std::make_unique<WebMessageReplyProxyImpl>(
+ ++next_id_, client_, origin_string, is_main_frame, proxy);
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.h b/chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.h
new file mode 100644
index 00000000000..93e5d55d71e
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_host_factory_proxy.h
@@ -0,0 +1,38 @@
+// 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 WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_PROXY_H_
+#define WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_PROXY_H_
+
+#include "base/android/scoped_java_ref.h"
+#include "weblayer/public/js_communication/web_message_host_factory.h"
+
+namespace weblayer {
+
+// TabImpl, on android, creates a WebMessageHostFactoryProxy for every call
+// to RegisterWebMessageCallback(). This is used to delegate the calls back to
+// the Java side.
+class WebMessageHostFactoryProxy : public WebMessageHostFactory {
+ public:
+ explicit WebMessageHostFactoryProxy(
+ const base::android::JavaParamRef<jobject>& client);
+ WebMessageHostFactoryProxy(const WebMessageHostFactoryProxy&) = delete;
+ WebMessageHostFactoryProxy& operator=(const WebMessageHostFactoryProxy&) =
+ delete;
+ ~WebMessageHostFactoryProxy() override;
+
+ // WebMessageHostFactory:
+ std::unique_ptr<WebMessageHost> CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* proxy) override;
+
+ private:
+ base::android::ScopedJavaGlobalRef<jobject> client_;
+ int next_id_ = 0;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_PROXY_H_
diff --git a/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc b/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc
new file mode 100644
index 00000000000..7a6088f540b
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc
@@ -0,0 +1,70 @@
+// 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 "weblayer/browser/js_communication/web_message_host_factory_wrapper.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_reply_proxy.h"
+#include "weblayer/public/js_communication/web_message.h"
+#include "weblayer/public/js_communication/web_message_host.h"
+#include "weblayer/public/js_communication/web_message_host_factory.h"
+#include "weblayer/public/js_communication/web_message_reply_proxy.h"
+
+namespace weblayer {
+namespace {
+
+// An implementation of js_injection::WebMessageHost that delegates to the
+// corresponding WebLayer type. This also serves as the WebMessageReplyProxy
+// implementation, which forwards to the js_injection implementation.
+class WebMessageHostWrapper : public js_injection::WebMessageHost,
+ public WebMessageReplyProxy {
+ public:
+ WebMessageHostWrapper(weblayer::WebMessageHostFactory* factory,
+ const std::string& origin_string,
+ bool is_main_frame,
+ js_injection::WebMessageReplyProxy* proxy)
+ : proxy_(proxy),
+ connection_(factory->CreateHost(origin_string, is_main_frame, this)) {}
+
+ // js_injection::WebMessageHost:
+ void OnPostMessage(
+ std::unique_ptr<js_injection::WebMessage> message) override {
+ std::unique_ptr<WebMessage> m = std::make_unique<WebMessage>();
+ m->message = message->message;
+ connection_->OnPostMessage(std::move(m));
+ }
+
+ // WebMessageReplyProxy:
+ void PostMessage(std::unique_ptr<WebMessage> message) override {
+ std::unique_ptr<js_injection::WebMessage> w =
+ std::make_unique<js_injection::WebMessage>();
+ w->message = std::move(message->message);
+ proxy_->PostMessage(std::move(w));
+ }
+
+ private:
+ js_injection::WebMessageReplyProxy* proxy_;
+ std::unique_ptr<weblayer::WebMessageHost> connection_;
+};
+
+} // namespace
+
+WebMessageHostFactoryWrapper::WebMessageHostFactoryWrapper(
+ std::unique_ptr<weblayer::WebMessageHostFactory> factory)
+ : factory_(std::move(factory)) {}
+
+WebMessageHostFactoryWrapper::~WebMessageHostFactoryWrapper() = default;
+
+std::unique_ptr<js_injection::WebMessageHost>
+WebMessageHostFactoryWrapper::CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ js_injection::WebMessageReplyProxy* proxy) {
+ auto wrapper = std::make_unique<WebMessageHostWrapper>(
+ factory_.get(), origin_string, is_main_frame, proxy);
+ return wrapper;
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.h b/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.h
new file mode 100644
index 00000000000..1c32d02bfc2
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.h
@@ -0,0 +1,38 @@
+// 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 WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_WRAPPER_H_
+#define WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_WRAPPER_H_
+
+#include "components/js_injection/browser/web_message_host_factory.h"
+
+namespace weblayer {
+
+class WebMessageHostFactory;
+
+// Provides an implementation of js_injection::WebMessageHostFactory that
+// wraps the corresponding WebLayer type.
+class WebMessageHostFactoryWrapper
+ : public js_injection::WebMessageHostFactory {
+ public:
+ explicit WebMessageHostFactoryWrapper(
+ std::unique_ptr<weblayer::WebMessageHostFactory> factory);
+ WebMessageHostFactoryWrapper(const WebMessageHostFactoryWrapper&) = delete;
+ WebMessageHostFactoryWrapper& operator=(const WebMessageHostFactoryWrapper&) =
+ delete;
+ ~WebMessageHostFactoryWrapper() override;
+
+ // js_injection::WebMessageHostFactory:
+ std::unique_ptr<js_injection::WebMessageHost> CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ js_injection::WebMessageReplyProxy* proxy) override;
+
+ private:
+ std::unique_ptr<weblayer::WebMessageHostFactory> factory_;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_WRAPPER_H_
diff --git a/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc b/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc
new file mode 100644
index 00000000000..8172852ecec
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc
@@ -0,0 +1,52 @@
+// 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 "weblayer/browser/js_communication/web_message_reply_proxy_impl.h"
+
+#include <memory>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "weblayer/browser/java/jni/WebMessageReplyProxyImpl_jni.h"
+#include "weblayer/public/js_communication/web_message.h"
+#include "weblayer/public/js_communication/web_message_reply_proxy.h"
+
+namespace weblayer {
+
+WebMessageReplyProxyImpl::WebMessageReplyProxyImpl(
+ int id,
+ base::android::ScopedJavaGlobalRef<jobject> client,
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* reply_proxy)
+ : reply_proxy_(reply_proxy) {
+ auto* env = base::android::AttachCurrentThread();
+ java_object_ = Java_WebMessageReplyProxyImpl_create(
+ env, reinterpret_cast<intptr_t>(this), id, client, is_main_frame,
+ base::android::ConvertUTF8ToJavaString(env, origin_string));
+}
+
+WebMessageReplyProxyImpl::~WebMessageReplyProxyImpl() {
+ Java_WebMessageReplyProxyImpl_onNativeDestroyed(
+ base::android::AttachCurrentThread(), java_object_);
+}
+
+void WebMessageReplyProxyImpl::PostMessage(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jstring>& message_contents) {
+ auto message = std::make_unique<WebMessage>();
+ base::android::ConvertJavaStringToUTF16(env, message_contents,
+ &(message->message));
+ reply_proxy_->PostMessage(std::move(message));
+}
+
+void WebMessageReplyProxyImpl::OnPostMessage(
+ std::unique_ptr<WebMessage> message) {
+ auto* env = base::android::AttachCurrentThread();
+ Java_WebMessageReplyProxyImpl_onPostMessage(
+ env, java_object_,
+ base::android::ConvertUTF16ToJavaString(env, message->message));
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.h b/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.h
new file mode 100644
index 00000000000..dbcfe016f06
--- /dev/null
+++ b/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.h
@@ -0,0 +1,47 @@
+// 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 WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_REPLY_PROXY_IMPL_H_
+#define WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_REPLY_PROXY_IMPL_H_
+
+#include <string>
+
+#include "base/android/scoped_java_ref.h"
+#include "components/js_injection/browser/web_message_host.h"
+#include "weblayer/public/js_communication/web_message_host.h"
+
+namespace weblayer {
+
+class WebMessageReplyProxy;
+
+// Created only on the Android side to support post-message.
+// WebMessageReplyProxyImpl creates the Java WebMessageReplyProxy that is then
+// sent over to the client side for communication with the page.
+class WebMessageReplyProxyImpl : public WebMessageHost {
+ public:
+ WebMessageReplyProxyImpl(int id,
+ base::android::ScopedJavaGlobalRef<jobject> client,
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* reply_proxy);
+ WebMessageReplyProxyImpl(const WebMessageReplyProxyImpl&) = delete;
+ WebMessageReplyProxyImpl& operator=(const WebMessageReplyProxyImpl&) = delete;
+ ~WebMessageReplyProxyImpl() override;
+
+ void PostMessage(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jstring>& message_contents);
+ // WebMessageHost:
+ void OnPostMessage(std::unique_ptr<WebMessage> message) override;
+
+ private:
+ WebMessageReplyProxy* reply_proxy_;
+
+ // The Java WebMessageReplyProxy.
+ base::android::ScopedJavaGlobalRef<jobject> java_object_;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_JS_COMMUNICATION_WEB_MESSAGE_REPLY_PROXY_IMPL_H_