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