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

Use preDraw for the Android embedding #27645

Merged
merged 9 commits into from
Jul 29, 2021
Merged

Conversation

jiahaog
Copy link
Member

@jiahaog jiahaog commented Jul 22, 2021

On Android, use the preDraw listener to report that the application is drawn only when Flutter has shown the first frame, when using the V2 FlutterActivity and FlutterFragmentActivity.

Related issue: flutter/flutter#85292

Changes

  • The preDraw listener is used by default for users of the FlutterActivity and FlutterFragmentActivity, unless:
    • A custom splash screen is detected (through io.flutter.embedding.android.SplashScreenDrawable / provideSplashScreen). When this is detected, add log warnings to direct users to a migration guide flutter.dev/go/android-splash-migration (not written yet)
    • RenderMode.surface is not used. This is because otherwise, FlutterTextureView will be used, but a deadlock will be caused because the underlying SurfaceTexture will never be available when preDraw returns false
  • Users who use FlutterFragment directly can enable this behavior through the shouldDelayFirstAndroidViewDraw builder method

Implementation Notes

  • Implement the check in FlutterActivityAndFragmentDelegate instead of FlutterView, to avoid the need to add yet another constructor to conditionally trigger this behavior. FlutterActivityAndFragmentDelegate also knows about the splash screen, and this implementation keeps the splash screen logic consolidated
  • Added a new parameter to FlutterActivityAndFragmentDelegate.onCreateView. I did not add a overload to preserve the old behavior since FlutterActivityAndFragmentDelegate is package private

Tested

  • Tested locally on a physical API 30 and API 31 device and it works as expected
  • Internal presubmit - minor changes needed to start activities asynchronously since some Integration Tests do not draw any frames

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.

Sorry, something went wrong.

@jiahaog
Copy link
Member Author

jiahaog commented Jul 22, 2021

@blasten @xster still have some WIP issues to iron out, but let me know if y'all have any feedback in the meantime

@@ -18,6 +18,9 @@
"io.flutter.embedding.android.NormalTheme";
/* package */ static final String HANDLE_DEEPLINKING_META_DATA_KEY =
"flutter_deeplinking_enabled";
/* package */ static final String USE_LEGACY_SPLASH_SCREEN_META_DATA_KEY =
"io.flutter.embedding.android.use-legacy-splash-screen";
Copy link

Choose a reason for hiding this comment

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

I'm not sure if this meta data is necessary.

It might be worth looking at the case when the user didn't supply a custom drawable. In this case, there's no drawable, so the splash screen is unnecessary.

I was thinking that it could be the way to decide whether we install the predraw listener or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

This will mean that the new behavior with preDraw will not be used by default, and is instead opt-in, which sounds a bit simpler, thanks 🙂 . I'll update the PR

Copy link

Choose a reason for hiding this comment

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

do we still need io.flutter.embedding.android.use-legacy-splash-screen or can it be removed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Whoops, removed it!

jiahaog added 4 commits July 23, 2021 10:16
- Only enable it by default for users who use `FlutterActivity` and
`FlutterActivityFragment`
- Add checks and disable it by default when it is used with
`RenderingMode.texture`
@jiahaog
Copy link
Member Author

jiahaog commented Jul 26, 2021

@blasten I updated the PR with what we discussed last Friday, and also to disable it for FlutterTextureView because that causes deadlocks, since onSurfaceTextureAvailable is never called when the preDraw listener is returning false. Let me know if there are any concerns regarding this.

new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (isFlutterUiDisplayed) {
Copy link
Member

Choose a reason for hiding this comment

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

I suspect this might run again after you rotate the screen. We might want to run this only once?

Copy link
Member Author

Choose a reason for hiding this comment

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

I tested it locally and registering the callback only happens once. We also deregister the listener the moment isFlutterUiDisplayed returns true, so it should be safe.

@@ -269,7 +282,8 @@ View onCreateView(
LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState,
int flutterViewId) {
int flutterViewId,
boolean shouldInterceptFirstDraw) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe shouldDelayFirstAndroidViewDraw?

Copy link
Member Author

Choose a reason for hiding this comment

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

Much better, thanks!

"A splash screen was provided to Flutter, but this is deprecated. See"
+ " flutter.dev/go/android-splash-migration for migration steps.");
FlutterSplashView flutterSplashView = new FlutterSplashView(host.getContext());
flutterSplashView.setId(ViewUtils.generateViewId(486947586));
Copy link

@blasten blasten Jul 26, 2021

Choose a reason for hiding this comment

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

minor clean up. 486947586 could be a final private static value.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point, done

- Rename to shouldDelayFirstAndroidViewDraw
- Static variable for Flutter splash view id
- Remove change to FlutterActivityLaunchConfigs
- Extract predraw to helper method
Copy link

@blasten blasten left a comment

Choose a reason for hiding this comment

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

LGTM

- Throw IllegalArgumentException instead of RuntimeException when using
TextureView and delaying the first draw
- Expose handler with @VisibleForTesting to make it easier to test
@jiahaog jiahaog marked this pull request as ready for review July 27, 2021 07:37
@jiahaog
Copy link
Member Author

jiahaog commented Jul 27, 2021

Added some unit tests and some minor visibility tweaks to make testing easier, please take another look 🙂

I'll follow up with the deprecation in a separate PR.

@xster
Copy link
Member

xster commented Jul 27, 2021

Still LGTM

Log.w(
TAG,
"A splash screen was provided to Flutter, but this is deprecated. See"
+ " flutter.dev/go/android-splash-migration for migration steps.");
Copy link

Choose a reason for hiding this comment

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

nice! flutter.dev/go/android-splash-migration returns 404 though

Copy link
Member Author

Choose a reason for hiding this comment

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

I plan to write this separately along with the deprecation annotations, will follow up

Copy link

@blasten blasten left a comment

Choose a reason for hiding this comment

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

LGTM

@jiahaog jiahaog 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 Jul 29, 2021
@fluttergithubbot fluttergithubbot merged commit ff770aa into flutter:master Jul 29, 2021
@jiahaog jiahaog deleted the predraw branch July 29, 2021 03:05
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jul 29, 2021
jiahaog added a commit that referenced this pull request Jul 29, 2021
jiahaog added a commit that referenced this pull request Jul 29, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
This reverts commit ff770aa.
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jul 29, 2021
jiahaog added a commit that referenced this pull request Jul 30, 2021
fluttergithubbot pushed a commit that referenced this pull request Jul 30, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
…)" (#27811)
naudzghebre pushed a commit to naudzghebre/engine that referenced this pull request Sep 2, 2021
naudzghebre pushed a commit to naudzghebre/engine that referenced this pull request Sep 2, 2021
filmil pushed a commit to filmil/engine that referenced this pull request Apr 21, 2022
filmil pushed a commit to filmil/engine that referenced this pull request Apr 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes platform-android 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.

None yet

4 participants