Skip to content
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

Rename first frame method and notify FlutterActivity when full drawn (#38714 #36796). #11357

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugin
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimPluginRegistry.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/shim/ShimRegistrar.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/renderer/OnFirstFrameRenderedListener.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterUiDisplayListener.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/renderer/RenderSurface.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/AccessibilityChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/KeyEventChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/LifecycleChannel.java
Expand Down
6 changes: 5 additions & 1 deletion shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ action("flutter_shell_java") {
"io/flutter/embedding/engine/plugins/shim/ShimPluginRegistry.java",
"io/flutter/embedding/engine/plugins/shim/ShimRegistrar.java",
"io/flutter/embedding/engine/renderer/FlutterRenderer.java",
"io/flutter/embedding/engine/renderer/OnFirstFrameRenderedListener.java",
"io/flutter/embedding/engine/renderer/FlutterUiDisplayListener.java",
"io/flutter/embedding/engine/renderer/RenderSurface.java",
"io/flutter/embedding/engine/systemchannels/AccessibilityChannel.java",
"io/flutter/embedding/engine/systemchannels/KeyEventChannel.java",
"io/flutter/embedding/engine/systemchannels/LifecycleChannel.java",
Expand Down Expand Up @@ -412,6 +413,9 @@ action("robolectric_tests") {
"test/io/flutter/embedding/android/FlutterActivityTest.java",
"test/io/flutter/embedding/android/FlutterFragmentTest.java",
"test/io/flutter/embedding/engine/FlutterEngineCacheTest.java",
"test/io/flutter/embedding/engine/FlutterJNITest.java",
"test/io/flutter/embedding/engine/RenderingComponentTest.java",
"test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java",
"test/io/flutter/embedding/engine/systemchannels/PlatformChannelTest.java",
"test/io/flutter/util/PreconditionsTest.java",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,18 @@ public boolean shouldAttachEngineToActivity() {
}

@Override
public void onFirstFrameRendered() {}
public void onFlutterUiDisplayed() {
// Notifies Android that we're fully drawn so that performance metrics can be collected by
// Flutter performance tests.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
reportFullyDrawn();
}
}

@Override
public void onFlutterUiNoLongerDisplayed() {
// no-op
}

/**
* The mode of the background of a {@code FlutterActivity}, either opaque or transparent.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain;

Expand Down Expand Up @@ -83,10 +83,15 @@
private boolean isFlutterEngineFromHost;

@NonNull
private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() {
private final FlutterUiDisplayListener flutterUiDisplayListener = new FlutterUiDisplayListener() {
@Override
public void onFirstFrameRendered() {
host.onFirstFrameRendered();
public void onFlutterUiDisplayed() {
host.onFlutterUiDisplayed();
}

@Override
public void onFlutterUiNoLongerDisplayed() {
host.onFlutterUiNoLongerDisplayed();
}
};

Expand Down Expand Up @@ -228,15 +233,15 @@ private void setupFlutterEngine() {
* <p>
* {@code inflater} and {@code container} may be null when invoked from an {@code Activity}.
* <p>
* This method creates a new {@link FlutterView}, adds a {@link OnFirstFrameRenderedListener} to
* This method creates a new {@link FlutterView}, adds a {@link FlutterUiDisplayListener} to
* it, and then returns it.
*/
@NonNull
View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.v(TAG, "Creating FlutterView.");
ensureAlive();
flutterView = new FlutterView(host.getActivity(), host.getRenderMode(), host.getTransparencyMode());
flutterView.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);

flutterSplashView = new FlutterSplashView(host.getContext());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Expand Down Expand Up @@ -391,12 +396,12 @@ void onStop() {
/**
* Invoke this from {@code Activity#onDestroy()} or {@code Fragment#onDestroyView()}.
* <p>
* This method removes this delegate's {@link FlutterView}'s {@link OnFirstFrameRenderedListener}.
* This method removes this delegate's {@link FlutterView}'s {@link FlutterUiDisplayListener}.
*/
void onDestroyView() {
Log.v(TAG, "onDestroyView()");
ensureAlive();
flutterView.removeOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
flutterView.removeOnFirstFrameRenderedListener(flutterUiDisplayListener);
}

/**
Expand Down Expand Up @@ -695,9 +700,13 @@ private void ensureAlive() {
boolean shouldAttachEngineToActivity();

/**
* Invoked by this delegate when its {@link FlutterView} has rendered its first Flutter
* frame.
* Invoked by this delegate when its {@link FlutterView} starts painting pixels.
*/
void onFlutterUiDisplayed();

/**
* Invoked by this delegate when its {@link FlutterView} stops painting pixels.
*/
void onFirstFrameRendered();
void onFlutterUiNoLongerDisplayed();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain;

Expand Down Expand Up @@ -567,21 +567,6 @@ public <T extends FlutterFragment> T build() {
// implementation for details about why it exists.
private FlutterActivityAndFragmentDelegate delegate;

private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() {
@Override
public void onFirstFrameRendered() {
// Notify our subclasses that the first frame has been rendered.
FlutterFragment.this.onFirstFrameRendered();

// Notify our owning Activity that the first frame has been rendered.
FragmentActivity fragmentActivity = getActivity();
if (fragmentActivity instanceof OnFirstFrameRenderedListener) {
OnFirstFrameRenderedListener activityAsListener = (OnFirstFrameRenderedListener) fragmentActivity;
activityAsListener.onFirstFrameRendered();
}
}
};

public FlutterFragment() {
// Ensure that we at least have an empty Bundle of arguments so that we don't
// need to continually check for null arguments before grabbing one.
Expand Down Expand Up @@ -951,21 +936,40 @@ public boolean shouldAttachEngineToActivity() {
}

/**
* Invoked after the {@link FlutterView} within this {@code FlutterFragment} renders its first
* frame.
* Invoked after the {@link FlutterView} within this {@code FlutterFragment} starts rendering
* pixels to the screen.
* <p>
* This method forwards {@code onFlutterUiDisplayed()} to its attached {@code Activity}, if
* the attached {@code Activity} implements {@link FlutterUiDisplayListener}.
* <p>
* Subclasses that override this method must call through to the {@code super} method.
* <p>
* Used by this {@code FlutterFragment}'s {@link FlutterActivityAndFragmentDelegate.Host}
*/
@Override
public void onFlutterUiDisplayed() {
FragmentActivity attachedActivity = getActivity();
if (attachedActivity instanceof FlutterUiDisplayListener) {
((FlutterUiDisplayListener) attachedActivity).onFlutterUiDisplayed();
}
}

/**
* Invoked after the {@link FlutterView} within this {@code FlutterFragment} stops rendering
* pixels to the screen.
* <p>
* This method forwards {@code onFirstFrameRendered()} to its attached {@code Activity}, if
* the attached {@code Activity} implements {@link OnFirstFrameRenderedListener}.
* This method forwards {@code onFlutterUiNoLongerDisplayed()} to its attached {@code Activity},
* if the attached {@code Activity} implements {@link FlutterUiDisplayListener}.
* <p>
* Subclasses that override this method must call through to the {@code super} method.
* <p>
* Used by this {@code FlutterFragment}'s {@link FlutterActivityAndFragmentDelegate.Host}
*/
@Override
public void onFirstFrameRendered() {
public void onFlutterUiNoLongerDisplayed() {
FragmentActivity attachedActivity = getActivity();
if (attachedActivity instanceof OnFirstFrameRenderedListener) {
((OnFirstFrameRenderedListener) attachedActivity).onFirstFrameRendered();
if (attachedActivity instanceof FlutterUiDisplayListener) {
((FlutterUiDisplayListener) attachedActivity).onFlutterUiNoLongerDisplayed();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;

/**
* {@code View} that displays a {@link SplashScreen} until a given {@link FlutterView}
Expand Down Expand Up @@ -51,13 +51,18 @@ public void onFlutterEngineDetachedFromFlutterView() {}
};

@NonNull
private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() {
private final FlutterUiDisplayListener flutterUiDisplayListener = new FlutterUiDisplayListener() {
@Override
public void onFirstFrameRendered() {
public void onFlutterUiDisplayed() {
if (splashScreen != null) {
transitionToFlutter();
}
}

@Override
public void onFlutterUiNoLongerDisplayed() {
// no-op
}
};

@NonNull
Expand Down Expand Up @@ -114,7 +119,7 @@ public void displayFlutterViewWithSplash(
) {
// If we were displaying a previous FlutterView, remove it.
if (this.flutterView != null) {
this.flutterView.removeOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
this.flutterView.removeOnFirstFrameRenderedListener(flutterUiDisplayListener);
removeView(this.flutterView);
}
// If we were displaying a previous splash screen View, remove it.
Expand All @@ -136,7 +141,7 @@ public void displayFlutterViewWithSplash(
// waiting for the first frame to render. Show a splash UI until that happens.
splashScreenView = splashScreen.createSplashView(getContext(), splashScreenState);
addView(this.splashScreenView);
flutterView.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);
} else if (isSplashScreenTransitionNeededNow()) {
Log.v(TAG, "Showing an immediate splash transition to Flutter due to previously interrupted transition.");
splashScreenView = splashScreen.createSplashView(getContext(), splashScreenState);
Expand Down
Loading