Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@jnschulze
Copy link
Member

@jnschulze jnschulze commented Jan 10, 2022

Fixes flutter/flutter#93234

This small fix prevents plugin registrar destruction callbacks from overwriting each other.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@jnschulze jnschulze force-pushed the fixes/windows-plugin-destruction branch 5 times, most recently from 17a582f to 7fe82e4 Compare February 1, 2022 10:25
@jnschulze jnschulze force-pushed the fixes/windows-plugin-destruction branch from 7fe82e4 to be83bde Compare February 1, 2022 10:43
@jnschulze
Copy link
Member Author

@stuartmorgan

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one question about the test. Thanks for cleaning this up!

@cbracken for second review.

EngineModifier modifier(engine.get());

MockEmbedderApiForKeyboard(modifier,
std::make_shared<MockKeyResponseController>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this test need a mock keyboard handler?

Copy link
Member Author

@jnschulze jnschulze Mar 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MockEmbedderApiForKeyboard mocks a couple of embedder API functions required by engine.RunWithEntrypoint. see

void MockEmbedderApiForKeyboard(
EngineModifier& modifier,
std::shared_ptr<MockKeyResponseController> response_controller) {
stored_response_controller = response_controller;
// This mock handles channel messages.
modifier.embedder_api()
.SendPlatformMessage = [](FLUTTER_API_SYMBOL(FlutterEngine) engine,
const FlutterPlatformMessage* message) {
if (std::string(message->channel) == std::string("flutter/settings")) {
return kSuccess;
}
if (std::string(message->channel) == std::string("flutter/keyevent")) {
stored_response_controller->HandleChannelMessage([message](bool handled) {
auto response = _keyHandlingResponse(handled);
auto response_handle = message->response_handle;
if (response_handle->callback != nullptr) {
response_handle->callback(response->data(), response->size(),
response_handle->user_data);
}
});
return kSuccess;
}
if (std::string(message->channel) == std::string("flutter/textinput")) {
std::unique_ptr<rapidjson::Document> document =
flutter::JsonMessageCodec::GetInstance().DecodeMessage(
message->message, message->message_size);
if (document == nullptr) {
return kInvalidArguments;
}
stored_response_controller->HandleTextInputMessage(std::move(document));
return kSuccess;
}
return kSuccess;
};
// This mock handles key events sent through the embedder API.
modifier.embedder_api().SendKeyEvent =
[](FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterKeyEvent* event,
FlutterKeyEventCallback callback, void* user_data) {
stored_response_controller->HandleEmbedderMessage(
event, [callback, user_data](bool handled) {
if (callback != nullptr) {
callback(handled, user_data);
}
});
return kSuccess;
};
// The following mocks enable channel mocking.
modifier.embedder_api().PlatformMessageCreateResponseHandle =
[](auto engine, auto data_callback, auto user_data, auto response_out) {
auto response_handle = new FlutterPlatformMessageResponseHandle();
response_handle->user_data = user_data;
response_handle->callback = data_callback;
*response_out = response_handle;
return kSuccess;
};
modifier.embedder_api().PlatformMessageReleaseResponseHandle =
[](FLUTTER_API_SYMBOL(FlutterEngine) engine,
FlutterPlatformMessageResponseHandle* response) {
delete response;
return kSuccess;
};
// The following mock disables responses for method channels sent from the
// embedding to the framework. (No code uses the response yet.)
modifier.embedder_api().SendPlatformMessageResponse =
[](FLUTTER_API_SYMBOL(FlutterEngine) engine,
const FlutterPlatformMessageResponseHandle* handle,
const uint8_t* data, size_t data_length) { return kSuccess; };
// The following mocks allows RunWithEntrypoint to be run, which creates a
// non-empty FlutterEngine and enables SendKeyEvent.
modifier.embedder_api().Run =
[](size_t version, const FlutterRendererConfig* config,
const FlutterProjectArgs* args, void* user_data,
FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
*engine_out = reinterpret_cast<FLUTTER_API_SYMBOL(FlutterEngine)>(1);
return kSuccess;
};
modifier.embedder_api().UpdateLocales =
[](auto engine, const FlutterLocale** locales, size_t locales_count) {
return kSuccess;
};
modifier.embedder_api().SendWindowMetricsEvent =
[](auto engine, const FlutterWindowMetricsEvent* event) {
return kSuccess;
};
modifier.embedder_api().Shutdown = [](auto engine) { return kSuccess; };
}

Should I just mock the required functions explicitly?

@stuartmorgan-g stuartmorgan-g requested a review from cbracken March 2, 2022 14:45
@chinmaygarde chinmaygarde added the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Mar 3, 2022
@fluttergithubbot fluttergithubbot merged commit 33afdde into flutter:main Mar 3, 2022
Copy link
Member

@cbracken cbracken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning this up!

engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 3, 2022
@jnschulze jnschulze deleted the fixes/windows-plugin-destruction branch March 11, 2022 10:55
bbrto21 pushed a commit to flutter-tizen/engine that referenced this pull request Jul 14, 2022
Applies flutter#30760 to the Tizen embedder.

This is an actual fix for flutter-tizen/flutter-tizen#90, which has been worked around by flutter-tizen/flutter-tizen#98. We can now support the old-fashioned "sharedLib" style plugins (each plugin is built into an individual shared object) based on this change.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

needs tests platform-windows waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[desktop][windows] something wrong with windows desktop application destructor when it refers two or more plugins

5 participants