Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
bf3c3c7
Skeleton cpp function
yaakovschectman Aug 16, 2023
839f8d1
Calling
yaakovschectman Aug 16, 2023
5dd476e
Message makes it to Shell
yaakovschectman Aug 16, 2023
0bdacd0
Part of project args
yaakovschectman Aug 16, 2023
c2091cf
FlutterWindowsEngine creates a callback
yaakovschectman Aug 16, 2023
b3cf373
Engine listens
yaakovschectman Aug 17, 2023
0ca00f7
Remove OnApplicationLifecycleEnabled
yaakovschectman Aug 17, 2023
0ea137c
Unit test
yaakovschectman Aug 17, 2023
af8cf2d
Doc comments
yaakovschectman Aug 17, 2023
711ebac
Formatting
yaakovschectman Aug 17, 2023
17c85e1
Update to info struct
yaakovschectman Aug 18, 2023
770bcfe
Merge branch 'main' into embedder_channel
yaakovschectman Aug 18, 2023
da9083a
Update test
yaakovschectman Aug 18, 2023
ba08343
Merge branch 'main' into embedder_channel
yaakovschectman Aug 21, 2023
f10ec72
Web parity
yaakovschectman Aug 21, 2023
6d86f71
Add callback to test context
yaakovschectman Aug 21, 2023
c7a6454
Start unit test
yaakovschectman Aug 23, 2023
6286c00
Merge branch 'main' into embedder_channel
yaakovschectman Aug 23, 2023
60f5ac9
Merge branch 'main' into embedder_channel
yaakovschectman Aug 23, 2023
d136a93
Run expired tasks
yaakovschectman Aug 23, 2023
3413635
Rename methods
yaakovschectman Aug 24, 2023
ff1e6c2
Copy channel name in lambda
yaakovschectman Aug 24, 2023
bf67370
Merge branch 'main' into embedder_channel
yaakovschectman Aug 24, 2023
6cf7338
Meet mac tidy
yaakovschectman Aug 24, 2023
f0ac397
Required named param
yaakovschectman Aug 24, 2023
bff347a
Check for listener set
yaakovschectman Aug 24, 2023
2e87fa9
Check values in unittest
yaakovschectman Aug 24, 2023
cf671c8
PR feedback
yaakovschectman Aug 24, 2023
77316c9
Merge branch 'main' into embedder_channel
yaakovschectman Aug 24, 2023
54d0826
Merge branch 'main' into embedder_channel
yaakovschectman Aug 28, 2023
62b015c
Remove const reference
yaakovschectman Aug 28, 2023
478b6dd
STREQ
yaakovschectman Aug 28, 2023
96e841c
Test lifecycle begins
yaakovschectman Aug 28, 2023
d01b399
Test lifecycle begins
yaakovschectman Aug 28, 2023
48a17ff
Update shell/platform/embedder/tests/embedder_unittests.cc
yaakovschectman Aug 28, 2023
6b9b572
Update shell/common/platform_view.h
yaakovschectman Aug 28, 2023
5b6a221
Merge branch 'main' into embedder_channel
yaakovschectman Aug 28, 2023
bdbb829
Add struct size
yaakovschectman Aug 28, 2023
f4d292b
Reintroduce const ref
yaakovschectman Aug 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/ui/channel_buffers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ class ChannelBuffers {
assert(!name.contains('\u0000'), 'Channel names must not contain U+0000 NULL characters.');
final _Channel channel = _channels.putIfAbsent(name, () => _Channel());
channel.setListener(callback);
channelListenedTo(name, true);
}

/// Clears the listener for the specified channel.
Expand All @@ -392,9 +393,15 @@ class ChannelBuffers {
final _Channel? channel = _channels[name];
if (channel != null) {
channel.clearListener();
channelListenedTo(name, false);
}
}

@Native<Void Function(Handle, Bool)>(symbol: 'PlatformConfigurationNativeApi::PlatformChannelListenedTo')
external static void _channelListenedTo(String name, bool listening);

void channelListenedTo(String name, bool listening) => _channelListenedTo(name, listening);

/// Deprecated. Migrate to [setListener] instead.
///
/// Remove and process all stored messages for a given channel.
Expand Down
1 change: 1 addition & 0 deletions lib/ui/dart_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ typedef CanvasPath Path;
V(PlatformConfigurationNativeApi::GetRootIsolateToken, 0) \
V(PlatformConfigurationNativeApi::RegisterBackgroundIsolate, 1) \
V(PlatformConfigurationNativeApi::SendPortPlatformMessage, 4) \
V(PlatformConfigurationNativeApi::PlatformChannelListenedTo, 2) \
V(DartRuntimeHooks::Logger_PrintDebugString, 1) \
V(DartRuntimeHooks::Logger_PrintString, 1) \
V(DartRuntimeHooks::ScheduleMicrotask, 1) \
Expand Down
7 changes: 7 additions & 0 deletions lib/ui/window/platform_configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -539,4 +539,11 @@ void PlatformConfigurationNativeApi::RegisterBackgroundIsolate(
dart_state->SetPlatformMessageHandler(weak_platform_message_handler);
}

