Repository navigation
Closed
Labels
engineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.p: pigeonrelated to pigeon messaging codegen toolrelated to pigeon messaging codegen toolp: video_playerThe Video Player pluginThe Video Player pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.will need additional triageThis issue or PR needs attention before being routed to secondary triageThis issue or PR needs attention before being routed to secondary triage
Description
The latest video player tries to set the message handler to nil on all the channels in the messages.m file when the FlutterEngine gets deallocated. The following code from the video player doe sthat:
- (void)detachFromEngineForRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
for (NSNumber* textureId in _players.allKeys) {
FLTVideoPlayer* player = _players[textureId];
[player disposeSansEventChannel];
}
[_players removeAllObjects];
FLTVideoPlayerApiSetup(registrar.messenger, nil);
}
However, by this time, the engine is not running, and this causes an exception:
2020-05-12 08:51:58.023258-0400[10094:37996] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Setting a message handler before the FlutterEngine has been run.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010dd416fb __exceptionPreprocess + 331
1 libobjc.A.dylib 0x000000010bf7bac5 objc_exception_throw + 48
2 CoreFoundation 0x000000010dd41482 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010b9c9927 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
4 Flutter 0x0000000110cdbb31 -[FlutterEngine setMessageHandlerOnChannel:binaryMessageHandler:] + 264
5 MyApp 0x000000010560b23a _Z22FLTVideoPlayerApiSetupPU33objcproto22FlutterBinaryMessenger11objc_objectPU28objcproto17FLTVideoPlayerApi11objc_object + 362
6 MyApp 0x00000001056dbd9e -[FLTVideoPlayerPlugin detachFromEngineForRegistrar:] + 766
7 CoreFoundation 0x000000010ddb19c2 -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 226
8 Flutter 0x0000000110cd8e56 -[FlutterEngine dealloc] + 92
Metadata
Metadata
Assignees
Labels
engineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.p: pigeonrelated to pigeon messaging codegen toolrelated to pigeon messaging codegen toolp: video_playerThe Video Player pluginThe Video Player pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.will need additional triageThis issue or PR needs attention before being routed to secondary triageThis issue or PR needs attention before being routed to secondary triage
Activity
dannyvalentesonos commentedon May 12, 2020
[✓] Flutter (Channel dev, 1.19.0-0.0.pre, on Mac OS X 10.14.6 18G4032, locale en-US)
• Flutter version 1.19.0-0.0.pre at /Users/danny.valente/Library/flutter/1.19.0-0.0.pre-dev
• Framework revision a849daf (4 days ago), 2020-05-07 18:59:02 -0700
• Engine revision 3953c3c
• Dart version 2.9.0 (build 2.9.0-5.0.dev 4da5b40fb6)
TahaTesser commentedon May 12, 2020
Hi @dannyvalentesonos
Pleas explain in detail, do you think this is a major issue? Can this reproduce when using code sample?
Thank you
dannyvalentesonos commentedon May 12, 2020
I have made a local copy and modified the plugin, so not major for me, but this has been published and it crashes, so it's not great. Though I'm not sure how many people actually destroy a Flutter Engine at runtime, so it might not be a problem for many.
So, the issue is that when a Flutter Engine is destroyed, on iOS we call for example
[self.flutterEngine destroyContext];Then, once the engine actually gets deallocated, it calls the
detachFromEngineForRegistraron all plugins. The video plugin tries to set message handlers to nil on its channels, but the flutter engine is dead at this point and causes a crash. The previous version of the video player plugin didn't try to set the message handlers to nil, so this was never a problem.I just debugged on Android, and Android's Flutter engine actually calls
detachFromEngineForRegistraron all plugins when the "destroy" method is called, such as here:flutterEngine.destroy();So, maybe on iOS, the engine should call
detachFromEngineForRegistrarfrom all plugins at the time ofdestroyContextinstead of destruction.Also, on android, the new version of the video plugin has the following code...
And the video player plugin's
detachFromEngineForRegistrarcall looks like:which calls
stopListening()below.Notice in
VideoPlayerApi'ssetupmethod doesn't actually check for whetherapiis null or not. So that isn't great either.dannyvalentesonos commentedon May 13, 2020
cc @gaaclarke as the pigeon documentation said to do so.
gaaclarke commentedon May 13, 2020
Thanks for the report @dannyvalentesonos.
I think that's a good idea. I'm going to try to fix this without changing the engine though first since I want pigeon to be compatible with old versions of the engine.
Why do you call
destroyContext? Was this a workaround to a previous bug in the engine or is it to get more deterministic memory management to avoid OOM?dannyvalentesonos commentedon May 13, 2020
@gaaclarke Thanks for responding.
The reason we call
destroyContextis actually because we're building an Add2App experience, so when we run our automation tests, we need to attach flutter driver to our process after the app has already launched, and so we have a message we send to our app that says to enable automation, which causes us to destroy the current Flutter engine so that we can create a new one with a different dart entry point from our main.dart file that enables flutter driver integration.dannyvalentesonos commentedon May 13, 2020
@gaaclarke also, have you seen the issue I brought up for Android as well?
basically, pigeon generates this:
However, if api is null, it still ends up subscribing a message handler instead of nulling it out.
added a test to reproduce the crash from flutter/flutter#56996
gaaclarke commentedon May 13, 2020
@dannyvalentesonos Yep, added an issue for it, fixing it right now. I don't think I'll be able to get detaching from a running engine working without making changes to the engine code. Since it didn't work previously I'm not really taking functionality away but we should have it fixed by next stable release hopefully. This wasn't your problem anyway and no one has complained about it yet.
gaaclarke commentedon May 13, 2020
v0.10.11 should have the fix. Unfortunately I don't think any of the first-party plugins test plugins the way you use them, detaching from an engine was something that was added later in flutter so there is some bias in the testing. I started working on an automated test for pigeon, I'm not sure if we should do something similar for plugins. Let me know if you run into anything else.
github-actions commentedon Aug 21, 2021
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.