提交 3bcdaa32 编写于 作者: A Adam Barth 提交者: GitHub

Complete routing for Java-to-Dart messages (#3140)

This patch completes the routing for Java-to-Dart platform messages.
上级 ca6d4fde
......@@ -581,11 +581,16 @@ public class FlutterView extends SurfaceView
private static native void nativeSurfaceDestroyed(long nativePlatformViewAndroid);
private static native Bitmap nativeGetBitmap(long nativePlatformViewAndroid);
// Send a platform message to Dart.
private static native void nativeDispatchPlatformMessage(long nativePlatformViewAndroid, String name, String message, int responseId);
private static native void nativeDispatchPointerDataPacket(long nativePlatformViewAndroid, ByteBuffer buffer, int position);
private static native void nativeDispatchSemanticsAction(long nativePlatformViewAndroid, int id, int action);
private static native void nativeSetSemanticsEnabled(long nativePlatformViewAndroid, boolean enabled);
private static native void nativeInvokePlatformMessageResponseCallback(long nativePlatformViewAndroid, int responseId, String buffer);
// Send a response to a platform message received from Dart.
private static native void nativeInvokePlatformMessageResponseCallback(long nativePlatformViewAndroid, int responseId, String message);
// Called by native to send us a platform message.
@CalledByNative
private void handlePlatformMessage(String name, String message, final int responseId) {
OnMessageListener listener = mOnMessageListeners.get(name);
......@@ -597,10 +602,10 @@ public class FlutterView extends SurfaceView
OnMessageListenerAsync asyncListener = mAsyncOnMessageListeners.get(name);
if (asyncListener != null) {
asyncListener.onMessage(this, message, new MessageResponse() {
@Override
public void send(String response) {
nativeInvokePlatformMessageResponseCallback(mNativePlatformView, responseId, response);
}
@Override
public void send(String response) {
nativeInvokePlatformMessageResponseCallback(mNativePlatformView, responseId, response);
}
});
return;
}
......@@ -608,6 +613,17 @@ public class FlutterView extends SurfaceView
nativeInvokePlatformMessageResponseCallback(mNativePlatformView, responseId, null);
}
private int mNextResponseId = 1;
private final Map<Integer, MessageReplyCallback> mPendingResponses = new HashMap<Integer, MessageReplyCallback>();
// Called by native to respond to a platform message that we sent.
@CalledByNative
private void handlePlatformMessageResponse(int responseId, String response) {
MessageReplyCallback callback = mPendingResponses.remove(responseId);
if (callback != null)
callback.onReply(response);
}
@CalledByNative
private void updateSemantics(ByteBuffer buffer, String[] strings) {
if (mAccessibilityNodeProvider != null) {
......@@ -712,12 +728,23 @@ public class FlutterView extends SurfaceView
return true;
}
private void dispatchPlatformMessage(String name, String message, MessageReplyCallback callback) {
int responseId = 0;
if (callback != null) {
responseId = mNextResponseId++;
mPendingResponses.put(responseId, callback);
}
nativeDispatchPlatformMessage(mNativePlatformView, name, message, responseId);
}
/**
* Send a message to the Flutter application. The Flutter Dart code can register a
* host message handler that will receive these messages.
*/
public void sendToFlutter(String messageName, String message,
final MessageReplyCallback callback) {
// TODO(abarth): Switch to dispatchPlatformMessage once the framework
// side has been converted.
mFlutterAppMessages.sendString(messageName, message,
new ApplicationMessages.SendStringResponse() {
@Override
......
......@@ -30,6 +30,36 @@
#include "third_party/skia/include/core/SkSurface.h"
namespace shell {
namespace {
class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse {
FRIEND_MAKE_REF_COUNTED(PlatformMessageResponseAndroid);
public:
void Complete(std::vector<char> data) override {
ftl::RefPtr<PlatformMessageResponseAndroid> self(this);
blink::Threads::Platform()->PostTask(
[ self, data = std::move(data) ]() mutable {
if (!self->view_)
return;
static_cast<PlatformViewAndroid*>(self->view_.get())
->HandlePlatformMessageResponse(self->response_id_,
std::move(data));
});
}
void CompleteWithError() override { Complete(std::vector<char>()); }
private:
PlatformMessageResponseAndroid(int response_id,
ftl::WeakPtr<PlatformView> view)
: response_id_(response_id), view_(view) {}
int response_id_;
ftl::WeakPtr<PlatformView> view_;
};
} // namespace
PlatformViewAndroid::PlatformViewAndroid()
: PlatformView(std::make_unique<GPURasterizer>()) {}
......@@ -105,6 +135,29 @@ void PlatformViewAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
ReleaseSurface();
}
void PlatformViewAndroid::DispatchPlatformMessage(JNIEnv* env,
jobject obj,
jstring java_name,
jstring java_message_data,
jint response_id) {
std::string name = base::android::ConvertJavaStringToUTF8(env, java_name);
std::string data;
if (java_message_data)
data = base::android::ConvertJavaStringToUTF8(env, java_message_data);
ftl::RefPtr<blink::PlatformMessageResponse> response;
if (response_id) {
response = ftl::MakeRefCounted<PlatformMessageResponseAndroid>(
response_id, GetWeakPtr());
}
PlatformView::DispatchPlatformMessage(
ftl::MakeRefCounted<blink::PlatformMessage>(
std::move(name),
std::vector<char>(data.data(), data.data() + data.size()),
std::move(response)));
}
void PlatformViewAndroid::DispatchPointerDataPacket(JNIEnv* env,
jobject obj,
jobject buffer,
......@@ -143,33 +196,47 @@ void PlatformViewAndroid::InvokePlatformMessageResponseCallback(
void PlatformViewAndroid::HandlePlatformMessage(
ftl::RefPtr<blink::PlatformMessage> message) {
JNIEnv* env = base::android::AttachCurrentThread();
{
base::android::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
if (view.is_null())
return;
base::android::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
if (view.is_null())
return;
int response_id = 0;
if (auto response = message->response()) {
response_id = next_response_id_++;
pending_responses_[response_id] = response;
}
int response_id = 0;
if (auto response = message->response()) {
response_id = next_response_id_++;
pending_responses_[response_id] = response;
}
base::StringPiece message_name = message->name();
base::StringPiece message_name = message->name();
auto data = message->data();
base::StringPiece message_data(data.data(), data.size());
auto data = message->data();
base::StringPiece message_data(data.data(), data.size());
auto java_message_name =
base::android::ConvertUTF8ToJavaString(env, message_name);
auto java_message_data =
base::android::ConvertUTF8ToJavaString(env, message_data);
message = nullptr;
auto java_message_name =
base::android::ConvertUTF8ToJavaString(env, message_name);
auto java_message_data =
base::android::ConvertUTF8ToJavaString(env, message_data);
message = nullptr;
// This call can re-enter in InvokePlatformMessageResponseCallback.
Java_FlutterView_handlePlatformMessage(
env, view.obj(), java_message_name.obj(), java_message_data.obj(),
response_id);
}
// This call can re-enter in InvokePlatformMessageResponseCallback.
Java_FlutterView_handlePlatformMessage(env, view.obj(),
java_message_name.obj(),
java_message_data.obj(), response_id);
}
void PlatformViewAndroid::HandlePlatformMessageResponse(
int response_id,
std::vector<char> data) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
if (view.is_null())
return;
base::StringPiece message_data(data.data(), data.size());
auto java_message_data =
base::android::ConvertUTF8ToJavaString(env, message_data);
Java_FlutterView_handlePlatformMessageResponse(env, view.obj(), response_id,
java_message_data.obj());
}
void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
......
......@@ -37,6 +37,12 @@ class PlatformViewAndroid : public PlatformView {
void SurfaceDestroyed(JNIEnv* env, jobject obj);
void DispatchPlatformMessage(JNIEnv* env,
jobject obj,
jstring name,
jstring message,
jint response_id);
void DispatchPointerDataPacket(JNIEnv* env,
jobject obj,
jobject buffer,
......@@ -61,6 +67,8 @@ class PlatformViewAndroid : public PlatformView {
void HandlePlatformMessage(
ftl::RefPtr<blink::PlatformMessage> message) override;
void HandlePlatformMessageResponse(int response_id, std::vector<char> data);
void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) override;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册