Skip to content

Commit

Permalink
Rename first frame method and notify FlutterActivity when full drawn (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-carroll authored Sep 3, 2019
1 parent ff4cf8e commit fde7c8c
Show file tree
Hide file tree
Showing 23 changed files with 638 additions and 409 deletions.
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

0 comments on commit fde7c8c

Please sign in to comment.