-
Notifications
You must be signed in to change notification settings - Fork 6k
Allow embedders to add callbacks for responses to platform messages from the framework. #9655
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -373,12 +373,11 @@ typedef struct { | |
| size_t struct_size; | ||
| const char* channel; | ||
| const uint8_t* message; | ||
| const size_t message_size; | ||
| 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. |FlutterEngineSendPlatformMessageResponse| must be called for | ||
| // all messages received by the embedder. Failure to call | ||
| // |FlutterEngineSendPlatformMessageResponse| when the response is ready. | ||
| // |FlutterEngineSendPlatformMessageResponse| must be called for all messages | ||
| // received by the embedder. Failure to call | ||
| // |FlutterEngineSendPlatformMessageResponse| will cause a memory leak. It is | ||
| // not safe to send multiple responses on a single response object. | ||
| const FlutterPlatformMessageResponseHandle* response_handle; | ||
|
|
@@ -388,6 +387,10 @@ typedef void (*FlutterPlatformMessageCallback)( | |
| const FlutterPlatformMessage* /* message*/, | ||
| void* /* user data */); | ||
|
|
||
| typedef void (*FlutterDataCallback)(const uint8_t* /* data */, | ||
| size_t /* size */, | ||
| void* /* user data */); | ||
|
|
||
| typedef struct { | ||
| double left; | ||
| double top; | ||
|
|
@@ -707,6 +710,33 @@ FlutterEngineResult FlutterEngineSendPlatformMessage( | |
| FlutterEngine engine, | ||
| const FlutterPlatformMessage* message); | ||
|
|
||
| // Creates a platform message response handle that allows the embedder to set a | ||
| // native callback for a response to a message. This handle may be set on the | ||
| // |response_handle| field of any |FlutterPlatformMessage| sent to the engine. | ||
| // | ||
| // The handle must be collected via a call to | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: consider adding a blank line above this, and another before the "The user data baton [...]" to break this long comment up into different conceptual sections (overview, memory management, argument details).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. At some point, we should move over to using doxygen style header docs too. |
||
| // |FlutterPlatformMessageReleaseResponseHandle|. This may be done immediately | ||
| // after a call to |FlutterEngineSendPlatformMessage| with a platform message | ||
| // whose response handle contains the handle created using this call. In case a | ||
| // handle is created but never sent in a message, the release call must still be | ||
| // made. Not calling release on the handle results in a small memory leak. | ||
| // | ||
| // The user data baton passed to the data callback is the one specified in this | ||
| // call as the third argument. | ||
| FLUTTER_EXPORT | ||
| FlutterEngineResult FlutterPlatformMessageCreateResponseHandle( | ||
| FlutterEngine engine, | ||
| FlutterDataCallback data_callback, | ||
| void* user_data, | ||
| FlutterPlatformMessageResponseHandle** response_out); | ||
|
|
||
| // Collects the handle created using | ||
| // |FlutterPlatformMessageCreateResponseHandle|. | ||
| FLUTTER_EXPORT | ||
| FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle( | ||
| FlutterEngine engine, | ||
| FlutterPlatformMessageResponseHandle* response); | ||
|
|
||
| FLUTTER_EXPORT | ||
| FlutterEngineResult FlutterEngineSendPlatformMessageResponse( | ||
| FlutterEngine engine, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| // Copyright 2013 The Flutter 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 "flutter/shell/platform/embedder/embedder_platform_message_response.h" | ||
|
|
||
| #include "flutter/fml/make_copyable.h" | ||
|
|
||
| namespace flutter { | ||
|
|
||
| EmbedderPlatformMessageResponse::EmbedderPlatformMessageResponse( | ||
| fml::RefPtr<fml::TaskRunner> runner, | ||
| Callback callback) | ||
| : runner_(std::move(runner)), callback_(callback) {} | ||
|
|
||
| EmbedderPlatformMessageResponse::~EmbedderPlatformMessageResponse() = default; | ||
|
|
||
| // |PlatformMessageResponse| | ||
| void EmbedderPlatformMessageResponse::Complete( | ||
| std::unique_ptr<fml::Mapping> data) { | ||
| if (!data) { | ||
| CompleteEmpty(); | ||
| return; | ||
| } | ||
|
|
||
| runner_->PostTask( | ||
| fml::MakeCopyable([data = std::move(data), callback = callback_]() { | ||
| callback(data->GetMapping(), data->GetSize()); | ||
| })); | ||
| } | ||
|
|
||
| // |PlatformMessageResponse| | ||
| void EmbedderPlatformMessageResponse::CompleteEmpty() { | ||
| Complete(std::make_unique<fml::NonOwnedMapping>(nullptr, 0u)); | ||
| } | ||
|
|
||
| } // namespace flutter |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| // Copyright 2013 The Flutter 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 FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_PLATFORM_MESSAGE_RESPONSE_H_ | ||
| #define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_PLATFORM_MESSAGE_RESPONSE_H_ | ||
|
|
||
| #include "flutter/fml/macros.h" | ||
| #include "flutter/fml/task_runner.h" | ||
| #include "flutter/lib/ui/window/platform_message_response.h" | ||
|
|
||
| namespace flutter { | ||
|
|
||
| //------------------------------------------------------------------------------ | ||
| /// @brief The platform message response subclass for responses to messages | ||
| /// from the embedder to the framework. Message responses are | ||
| /// fulfilled by the framework. | ||
| class EmbedderPlatformMessageResponse : public PlatformMessageResponse { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add class definition documentation?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| public: | ||
| using Callback = std::function<void(const uint8_t* data, size_t size)>; | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @param[in] runner The task runner on which to execute the callback. | ||
| /// The response will be initiated by the framework on | ||
| /// the UI thread. | ||
| /// @param[in] callback The callback that communicates to the embedder the | ||
| /// contents of the response sent by the framework back | ||
| /// to the emebder. | ||
| EmbedderPlatformMessageResponse(fml::RefPtr<fml::TaskRunner> runner, | ||
| Callback callback); | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @brief Destroys the message response. Can be called on any thread. | ||
| /// Does not execute unfulfilled callbacks. | ||
| /// | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: remove blank comment line. |
||
| ~EmbedderPlatformMessageResponse() override; | ||
|
|
||
| private: | ||
| fml::RefPtr<fml::TaskRunner> runner_; | ||
| Callback callback_; | ||
|
|
||
| // |PlatformMessageResponse| | ||
| void Complete(std::unique_ptr<fml::Mapping> data) override; | ||
|
|
||
| // |PlatformMessageResponse| | ||
| void CompleteEmpty() override; | ||
|
|
||
| FML_DISALLOW_COPY_AND_ASSIGN(EmbedderPlatformMessageResponse); | ||
| }; | ||
|
|
||
| } // namespace flutter | ||
|
|
||
| #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_PLATFORM_MESSAGE_RESPONSE_H_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -144,3 +144,12 @@ void a11y_main() async { // ignore: non_constant_identifier_names | |
| await semanticsChanged; | ||
| notifySemanticsEnabled(window.semanticsEnabled); | ||
| } | ||
|
|
||
|
|
||
| @pragma('vm:entry-point') | ||
| void platform_messages_response() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should these messages have documentation relating to the tests using them? |
||
| window.onPlatformMessage = (String name, ByteData data, PlatformMessageResponseCallback callback) { | ||
| callback(data); | ||
| }; | ||
| signalNativeTest(); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.