void PlatformConfigurationNativeApi::PlatformChannelListenedTo(
const std::string& name,
bool listening) {
UIDartState::Current()->platform_configuration()->client()->ChannelListenedTo(
name, listening);
}

} // namespace flutter
14 changes: 14 additions & 0 deletions lib/ui/window/platform_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,17 @@ class PlatformConfigurationClient {
///
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id) = 0;

//--------------------------------------------------------------------------
/// @brief Invoked when a listener is registered on a platform channel.
///
/// @param[in] name The name of the platform channel to which a
/// listener has been registered or cleared.
///
/// @param[in] listening Whether the listener has been set (true) or
/// cleared (false).
///
virtual void ChannelListenedTo(const std::string& name, bool listening) = 0;

protected:
virtual ~PlatformConfigurationClient();
};
Expand Down Expand Up @@ -521,6 +532,9 @@ class PlatformConfigurationNativeApi {
static void RespondToPlatformMessage(int response_id,
const tonic::DartByteData& data);

static void PlatformChannelListenedTo(const std::string& name,
bool listening);

//--------------------------------------------------------------------------
/// @brief Requests the Dart VM to adjusts the GC heuristics based on
/// the requested `performance_mode`. Returns the old performance
Expand Down
6 changes: 6 additions & 0 deletions runtime/runtime_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,12 @@ RuntimeController::ComputePlatformResolvedLocale(
return client_.ComputePlatformResolvedLocale(supported_locale_data);
}

// |PlatformConfigurationClient|
void RuntimeController::ChannelListenedTo(const std::string& name,
bool listening) {
client_.ChannelListenedTo(name, listening);
}

Dart_Port RuntimeController::GetMainPort() {
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
Expand Down
3 changes: 3 additions & 0 deletions runtime/runtime_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,9 @@ class RuntimeController : public PlatformConfigurationClient {
std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
const std::vector<std::string>& supported_locale_data) override;

// |PlatformConfigurationClient|
void ChannelListenedTo(const std::string& name, bool listening) override;

FML_DISALLOW_COPY_AND_ASSIGN(RuntimeController);
};

Expand Down
2 changes: 2 additions & 0 deletions runtime/runtime_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class RuntimeDelegate {
virtual std::weak_ptr<PlatformMessageHandler> GetPlatformMessageHandler()
const = 0;

virtual void ChannelListenedTo(const std::string& name, bool listening) = 0;

protected:
virtual ~RuntimeDelegate();
};
Expand Down
4 changes: 4 additions & 0 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,10 @@ std::weak_ptr<PlatformMessageHandler> Engine::GetPlatformMessageHandler()
return delegate_.GetPlatformMessageHandler();
}

void Engine::ChannelListenedTo(const std::string& name, bool listening) {
delegate_.OnEngineChannelListenedTo(name, listening);
}

void Engine::LoadDartDeferredLibrary(
intptr_t loading_unit_id,
std::unique_ptr<const fml::Mapping> snapshot_data,
Expand Down
15 changes: 15 additions & 0 deletions shell/common/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,18 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
/// Flutter to the host platform (and its responses).
virtual const std::shared_ptr<PlatformMessageHandler>&
GetPlatformMessageHandler() const = 0;

//--------------------------------------------------------------------------
/// @brief Invoked when a listener is registered on a platform channel.
///
/// @param[in] name The name of the platform channel to which a
/// listener has been registered or cleared.
///
/// @param[in] listening Whether the listener has been set (true) or
/// cleared (false).
///
virtual void OnEngineChannelListenedTo(const std::string& name,
bool listening) = 0;
};

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -933,6 +945,9 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
std::weak_ptr<PlatformMessageHandler> GetPlatformMessageHandler()
const override;

// |RuntimeDelegate|
void ChannelListenedTo(const std::string& name, bool listening) override;

void SetNeedsReportTimings(bool value) override;

bool HandleLifecyclePlatformMessage(PlatformMessage* message);
Expand Down
2 changes: 2 additions & 0 deletions shell/common/engine_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MockDelegate : public Engine::Delegate {
MOCK_METHOD0(GetCurrentTimePoint, fml::TimePoint());
MOCK_CONST_METHOD0(GetPlatformMessageHandler,
const std::shared_ptr<PlatformMessageHandler>&());
MOCK_METHOD2(OnEngineChannelListenedTo, void(const std::string&, bool));
};

