Skip to content

Commit e6ecb94

Browse files
authored
[engine] Sync Flutter 3.7 source code (#21)
1 parent 124f613 commit e6ecb94

File tree

14 files changed

+459
-101
lines changed

14 files changed

+459
-101
lines changed

flutter/shell/platform/common/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ config("desktop_library_implementation") {
88

99
_public_headers = [
1010
"public/flutter_export.h",
11+
"public/flutter_macros.h",
1112
"public/flutter_messenger.h",
1213
"public/flutter_plugin_registrar.h",
1314
"public/flutter_texture_registrar.h",

flutter/shell/platform/common/client_wrapper/core_implementations.cc

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ namespace flutter {
2626
// ========== binary_messenger_impl.h ==========
2727

2828
namespace {
29+
30+
using FlutterDesktopMessengerScopedLock =
31+
std::unique_ptr<FlutterDesktopMessenger,
32+
decltype(&FlutterDesktopMessengerUnlock)>;
33+
2934
// Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
3035
// with a BinaryReply that will send a response on |message|'s response handle.
3136
//
@@ -36,17 +41,28 @@ void ForwardToHandler(FlutterDesktopMessengerRef messenger,
3641
const FlutterDesktopMessage* message,
3742
void* user_data) {
3843
auto* response_handle = message->response_handle;
39-
BinaryReply reply_handler = [messenger, response_handle](
44+
auto messenger_ptr = std::shared_ptr<FlutterDesktopMessenger>(
45+
FlutterDesktopMessengerAddRef(messenger),
46+
&FlutterDesktopMessengerRelease);
47+
BinaryReply reply_handler = [messenger_ptr, response_handle](
4048
const uint8_t* reply,
4149
size_t reply_size) mutable {
50+
// Note: This lambda can be called on any thread.
51+
auto lock = FlutterDesktopMessengerScopedLock(
52+
FlutterDesktopMessengerLock(messenger_ptr.get()),
53+
&FlutterDesktopMessengerUnlock);
54+
if (!FlutterDesktopMessengerIsAvailable(messenger_ptr.get())) {
55+
// Drop reply if it comes in after the engine is destroyed.
56+
return;
57+
}
4258
if (!response_handle) {
4359
std::cerr << "Error: Response can be set only once. Ignoring "
4460
"duplicate response."
4561
<< std::endl;
4662
return;
4763
}
48-
FlutterDesktopMessengerSendResponse(messenger, response_handle, reply,
49-
reply_size);
64+
FlutterDesktopMessengerSendResponse(messenger_ptr.get(), response_handle,
65+
reply, reply_size);
5066
// The engine frees the response handle once
5167
// FlutterDesktopSendMessageResponse is called.
5268
response_handle = nullptr;
@@ -195,9 +211,32 @@ bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) {
195211
texture_registrar_ref_, texture_id);
196212
}
197213

214+
void TextureRegistrarImpl::UnregisterTexture(int64_t texture_id,
215+
std::function<void()> callback) {
216+
if (callback == nullptr) {
217+
FlutterDesktopTextureRegistrarUnregisterExternalTexture(
218+
texture_registrar_ref_, texture_id, nullptr, nullptr);
219+
return;
220+
}
221+
222+
struct Captures {
223+
std::function<void()> callback;
224+
};
225+
auto captures = new Captures();
226+
captures->callback = std::move(callback);
227+
FlutterDesktopTextureRegistrarUnregisterExternalTexture(
228+
texture_registrar_ref_, texture_id,
229+
[](void* opaque) {
230+
auto captures = reinterpret_cast<Captures*>(opaque);
231+
captures->callback();
232+
delete captures;
233+
},
234+
captures);
235+
}
236+
198237
bool TextureRegistrarImpl::UnregisterTexture(int64_t texture_id) {
199-
return FlutterDesktopTextureRegistrarUnregisterExternalTexture(
200-
texture_registrar_ref_, texture_id);
238+
UnregisterTexture(texture_id, nullptr);
239+
return true;
201240
}
202241

203242
} // namespace flutter

flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h

Lines changed: 70 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,13 @@ class EventChannel {
4747
// Registers a stream handler on this channel.
4848
// If no handler has been registered, any incoming stream setup requests will
4949
// be handled silently by providing an empty stream.
50+
//
51+
// Note that the EventChannel does not own the handler and will not
52+
// unregister it on destruction. The caller is responsible for unregistering
53+
// the handler if it should no longer be called.
5054
void SetStreamHandler(std::unique_ptr<StreamHandler<T>> handler) {
5155
if (!handler) {
5256
messenger_->SetMessageHandler(name_, nullptr);
53-
is_listening_ = false;
5457
return;
5558
}
5659

@@ -61,69 +64,75 @@ class EventChannel {
6164
const MethodCodec<T>* codec = codec_;
6265
const std::string channel_name = name_;
6366
const BinaryMessenger* messenger = messenger_;
64-
BinaryMessageHandler binary_handler = [shared_handler, codec, channel_name,
65-
messenger,
66-
this](const uint8_t* message,
67-
const size_t message_size,
68-
BinaryReply reply) {
69-
constexpr char kOnListenMethod[] = "listen";
70-
constexpr char kOnCancelMethod[] = "cancel";
71-
72-
std::unique_ptr<MethodCall<T>> method_call =
73-
codec->DecodeMethodCall(message, message_size);
74-
if (!method_call) {
75-
std::cerr << "Unable to construct method call from message on channel: "
76-
<< channel_name << std::endl;
77-
reply(nullptr, 0);
78-
return;
79-
}
80-
81-
const std::string& method = method_call->method_name();
82-
if (method.compare(kOnListenMethod) == 0) {
83-
if (is_listening_) {
84-
std::unique_ptr<StreamHandlerError<T>> error =
85-
shared_handler->OnCancel(nullptr);
86-
if (error) {
87-
std::cerr << "Failed to cancel existing stream: "
88-
<< (error->error_code) << ", " << (error->error_message)
89-
<< ", " << (error->error_details);
67+
BinaryMessageHandler binary_handler =
68+
[shared_handler, codec, channel_name, messenger,
69+
// Mutable state to track the handler's listening status.
70+
is_listening = bool(false)](const uint8_t* message,
71+
const size_t message_size,
72+
BinaryReply reply) mutable {
73+
constexpr char kOnListenMethod[] = "listen";
74+
constexpr char kOnCancelMethod[] = "cancel";
75+
76+
std::unique_ptr<MethodCall<T>> method_call =
77+
codec->DecodeMethodCall(message, message_size);
78+
if (!method_call) {
79+
std::cerr
80+
<< "Unable to construct method call from message on channel: "
81+
<< channel_name << std::endl;
82+
reply(nullptr, 0);
83+
return;
9084
}
91-
}
92-
is_listening_ = true;
93-
94-
std::unique_ptr<std::vector<uint8_t>> result;
95-
auto sink = std::make_unique<EventSinkImplementation>(
96-
messenger, channel_name, codec);
97-
std::unique_ptr<StreamHandlerError<T>> error =
98-
shared_handler->OnListen(method_call->arguments(), std::move(sink));
99-
if (error) {
100-
result = codec->EncodeErrorEnvelope(
101-
error->error_code, error->error_message, error->error_details);
102-
} else {
103-
result = codec->EncodeSuccessEnvelope();
104-
}
105-
reply(result->data(), result->size());
106-
} else if (method.compare(kOnCancelMethod) == 0) {
107-
std::unique_ptr<std::vector<uint8_t>> result;
108-
if (is_listening_) {
109-
std::unique_ptr<StreamHandlerError<T>> error =
110-
shared_handler->OnCancel(method_call->arguments());
111-
if (error) {
112-
result = codec->EncodeErrorEnvelope(
113-
error->error_code, error->error_message, error->error_details);
85+
86+
const std::string& method = method_call->method_name();
87+
if (method.compare(kOnListenMethod) == 0) {
88+
if (is_listening) {
89+
std::unique_ptr<StreamHandlerError<T>> error =
90+
shared_handler->OnCancel(nullptr);
91+
if (error) {
92+
std::cerr << "Failed to cancel existing stream: "
93+
<< (error->error_code) << ", "
94+
<< (error->error_message) << ", "
95+
<< (error->error_details);
96+
}
97+
}
98+
is_listening = true;
99+
100+
std::unique_ptr<std::vector<uint8_t>> result;
101+
auto sink = std::make_unique<EventSinkImplementation>(
102+
messenger, channel_name, codec);
103+
std::unique_ptr<StreamHandlerError<T>> error =
104+
shared_handler->OnListen(method_call->arguments(),
105+
std::move(sink));
106+
if (error) {
107+
result = codec->EncodeErrorEnvelope(error->error_code,
108+
error->error_message,
109+
error->error_details);
110+
} else {
111+
result = codec->EncodeSuccessEnvelope();
112+
}
113+
reply(result->data(), result->size());
114+
} else if (method.compare(kOnCancelMethod) == 0) {
115+
std::unique_ptr<std::vector<uint8_t>> result;
116+
if (is_listening) {
117+
std::unique_ptr<StreamHandlerError<T>> error =
118+
shared_handler->OnCancel(method_call->arguments());
119+
if (error) {
120+
result = codec->EncodeErrorEnvelope(error->error_code,
121+
error->error_message,
122+
error->error_details);
123+
} else {
124+
result = codec->EncodeSuccessEnvelope();
125+
}
126+
is_listening = false;
127+
} else {
128+
result = codec->EncodeErrorEnvelope(
129+
"error", "No active stream to cancel", nullptr);
130+
}
131+
reply(result->data(), result->size());
114132
} else {
115-
result = codec->EncodeSuccessEnvelope();
133+
reply(nullptr, 0);
116134
}
117-
is_listening_ = false;
118-
} else {
119-
result = codec->EncodeErrorEnvelope(
120-
"error", "No active stream to cancel", nullptr);
121-
}
122-
reply(result->data(), result->size());
123-
} else {
124-
reply(nullptr, 0);
125-
}
126-
};
135+
};
127136
messenger_->SetMessageHandler(name_, std::move(binary_handler));
128137
}
129138

@@ -165,7 +174,6 @@ class EventChannel {
165174
BinaryMessenger* messenger_;
166175
const std::string name_;
167176
const MethodCodec<T>* codec_;
168-
bool is_listening_ = false;
169177
};
170178

171179
} // namespace flutter

flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,13 @@ class TextureRegistrar {
9595
// the callback that was provided upon creating the texture.
9696
virtual bool MarkTextureFrameAvailable(int64_t texture_id) = 0;
9797

98-
// Unregisters an existing Texture object.
99-
// Textures must not be unregistered while they're in use.
98+
// Asynchronously unregisters an existing texture object.
99+
// Upon completion, the optional |callback| gets invoked.
100+
virtual void UnregisterTexture(int64_t texture_id,
101+
std::function<void()> callback) = 0;
102+
103+
// Unregisters an existing texture object.
104+
// DEPRECATED: Use UnregisterTexture(texture_id, optional_callback) instead.
100105
virtual bool UnregisterTexture(int64_t texture_id) = 0;
101106
};
102107

flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ class TextureRegistrarImpl : public TextureRegistrar {
2727
// |flutter::TextureRegistrar|
2828
bool MarkTextureFrameAvailable(int64_t texture_id) override;
2929

30+
// |flutter::TextureRegistrar|
31+
void UnregisterTexture(int64_t texture_id,
32+
std::function<void()> callback) override;
33+
3034
// |flutter::TextureRegistrar|
3135
bool UnregisterTexture(int64_t texture_id) override;
3236

flutter/shell/platform/common/incoming_message_dispatcher.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ void IncomingMessageDispatcher::HandleMessage(
1919
const std::function<void(void)>& input_unblock_cb) {
2020
std::string channel(message.channel);
2121

22+
auto callback_iterator = callbacks_.find(channel);
2223
// Find the handler for the channel; if there isn't one, report the failure.
23-
if (callbacks_.find(channel) == callbacks_.end()) {
24+
if (callback_iterator == callbacks_.end()) {
2425
FlutterDesktopMessengerSendResponse(messenger_, message.response_handle,
2526
nullptr, 0);
2627
return;
2728
}
28-
auto& callback_info = callbacks_[channel];
29-
FlutterDesktopMessageCallback message_callback = callback_info.first;
29+
auto& callback_info = callback_iterator->second;
30+
const FlutterDesktopMessageCallback& message_callback = callback_info.first;
3031

3132
// Process the call, handling input blocking if requested.
3233
bool block_input = input_blocking_channels_.count(channel) > 0;

flutter/shell/platform/common/public/flutter_export.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_
77

88
#ifdef FLUTTER_DESKTOP_LIBRARY
9-
// Add visibility/export annotations when building the library.
109

10+
// Add visibility/export annotations when building the library.
1111
#ifdef _WIN32
1212
#define FLUTTER_EXPORT __declspec(dllexport)
1313
#else
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MACROS_H_
6+
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MACROS_H_
7+
8+
#ifdef FLUTTER_DESKTOP_LIBRARY
9+
10+
// Do not add deprecation annotations when building the library.
11+
#define FLUTTER_DEPRECATED(message)
12+
13+
#else // FLUTTER_DESKTOP_LIBRARY
14+
15+
// Add deprecation warning for users of the library.
16+
#ifdef _WIN32
17+
#define FLUTTER_DEPRECATED(message) __declspec(deprecated(message))
18+
#else
19+
#define FLUTTER_DEPRECATED(message) __attribute__((deprecated(message)))
20+
#endif
21+
22+
#endif // FLUTTER_DESKTOP_LIBRARY
23+
24+
#endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MACROS_H_

flutter/shell/platform/common/public/flutter_messenger.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
66
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
77

8+
#include <stdbool.h>
89
#include <stddef.h>
910
#include <stdint.h>
1011

@@ -87,6 +88,53 @@ FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback(
8788
FlutterDesktopMessageCallback callback,
8889
void* user_data);
8990

91+
// Increments the reference count for the |messenger|.
92+
//
93+
// Operation is thread-safe.
94+
//
95+
// See also: |FlutterDesktopMessengerRelease|
96+
FLUTTER_EXPORT FlutterDesktopMessengerRef
97+
FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger);
98+
99+
// Decrements the reference count for the |messenger|.
100+
//
101+
// Operation is thread-safe.
102+
//
103+
// See also: |FlutterDesktopMessengerAddRef|
104+
FLUTTER_EXPORT void FlutterDesktopMessengerRelease(
105+
FlutterDesktopMessengerRef messenger);
106+
107+
// Returns `true` if the |FlutterDesktopMessengerRef| still references a running
108+
// engine.
109+
//
110+
// This check should be made inside of a |FlutterDesktopMessengerLock| and
111+
// before any other calls are made to the FlutterDesktopMessengerRef when using
112+
// it from a thread other than the platform thread.
113+
FLUTTER_EXPORT bool FlutterDesktopMessengerIsAvailable(
114+
FlutterDesktopMessengerRef messenger);
115+
116+
// Locks the `FlutterDesktopMessengerRef` ensuring that
117+
// |FlutterDesktopMessengerIsAvailable| does not change while locked.
118+
//
119+
// All calls to the FlutterDesktopMessengerRef from threads other than the
120+
// platform thread should happen inside of a lock.
121+
//
122+
// Operation is thread-safe.
123+
//
124+
// Returns the |messenger| value.
125+
//
126+
// See also: |FlutterDesktopMessengerUnlock|
127+
FLUTTER_EXPORT FlutterDesktopMessengerRef
128+
FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger);
129+
130+
// Unlocks the `FlutterDesktopMessengerRef`.
131+
//
132+
// Operation is thread-safe.
133+
//
134+
// See also: |FlutterDesktopMessengerLock|
135+
FLUTTER_EXPORT void FlutterDesktopMessengerUnlock(
136+
FlutterDesktopMessengerRef messenger);
137+
90138
#if defined(__cplusplus)
91139
} // extern "C"
92140
#endif

0 commit comments

Comments
 (0)