Commit 2846bdea authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

weblayer: wires up post-message API on java side.

BUG=1042771
TEST=WebMessageTest

Change-Id: I36a550146fc15bcb76bbcfaca617ddbf79fa5792
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2250923
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: default avatarClark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#779866}
parent 451f5fa4
......@@ -469,6 +469,10 @@ source_set("weblayer_lib_base") {
"browser/fullscreen_callback_proxy.h",
"browser/infobar_service.cc",
"browser/infobar_service.h",
"browser/js_communication/web_message_host_factory_proxy.cc",
"browser/js_communication/web_message_host_factory_proxy.h",
"browser/js_communication/web_message_reply_proxy_impl.cc",
"browser/js_communication/web_message_reply_proxy_impl.h",
"browser/new_tab_callback_proxy.cc",
"browser/new_tab_callback_proxy.h",
"browser/tab_callback_proxy.cc",
......
......@@ -35,6 +35,7 @@ android_library("weblayer_java_tests") {
"src/org/chromium/weblayer/test/TopControlsTest.java",
"src/org/chromium/weblayer/test/WebLayerLoadingTest.java",
"src/org/chromium/weblayer/test/WebLayerTest.java",
"src/org/chromium/weblayer/test/WebMessageTest.java",
"src/org/chromium/weblayer/test/WebViewCompatibilityTest.java",
]
deps = [
......
// 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.
package org.chromium.weblayer.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
import androidx.test.filters.SmallTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.weblayer.WebMessage;
import org.chromium.weblayer.WebMessageCallback;
import org.chromium.weblayer.WebMessageReplyProxy;
import org.chromium.weblayer.shell.InstrumentationActivity;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Verifies WebMessage related APIs.
*/
@MinWebLayerVersion(85)
@RunWith(WebLayerJUnit4ClassRunner.class)
public class WebMessageTest {
@Rule
public InstrumentationActivityTestRule mActivityTestRule =
new InstrumentationActivityTestRule();
// WebMessageCallback that stores last values supplied to onWebMessageReceived().
private static final class WebMessageCallbackImpl extends WebMessageCallback {
public WebMessageReplyProxy mLastProxy;
public WebMessage mLastMessage;
public CallbackHelper mCallbackHelper;
WebMessageCallbackImpl(CallbackHelper callbackHelper) {
mCallbackHelper = callbackHelper;
}
@Override
public void onWebMessageReceived(WebMessageReplyProxy replyProxy, WebMessage message) {
mLastProxy = replyProxy;
mLastMessage = message;
mCallbackHelper.notifyCalled();
}
public void reset() {
mLastProxy = null;
mLastMessage = null;
}
}
@Test
@SmallTest
public void testPostMessage() throws Exception {
// Load a page with a form.
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank");
assertNotNull(activity);
CallbackHelper callbackHelper = new CallbackHelper();
WebMessageCallbackImpl webMessageCallback = new WebMessageCallbackImpl(callbackHelper);
runOnUiThreadBlocking(() -> {
activity.getTab().registerWebMessageCallback(
webMessageCallback, "x", Arrays.asList("*"));
});
mActivityTestRule.navigateAndWait(
mActivityTestRule.getTestDataURL("web_message_test.html"));
// web_message_test.html posts a message, wait for it.
callbackHelper.waitForCallback(0);
assertNotNull(webMessageCallback.mLastMessage);
assertNotNull(webMessageCallback.mLastProxy);
assertEquals("from page", webMessageCallback.mLastMessage.getContents());
WebMessageReplyProxy lastProxy = webMessageCallback.mLastProxy;
webMessageCallback.reset();
int currentCallCount = callbackHelper.getCallCount();
// Send a message, which the page should ack back.
runOnUiThreadBlocking(() -> { lastProxy.postMessage(new WebMessage("Z")); });
callbackHelper.waitForCallback(currentCallCount);
assertNotNull(webMessageCallback.mLastMessage);
assertEquals("bouncing Z", webMessageCallback.mLastMessage.getContents());
assertEquals(lastProxy, webMessageCallback.mLastProxy);
runOnUiThreadBlocking(() -> { activity.getTab().unregisterWebMessageCallback("x"); });
}
@Test
@SmallTest
public void testBadArguments() throws Exception {
// Load a page with a form.
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank");
assertNotNull(activity);
WebMessageCallback webMessageCallback = new WebMessageCallback() {};
runOnUiThreadBlocking(() -> {
// Invalid JS object name.
try {
activity.getTab().registerWebMessageCallback(
webMessageCallback, "", Arrays.asList("*"));
fail();
} catch (IllegalArgumentException e) {
}
// Origins can not have empty strings.
try {
activity.getTab().registerWebMessageCallback(
webMessageCallback, "x", Arrays.asList(""));
fail();
} catch (IllegalArgumentException e) {
}
// Origins can not be empty.
try {
activity.getTab().registerWebMessageCallback(
webMessageCallback, "x", new ArrayList<String>());
fail();
} catch (IllegalArgumentException e) {
}
// Invalid origin.
try {
activity.getTab().registerWebMessageCallback(
webMessageCallback, "x", Arrays.asList("***"));
fail();
} catch (IllegalArgumentException e) {
}
});
}
}
......@@ -135,6 +135,7 @@ android_library("java") {
"org/chromium/weblayer_private/WebLayerNotificationChannels.java",
"org/chromium/weblayer_private/WebLayerSiteSettingsClient.java",
"org/chromium/weblayer_private/WebLayerTabModalPresenter.java",
"org/chromium/weblayer_private/WebMessageReplyProxyImpl.java",
"org/chromium/weblayer_private/WebShareServiceFactory.java",
"org/chromium/weblayer_private/WebViewCompatibilityHelperImpl.java",
"org/chromium/weblayer_private/metrics/MetricsServiceClient.java",
......@@ -292,6 +293,7 @@ generate_jni("jni") {
"org/chromium/weblayer_private/WebLayerExceptionFilter.java",
"org/chromium/weblayer_private/WebLayerFactoryImpl.java",
"org/chromium/weblayer_private/WebLayerImpl.java",
"org/chromium/weblayer_private/WebMessageReplyProxyImpl.java",
"org/chromium/weblayer_private/WebViewCompatibilityHelperImpl.java",
"org/chromium/weblayer_private/metrics/MetricsServiceClient.java",
"org/chromium/weblayer_private/metrics/UmaUtils.java",
......@@ -384,6 +386,8 @@ android_aidl("aidl") {
"org/chromium/weblayer_private/interfaces/IWebLayer.aidl",
"org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl",
"org/chromium/weblayer_private/interfaces/IWebLayerFactory.aidl",
"org/chromium/weblayer_private/interfaces/IWebMessageCallbackClient.aidl",
"org/chromium/weblayer_private/interfaces/IWebMessageReplyProxy.aidl",
]
}
......
......@@ -57,6 +57,7 @@ import org.chromium.weblayer_private.interfaces.INavigationControllerClient;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.ITab;
import org.chromium.weblayer_private.interfaces.ITabClient;
import org.chromium.weblayer_private.interfaces.IWebMessageCallbackClient;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
......@@ -694,6 +695,32 @@ public final class TabImpl extends ITab.Stub implements LoginPrompt.Observer {
TabImplJni.get().setHttpAuth(mNativeTab, username, password);
}
@Override
public void registerWebMessageCallback(
String jsObjectName, List<String> allowedOrigins, IWebMessageCallbackClient client) {
if (jsObjectName.isEmpty()) {
throw new IllegalArgumentException("JS object name must not be empty");
}
if (allowedOrigins.isEmpty()) {
throw new IllegalArgumentException("At least one origin must be specified");
}
for (String origin : allowedOrigins) {
if (TextUtils.isEmpty(origin)) {
throw new IllegalArgumentException("Origin must not be non-empty");
}
}
String registerError = TabImplJni.get().registerWebMessageCallback(mNativeTab, jsObjectName,
allowedOrigins.toArray(new String[allowedOrigins.size()]), client);
if (!TextUtils.isEmpty(registerError)) {
throw new IllegalArgumentException(registerError);
}
}
@Override
public void unregisterWebMessageCallback(String jsObjectName) {
TabImplJni.get().unregisterWebMessageCallback(mNativeTab, jsObjectName);
}
public void destroy() {
// Ensure that this method isn't called twice.
assert mInterceptNavigationDelegate != null;
......@@ -857,5 +884,8 @@ public final class TabImpl extends ITab.Stub implements LoginPrompt.Observer {
boolean isRendererControllingBrowserControlsOffsets(long nativeTabImpl);
void setHttpAuth(long nativeTabImpl, String username, String password);
void cancelHttpAuth(long nativeTabImpl);
String registerWebMessageCallback(long nativeTabImpl, String jsObjectName,
String[] allowedOrigins, IWebMessageCallbackClient client);
void unregisterWebMessageCallback(long nativeTabImpl, String jsObjectName);
}
}
// 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.
package org.chromium.weblayer_private;
import android.os.RemoteException;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.weblayer_private.interfaces.APICallException;
import org.chromium.weblayer_private.interfaces.IWebMessageCallbackClient;
import org.chromium.weblayer_private.interfaces.IWebMessageReplyProxy;
/**
* WebMessageReplyProxyImpl is responsible for both sending and receiving WebMessages.
*/
@JNINamespace("weblayer")
public final class WebMessageReplyProxyImpl extends IWebMessageReplyProxy.Stub {
private long mNativeWebMessageReplyProxyImpl;
private final IWebMessageCallbackClient mClient;
// Unique id (scoped to the call to Tab.registerWebMessageCallback()) for this proxy. This is
// sent over AIDL.
private final int mId;
private WebMessageReplyProxyImpl(long nativeWebMessageReplyProxyImpl, int id,
IWebMessageCallbackClient client, boolean isMainFrame, String sourceOrigin) {
mNativeWebMessageReplyProxyImpl = nativeWebMessageReplyProxyImpl;
mClient = client;
mId = id;
try {
client.onNewReplyProxy(this, mId, isMainFrame, sourceOrigin);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
@CalledByNative
private static WebMessageReplyProxyImpl create(long nativeWebMessageReplyProxyImpl, int id,
IWebMessageCallbackClient client, boolean isMainFrame, String sourceOrigin) {
return new WebMessageReplyProxyImpl(
nativeWebMessageReplyProxyImpl, id, client, isMainFrame, sourceOrigin);
}
@CalledByNative
private void onNativeDestroyed() {
mNativeWebMessageReplyProxyImpl = 0;
try {
mClient.onReplyProxyDestroyed(mId);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
@CalledByNative
private void onPostMessage(String message) {
try {
mClient.onPostMessage(mId, message);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
@Override
public void postMessage(String message) {
if (mNativeWebMessageReplyProxyImpl != 0) {
WebMessageReplyProxyImplJni.get().postMessage(mNativeWebMessageReplyProxyImpl, message);
}
}
@NativeMethods
interface Natives {
void postMessage(long nativeWebMessageReplyProxyImpl, String message);
}
}
......@@ -4,6 +4,8 @@
package org.chromium.weblayer_private.interfaces;
import java.util.List;
import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient;
import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient;
import org.chromium.weblayer_private.interfaces.IFindInPageCallbackClient;
......@@ -13,6 +15,7 @@ import org.chromium.weblayer_private.interfaces.INavigationController;
import org.chromium.weblayer_private.interfaces.INavigationControllerClient;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.ITabClient;
import org.chromium.weblayer_private.interfaces.IWebMessageCallbackClient;
interface ITab {
void setClient(in ITabClient client) = 0;
......@@ -57,4 +60,8 @@ interface ITab {
// Added in 85
Map getData() = 18;
void registerWebMessageCallback(in String jsObjectName,
in List<String> allowedOrigins,
in IWebMessageCallbackClient client) = 19;
void unregisterWebMessageCallback(in String jsObjectName) = 20;
}
// 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.
package org.chromium.weblayer_private.interfaces;
import org.chromium.weblayer_private.interfaces.IWebMessageReplyProxy;
interface IWebMessageCallbackClient {
void onNewReplyProxy(in IWebMessageReplyProxy proxy,
in int proxyId,
in boolean isMainFrame,
in String sourceOrigin) = 0;
void onPostMessage(in int proxyId, in String message) = 1;
void onReplyProxyDestroyed(in int proxyId) = 2;
}
// 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.
package org.chromium.weblayer_private.interfaces;
interface IWebMessageReplyProxy {
void postMessage(in String message) = 0;
}
// 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
// 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_
// 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
// 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_
......@@ -95,6 +95,7 @@
#include "weblayer/browser/http_auth_handler_impl.h"
#include "weblayer/browser/java/jni/TabImpl_jni.h"
#include "weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h"
#include "weblayer/browser/js_communication/web_message_host_factory_proxy.h"
#include "weblayer/browser/weblayer_factory_impl_android.h"
#include "weblayer/browser/webrtc/media_stream_manager.h"
#endif
......@@ -742,6 +743,28 @@ void TabImpl::CancelHttpAuth(JNIEnv* env) {
auth_handler_->Cancel();
CloseHttpAuthPrompt();
}
base::android::ScopedJavaLocalRef<jstring> TabImpl::RegisterWebMessageCallback(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& js_object_name,
const base::android::JavaParamRef<jobjectArray>& js_origins,
const base::android::JavaParamRef<jobject>& client) {
auto proxy = std::make_unique<WebMessageHostFactoryProxy>(client);
std::vector<std::string> origins;
base::android::AppendJavaStringArrayToStringVector(env, js_origins, &origins);
base::string16 result = AddWebMessageHostFactory(
std::move(proxy),
base::android::ConvertJavaStringToUTF16(env, js_object_name), origins);
return base::android::ConvertUTF16ToJavaString(env, result);
}
void TabImpl::UnregisterWebMessageCallback(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& js_object_name) {
base::string16 name;
base::android::ConvertJavaStringToUTF16(env, js_object_name, &name);
RemoveWebMessageHostFactory(name);
}
#endif // OS_ANDROID
content::WebContents* TabImpl::OpenURLFromTab(
......
......@@ -62,6 +62,7 @@ class HttpAuthHandlerImpl;
#if defined(OS_ANDROID)
class BrowserControlsContainerView;
enum class ControlsVisibilityReason;
class WebMessageHostFactoryProxy;
#endif
class TabImpl : public Tab,
......@@ -181,6 +182,14 @@ class TabImpl : public Tab,
const base::android::JavaParamRef<jstring>& username,
const base::android::JavaParamRef<jstring>& password);
void CancelHttpAuth(JNIEnv* env);
base::android::ScopedJavaLocalRef<jstring> RegisterWebMessageCallback(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& js_object_name,
const base::android::JavaParamRef<jobjectArray>& origins,
const base::android::JavaParamRef<jobject>& client);
void UnregisterWebMessageCallback(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& js_object_name);
#endif
ErrorPageDelegate* error_page_delegate() { return error_page_delegate_; }
......@@ -204,7 +213,7 @@ class TabImpl : public Tab,
base::string16 AddWebMessageHostFactory(
std::unique_ptr<WebMessageHostFactory> factory,
const base::string16& js_object_name,
const std::vector<std::string>& allowed_origin_rules) override;
const std::vector<std::string>& js_origins) override;
void RemoveWebMessageHostFactory(
const base::string16& js_object_name) override;
#if !defined(OS_ANDROID)
......@@ -351,6 +360,9 @@ class TabImpl : public Tab,
// Last value supplied to UpdateBrowserControlsState().
content::BrowserControlsState current_browser_controls_state_ =
content::BROWSER_CONTROLS_STATE_SHOWN;
std::map<std::string, std::unique_ptr<WebMessageHostFactoryProxy>>
js_name_to_proxy_;
#endif
bool is_fullscreen_ = false;
......
......@@ -80,6 +80,9 @@ android_library("java") {
"org/chromium/weblayer/UrlBarOptions.java",
"org/chromium/weblayer/WebLayer.java",
"org/chromium/weblayer/WebLayerFileProvider.java",
"org/chromium/weblayer/WebMessage.java",
"org/chromium/weblayer/WebMessageCallback.java",
"org/chromium/weblayer/WebMessageReplyProxy.java",
"org/chromium/weblayer/WebViewCompatibilityHelper.java",
_version_constants_java_file,
]
......
// 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.
package org.chromium.weblayer;
import androidx.annotation.NonNull;
/**
* Used when sending and receiving messages to a page.
*
* @since 85
*/
public class WebMessage {
private final String mContents;
/**
* Creates a message with the specified contents.
*
* @param message Contents of the message.
*/
public WebMessage(@NonNull String message) {
mContents = message;
}
/**
* Returns the contents of the message.
*
* @return The contents of the message.
*/
public @NonNull String getContents() {
return mContents;
}
}
// 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.
package org.chromium.weblayer;
import androidx.annotation.NonNull;
/**
* Receives messages from a JavaScript object that was created by calling {@link
* Tab#registerWebMessageCallback().
*
* @since 85
*/
public abstract class WebMessageCallback {
/**
* Called when a message is received from the page.
*
* @param replyProxy An object that may be used to post a message back to the page.
* @param message The message from the page.
*/
public void onWebMessageReceived(
@NonNull WebMessageReplyProxy replyProxy, @NonNull WebMessage message) {}
}
// 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.
package org.chromium.weblayer;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import org.chromium.weblayer_private.interfaces.APICallException;
import org.chromium.weblayer_private.interfaces.IWebMessageReplyProxy;
/**
* Used to post a message to a page. WebMessageReplyProxy is created when a page posts a message to
* the JavaScript object that was created by way of {@link Tab#registerWebMessageCallback}.
*
* @since 85
*/
public class WebMessageReplyProxy {
private final IWebMessageReplyProxy mIReplyProxy;
private final boolean mIsMainFrame;
private final String mSourceOrigin;
// Constructor for test mocking.
protected WebMessageReplyProxy() {
this(null, false, "");
}
WebMessageReplyProxy(
IWebMessageReplyProxy iReplyProxy, boolean isMainFrame, String sourceOrigin) {
mIReplyProxy = iReplyProxy;
mIsMainFrame = isMainFrame;
mSourceOrigin = sourceOrigin;
}
/**
* Returns true if the connection is to the main frame.
*
* @return True if the connection is to the main frame.
*/
public boolean isMainFrame() {
ThreadCheck.ensureOnUiThread();
return mIsMainFrame;
}
/**
* Returns the origin of the page.
*
* @return the origin of the page.
*/
public @NonNull String getSourceOrigin() {
ThreadCheck.ensureOnUiThread();
return mSourceOrigin;
}
/**
* Posts a message to the page.
*
* @param message The message to send to the page.
*/
public void postMessage(@NonNull WebMessage message) {
ThreadCheck.ensureOnUiThread();
try {
mIReplyProxy.postMessage(message.getContents());
} catch (RemoteException e) {
throw new APICallException(e);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment