未验证 提交 bedba126 编写于 作者: C Chinmay Garde 提交者: GitHub

Allow embedders to respond to platform messages from the Dart application. (#4361)

This updated the native embedder API in a non-ABI breaking way.
上级 f8c4a02b
......@@ -55,6 +55,10 @@ class PlatformViewHolder {
FXL_DISALLOW_COPY_AND_ASSIGN(PlatformViewHolder);
};
struct _FlutterPlatformMessageResponseHandle {
fxl::RefPtr<blink::PlatformMessage> message;
};
FlutterResult FlutterEngineRun(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
......@@ -101,6 +105,25 @@ FlutterResult FlutterEngineRun(size_t version,
return ptr(user_data);
};
shell::PlatformViewEmbedder::PlatformMessageResponseCallback
platform_message_response_callback = nullptr;
if (SAFE_ACCESS(args, platform_message_callback, nullptr) != nullptr) {
platform_message_response_callback =
[ ptr = args->platform_message_callback,
user_data ](fxl::RefPtr<blink::PlatformMessage> message) {
auto handle = new FlutterPlatformMessageResponseHandle();
const FlutterPlatformMessage incoming_message = {
.struct_size = sizeof(FlutterPlatformMessage),
.channel = message->channel().c_str(),
.message = message->data().data(),
.message_size = message->data().size(),
.response_handle = handle,
};
handle->message = std::move(message);
return ptr(&incoming_message, user_data);
};
}
std::string icu_data_path;
if (SAFE_ACCESS(args, icu_data_path, nullptr) != nullptr) {
icu_data_path = SAFE_ACCESS(args, icu_data_path, nullptr);
......@@ -128,7 +151,9 @@ FlutterResult FlutterEngineRun(size_t version,
.gl_make_current_callback = make_current,
.gl_clear_current_callback = clear_current,
.gl_present_callback = present,
.gl_fbo_callback = fbo_callback};
.gl_fbo_callback = fbo_callback,
.platform_message_response_callback = platform_message_response_callback,
};
auto platform_view = std::make_shared<shell::PlatformViewEmbedder>(table);
platform_view->Attach();
......@@ -274,3 +299,25 @@ FlutterResult FlutterEngineSendPlatformMessage(
});
return kSuccess;
}
FlutterResult FlutterEngineSendPlatformMessageResponse(
FlutterEngine engine,
const FlutterPlatformMessageResponseHandle* handle,
const uint8_t* data,
size_t data_length) {
if (data_length != 0 && data == nullptr) {
return kInvalidArguments;
}
auto response = handle->message->response();
if (data_length == 0) {
response->CompleteEmpty();
} else {
response->Complete({data, data + data_length});
}
delete handle;
return kSuccess;
}
......@@ -50,36 +50,6 @@ typedef struct {
};
} FlutterRendererConfig;
typedef struct {
// The size of this struct. Must be sizeof(FlutterProjectArgs).
size_t struct_size;
// The path to the FLX file containing project assets. The string can be
// collected after the call to |FlutterEngineRun| returns. The string must be
// NULL terminated.
const char* assets_path;
// The path to the Dart file containing the |main| entry point. The string can
// be collected after the call to |FlutterEngineRun| returns. The string must
// be NULL terminated.
const char* main_path;
// The path to the |.packages| for the project. The string can be collected
// after the call to |FlutterEngineRun| returns. The string must be NULL
// terminated.
const char* packages_path;
// The path to the icudtl.dat file for the project. The string can be
// collected after the call to |FlutterEngineRun| returns. The string must
// be NULL terminated.
const char* icu_data_path;
// The command line argument count used to initialize the project. The string
// can be collected after the call to |FlutterEngineRun| returns. The string
// must be NULL terminated.
int command_line_argc;
// The command line arguments used to initialize the project. The strings can
// be collected after the call to |FlutterEngineRun| returns. The strings must
// be NULL terminated.
const char* const* command_line_argv;
} FlutterProjectArgs;
typedef struct {
// The size of this struct. Must be sizeof(FlutterWindowMetricsEvent).
size_t struct_size;
......@@ -107,14 +77,64 @@ typedef struct {
double y;
} FlutterPointerEvent;
struct _FlutterPlatformMessageResponseHandle;
typedef struct _FlutterPlatformMessageResponseHandle
FlutterPlatformMessageResponseHandle;
typedef struct {
// The size of this struct. Must be sizeof(FlutterPlatformMessage).
size_t struct_size;
const char* channel;
const uint8_t* message;
const size_t message_size;
// The response handle on which to invoke
// |FlutterEngineSendPlatformMessageResponse| when the response is ready. This
// field is ignored for messages being sent from the embedder to the
// framework. If the embedder ever receives a message with a non-null response
// handle, that handle must always be used with a
// |FlutterEngineSendPlatformMessageResponse| call. If not, this is a memory
// leak. It is not safe to send multiple responses on a single response
// object.
const FlutterPlatformMessageResponseHandle* response_handle;
} FlutterPlatformMessage;
typedef void (*FlutterPlatformMessageCallback)(
const FlutterPlatformMessage* /* message*/,
void* /* user data */);
typedef struct {
// The size of this struct. Must be sizeof(FlutterProjectArgs).
size_t struct_size;
// The path to the FLX file containing project assets. The string can be
// collected after the call to |FlutterEngineRun| returns. The string must be
// NULL terminated.
const char* assets_path;
// The path to the Dart file containing the |main| entry point. The string can
// be collected after the call to |FlutterEngineRun| returns. The string must
// be NULL terminated.
const char* main_path;
// The path to the |.packages| for the project. The string can be collected
// after the call to |FlutterEngineRun| returns. The string must be NULL
// terminated.
const char* packages_path;
// The path to the icudtl.dat file for the project. The string can be
// collected after the call to |FlutterEngineRun| returns. The string must
// be NULL terminated.
const char* icu_data_path;
// The command line argument count used to initialize the project. The string
// can be collected after the call to |FlutterEngineRun| returns. The string
// must be NULL terminated.
int command_line_argc;
// The command line arguments used to initialize the project. The strings can
// be collected after the call to |FlutterEngineRun| returns. The strings must
// be NULL terminated.
const char* const* command_line_argv;
// The callback invoked by the engine in order to give the embedder the chance
// to respond to platform messages from the Dart application. The callback
// will be invoked on the thread on which the |FlutterEngineRun| call is made.
FlutterPlatformMessageCallback platform_message_callback;
} FlutterProjectArgs;
FLUTTER_EXPORT
FlutterResult FlutterEngineRun(size_t version,
const FlutterRendererConfig* config,
......@@ -140,6 +160,13 @@ FlutterResult FlutterEngineSendPlatformMessage(
FlutterEngine engine,
const FlutterPlatformMessage* message);
FLUTTER_EXPORT
FlutterResult FlutterEngineSendPlatformMessageResponse(
FlutterEngine engine,
const FlutterPlatformMessageResponseHandle* handle,
const uint8_t* data,
size_t data_length);
#if defined(__cplusplus)
} // extern "C"
#endif
......
......@@ -47,4 +47,22 @@ void PlatformViewEmbedder::RunFromSource(const std::string& assets_directory,
FXL_LOG(INFO) << "Hot reloading is unsupported on this platform.";
}
void PlatformViewEmbedder::HandlePlatformMessage(
fxl::RefPtr<blink::PlatformMessage> message) {
if (!message) {
return;
}
if (!message->response()) {
return;
}
if (dispatch_table_.platform_message_response_callback == nullptr) {
message->response()->CompleteEmpty();
return;
}
dispatch_table_.platform_message_response_callback(std::move(message));
}
} // namespace shell
......@@ -7,17 +7,22 @@
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/gpu/gpu_surface_gl.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "lib/fxl/macros.h"
namespace shell {
class PlatformViewEmbedder : public PlatformView, public GPUSurfaceGLDelegate {
public:
using PlatformMessageResponseCallback =
std::function<void(fxl::RefPtr<blink::PlatformMessage>)>;
struct DispatchTable {
std::function<bool(void)> gl_make_current_callback;
std::function<bool(void)> gl_clear_current_callback;
std::function<bool(void)> gl_present_callback;
std::function<intptr_t(void)> gl_fbo_callback;
std::function<bool(void)> gl_make_current_callback; // required
std::function<bool(void)> gl_clear_current_callback; // required
std::function<bool(void)> gl_present_callback; // required
std::function<intptr_t(void)> gl_fbo_callback; // required
PlatformMessageResponseCallback
platform_message_response_callback; // optional
};
PlatformViewEmbedder(DispatchTable dispatch_table);
......@@ -47,6 +52,10 @@ class PlatformViewEmbedder : public PlatformView, public GPUSurfaceGLDelegate {
const std::string& main,
const std::string& packages) override;
// |shell::PlatformView|
void HandlePlatformMessage(
fxl::RefPtr<blink::PlatformMessage> message) override;
private:
DispatchTable dispatch_table_;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册