Complete routing for Java-to-Dart messages (flutter/engine#3140)
This patch completes the routing for Java-to-Dart platform messages.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
base::StringPiece message_name = message->name();
|
||||
|
||||
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;
|
||||
|
||||
// This call can re-enter in InvokePlatformMessageResponseCallback.
|
||||
Java_FlutterView_handlePlatformMessage(
|
||||
env, view.obj(), java_message_name.obj(), java_message_data.obj(),
|
||||
response_id);
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
|
||||
Reference in New Issue
Block a user