class MockResponse : public PlatformMessageResponse {
Expand Down Expand Up @@ -68,6 +69,7 @@ class MockRuntimeDelegate : public RuntimeDelegate {
MOCK_METHOD1(RequestDartDeferredLibrary, void(intptr_t));
MOCK_CONST_METHOD0(GetPlatformMessageHandler,
std::weak_ptr<PlatformMessageHandler>());
MOCK_METHOD2(ChannelListenedTo, void(const std::string&, bool));
};

class MockRuntimeController : public RuntimeController {
Expand Down
2 changes: 2 additions & 0 deletions shell/common/platform_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ void PlatformView::UpdateSemantics(
// NOLINTNEXTLINE(performance-unnecessary-value-param)
CustomAccessibilityActionUpdates actions) {}

void PlatformView::ChannelListenedTo(const std::string& name, bool listening) {}

void PlatformView::HandlePlatformMessage(
std::unique_ptr<PlatformMessage> message) {
if (auto response = message->response()) {
Expand Down
3 changes: 3 additions & 0 deletions shell/common/platform_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ class PlatformView {
virtual void UpdateSemantics(SemanticsNodeUpdates updates,
CustomAccessibilityActionUpdates actions);

//----------------------------------------------------------------------------
virtual void ChannelListenedTo(const std::string& name, bool listening);

//----------------------------------------------------------------------------
/// @brief Used by embedders to specify the updated viewport metrics for
/// a view. In response to this call, on the raster thread, the
Expand Down
12 changes: 12 additions & 0 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,18 @@ void Shell::OnEngineHandlePlatformMessage(
}
}

void Shell::OnEngineChannelListenedTo(const std::string& name, bool listening) {
FML_DCHECK(is_set_up_);
FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());

task_runners_.GetPlatformTaskRunner()->PostTask(
[view = platform_view_->GetWeakPtr(), name, listening] {
if (view) {
view->ChannelListenedTo(name, listening);
}
});
}

void Shell::HandleEngineSkiaMessage(std::unique_ptr<PlatformMessage> message) {
const auto& data = message->data();

Expand Down
4 changes: 4 additions & 0 deletions shell/common/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,10 @@ class Shell final : public PlatformView::Delegate,
// |Engine::Delegate|
fml::TimePoint GetCurrentTimePoint() override;

// |Engine::Delegate|
void OnEngineChannelListenedTo(const std::string& name,
bool listening) override;

// |Rasterizer::Delegate|
void OnFrameRasterized(const FrameTiming&) override;

Expand Down
12 changes: 12 additions & 0 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1881,6 +1881,17 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
user_data]() { return ptr(user_data); };
}

flutter::PlatformViewEmbedder::ChannelListenedToCallback
channel_listened_to_callback = nullptr;
if (SAFE_ACCESS(args, channel_listened_to_callback, nullptr) != nullptr) {
channel_listened_to_callback = [ptr = args->channel_listened_to_callback,
user_data](const std::string& name,
bool listening) {
size_t name_len = name.size();
ptr(name.data(), name_len, listening, user_data);
};
}

auto external_view_embedder_result = InferExternalViewEmbedderFromArgs(
SAFE_ACCESS(args, compositor, nullptr), settings.enable_impeller);
if (external_view_embedder_result.second) {
Expand All @@ -1895,6 +1906,7 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
vsync_callback, //
compute_platform_resolved_locale_callback, //
on_pre_engine_restart_callback, //
channel_listened_to_callback, //
};

auto on_create_platform_view = InferPlatformViewCreationCallback(
Expand Down
10 changes: 10 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,12 @@ typedef void (*FlutterUpdateSemanticsCallback2)(
const FlutterSemanticsUpdate2* /* semantics update */,
void* /* user data*/);

typedef void (*FlutterChannelListenedToCallback)(
const char* data /* name */,
size_t data_len /* name.size */,
bool /* listening */,
void* /* user data */);

typedef struct _FlutterTaskRunner* FlutterTaskRunner;

typedef struct {
Expand Down Expand Up @@ -2118,6 +2124,10 @@ typedef struct {
/// and `update_semantics_callback2` may be provided; the others must be set
/// to null.
FlutterUpdateSemanticsCallback2 update_semantics_callback2;

/// The callback invoked by the engine in response to a channel listener
/// being registered on the framework side.
FlutterChannelListenedToCallback channel_listened_to_callback;
} FlutterProjectArgs;

#ifndef FLUTTER_ENGINE_NO_PROTOTYPES
Expand Down
8 changes: 8 additions & 0 deletions shell/platform/embedder/platform_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ void PlatformViewEmbedder::OnPreEngineRestart() const {
}
}

// |PlatformView|
void PlatformViewEmbedder::ChannelListenedTo(const std::string& name,
bool listening) {
if (platform_dispatch_table_.on_channel_listened_to != nullptr) {
platform_dispatch_table_.on_channel_listened_to(name, listening);
}
}

std::shared_ptr<PlatformMessageHandler>
PlatformViewEmbedder::GetPlatformMessageHandler() const {
return platform_message_handler_;
Expand Down
6 changes: 6 additions & 0 deletions shell/platform/embedder/platform_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class PlatformViewEmbedder final : public PlatformView {
std::function<std::unique_ptr<std::vector<std::string>>(
const std::vector<std::string>& supported_locale_data)>;
using OnPreEngineRestartCallback = std::function<void()>;
using ChannelListenedToCallback =
std::function<void(const std::string&, bool)>;

struct PlatformDispatchTable {
UpdateSemanticsCallback update_semantics_callback; // optional
Expand All @@ -50,6 +52,7 @@ class PlatformViewEmbedder final : public PlatformView {
ComputePlatformResolvedLocaleCallback
compute_platform_resolved_locale_callback;
OnPreEngineRestartCallback on_pre_engine_restart_callback; // optional
ChannelListenedToCallback on_channel_listened_to; // optional
};

// Create a platform view that sets up a software rasterizer.
Expand Down Expand Up @@ -134,6 +137,9 @@ class PlatformViewEmbedder final : public PlatformView {
std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocales(
const std::vector<std::string>& supported_locale_data) override;

// |PlatformView|
void ChannelListenedTo(const std::string& name, bool listening) override;

FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewEmbedder);
};

Expand Down
25 changes: 15 additions & 10 deletions shell/platform/windows/flutter_windows_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,12 @@ bool FlutterWindowsEngine::Run(std::string_view entrypoint) {
host->root_isolate_create_callback_();
}
};
args.channel_listened_to_callback = [](const char* name, size_t name_len,
bool listening, void* user_data) {
auto host = static_cast<FlutterWindowsEngine*>(user_data);
std::string channel_name(name, name + name_len);
host->OnChannelListenedTo(channel_name, listening);
};

args.custom_task_runners = &custom_task_runners;

Expand Down Expand Up @@ -792,16 +798,6 @@ void FlutterWindowsEngine::OnDwmCompositionChanged() {
view_->OnDwmCompositionChanged();
}

// TODO(yaakovschectman): This enables the flutter/lifecycle channel
// once the System.initializationComplete message is received on
// the flutter/system channel. This is a short-term workaround to
// ensure the framework is initialized and ready to accept lifecycle
// messages. This cross-channel dependency should be removed.
// See: https://github.com/flutter/flutter/issues/132514
void FlutterWindowsEngine::OnApplicationLifecycleEnabled() {
lifecycle_manager_->BeginProcessingLifecycle();
}

void FlutterWindowsEngine::OnWindowStateEvent(HWND hwnd,
WindowStateEvent event) {
lifecycle_manager_->OnWindowStateEvent(hwnd, event);
Expand All @@ -819,4 +815,13 @@ std::optional<LRESULT> FlutterWindowsEngine::ProcessExternalWindowMessage(
return std::nullopt;
}

void FlutterWindowsEngine::OnChannelListenedTo(const std::string& name,
bool listening) {
if (name.compare("flutter/platform") == 0) {
lifecycle_manager_->BeginProcessingExit();
} else if (name.compare("flutter/lifecycle") == 0) {
lifecycle_manager_->BeginProcessingLifecycle();
}
}

} // namespace flutter
8 changes: 4 additions & 4 deletions shell/platform/windows/flutter_windows_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,6 @@ class FlutterWindowsEngine {
// Called when a WM_DWMCOMPOSITIONCHANGED message is received.
void OnDwmCompositionChanged();

// Called in response to the framework registering a ServiceBindings.
// Registers the top level handler for the WM_CLOSE window message.
void OnApplicationLifecycleEnabled();

// Called when a Window receives an event that may alter the application
// lifecycle state.
void OnWindowStateEvent(HWND hwnd, WindowStateEvent event);
Expand Down Expand Up @@ -301,6 +297,10 @@ class FlutterWindowsEngine {
// created. This is typically caused by a hot restart (Shift-R in CLI.)
void OnPreEngineRestart();

// Invoked by the engine when a listener is set or cleared on a platform
// channel.
virtual void OnChannelListenedTo(const std::string& name, bool listening);

private:
// Allows swapping out embedder_api_ calls in tests.
friend class EngineModifier;
Expand Down
Loading