-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Alert engine upon registering ServiceBinding #126075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alert engine upon registering ServiceBinding #126075
Conversation
|
I think this will need a test, but as it tests the initialization of the binding, I will need to determine exactly how to write it. |
gspencergoog
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, but yes, does need a test.
|
@gspencergoog How would we be able to test that the framework sends a certain platform message to the engine upon initializing the ServiceBinding? Do we have a way to mock engine-side message handling from within framework tests? It looks like we only mock the framework-side. |
|
It could be an integration test that has a plugin that registers to receive those platform messages, maybe. That's a lot to set up, though. Maybe just verifying that the framework tries to send the message is enough: you could modify the
|
|
@gspencergoog I am unclear on what
|
|
Yeah, you're right, it's not available at that layer. Maybe it needs to be a test run with the tests for |
|
Are you referring to
What is available at that layer that seems useful to this prospective test? |
|
The Unfortunately, I don't think that will work because we don't use the injected instance when we send messages to the engine:
|
| SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object)); | ||
| SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage); | ||
| SystemChannels.platform.setMethodCallHandler(_handlePlatformMessage); | ||
| _registerBindingWithEngine(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to leverage this as a generic "the ServicesBinding is fully initialized" message in the future. Should we make this be the last step in initInstances?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, it seems weird to require an app to send a System.registerBinding if it wants to listen to application lifecycle events. For example, a dart:ui app may want to listen to app lifecycle events without using ServicesBinding. Perhaps we should use a different name like System.enableApplicationLifecycle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's that weird. Having something that happens after the binding is initialized seems like something you might want to use for other things besides enabling application lifecycle events too, so it doesn't seem too odd to have a "we're done initializing the binding" message to start things off. It does increase the boilerplate for such an app, however, which is too bad, but I think anyone building an app at that level is expecting some level of boilerplate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, I'm fine with the boilerplate. I disliked the previous message name System.registerBinding for a raw dart:ui app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about initializationComplete? Is that really true at the point the message is sent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be fine with System.initializationComplete too, but what would be the best way to document its implications? (Namely that the app now needs to respond to System.requestAppExit)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for now that is all it implies: that it's ready to respond to System.requestAppExit requests, but to the embedding, it also represents the point at which the framework's bindings are registered, so it can feel free to communicate with the bindings. I also wonder if there are other parts of the engine that assume the binding will respond to a method call which would benefit from waiting until the binding is ready?
|
What are your thoughts on adding to the |
That sounds reasonable. |
|
I'm running into some difficulty setting the handler for the platform message on the C++ side, because it has a reference to the standard method codec instance, but not the JSON method codec, which is what the platform channel uses, and I do not currently see a way to ensure the platform channel message is sent without registering a handler that responds to it in some way. |
| /// Alert the engine that the binding is registered. This instructs the engine to | ||
| /// register its top level window handler on Windows. | ||
| Future<void> enableApplicationLifecycle() async { | ||
| SystemChannels.platform.invokeMethod('System.enableApplicationLifecycle'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loïc and I discussed making this "System.initializationComplete" so that this wouldn't be so tied to app lifecycle, but could be used as a more generic signal. That's what I currently have in my implementations for macOS and Linux.
|
I've reworked the test. Instead of using the integration test, we are now using a unit test. |
| ); | ||
| } | ||
|
|
||
| /// Expose this method for testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This exposes the method for every test (not only ours, but also for all our customers). Since there should never be a reason for anyone to call this, we shouldn't do that. You'll have to create a custom binding subclass that's only used for your test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As only one binding can be active at a time, to my knowledge, I've put this test into a new file so that the custom binding it uses can be used exclusively by this test.
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…mework (#41782) ## Description Similar to #41733 and #41753 this causes the linux embedding to wait until it hears that the scheduler binding has registered itself before proceeding to send termination requests to the framework. This allows applications that don't use the framework (just use `dart:ui` directly) to exit automatically when the last window is closed. Without this change, the app does not exit when the window is closed. Depends on framework PR flutter/flutter#126075 landing first. ## Related PRs - #41733 - #41753 ## Related Issues - flutter/flutter#126033. ## Tests - Added a test to make sure that it doesn't send a termination request if the binding hasn't notified that it is ready yet.
…mework (#41753) Similar to #41733 and #41782, this causes the macos embedding to wait until it hears that the scheduler binding has registered itself before proceeding to send termination requests to the framework. This allows applications that don't use the framework (just use `dart:ui` directly) to exit automatically when the last window is closed. Without this change, the last window closes, but the app does not exit. Depends on framework PR flutter/flutter#126075 landing first.
Send a platform message to the engine when the `ServiceBinding` is registered. Framework side of flutter/engine#41733 Addresses flutter#126033 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [Features we expect every widget to implement]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat --------- Co-authored-by: Greg Spencer <[email protected]>
Send a platform message to the engine when the
ServiceBindingis registered. Framework side of flutter/engine#41733Addresses #126033
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.